-
Notifications
You must be signed in to change notification settings - Fork 249
feat: add SubscriptionOnStartHandler #2059
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
dkorittki
merged 140 commits into
topic/streams-v1
from
ale/eng-7600-add-subscriptiononstarthandler
Oct 10, 2025
Merged
Changes from 83 commits
Commits
Show all changes
140 commits
Select commit
Hold shift + click to select a range
1d520ea
chore: add rfc
alepane21 290aa5f
Add some more description
alepane21 da3f6a1
feat: improved RFC base on feedback received
alepane21 82fed9f
chore: clean a bit structures
alepane21 1252790
chore: small fixes
alepane21 0008025
chore: fix indentations
alepane21 26bb7db
chore: small fixes
alepane21 d909dc0
chore: improved english flow
alepane21 d032b67
chore: fix wrong logic in an example
alepane21 9c69cdc
chore: change StreamOnEventFilter meaning of the returned boolean
alepane21 80f7097
chore: small fixes to example
alepane21 7969ec9
chore: address feedback
alepane21 5312f14
chore: limit filter example to inbound events
alepane21 259b2a0
chore: separate inbound and outbound hooks, added some complete examples
alepane21 23f3e19
chore: add some comments
alepane21 4d76c66
chore: moved interfaces and types to an appendix
alepane21 e35ac47
chore: improve example checks
alepane21 df62784
chore: improve data structure to expose ProviderId/Type and Specific …
alepane21 ace1c5c
chore: removed logic in the examples
alepane21 e6fc78f
chore: add proposal about how we could integrate AsyncAPI
alepane21 95a3941
core: add usage of FieldName()
alepane21 5adb360
chore: remove second example
alepane21 bfe2651
chore: explicit that the second async schema can be used by outside s…
alepane21 368413e
chore: change sent to published to be more consistent
alepane21 9015adf
chore: add enums for provider types
alepane21 cc83382
chore: remove Data and SetData, they break immutability!
alepane21 b5f188c
chore: FieldName -> RootFieldName
alepane21 68e7874
chore: improve data mapping description
alepane21 127a08a
chore: explicit that WriteEvent is writing event only to the current …
alepane21 083bf70
chore: explicit the WriteEvent behaviour also in the example
alepane21 ef36c76
chore: add an outlook on the Appendix 2 about a possible evolution
alepane21 93e4b04
chore: fixes example code to avoid panic on request not authenticated
alepane21 1fdeec3
chore: add explicit reference to Filtering hook that could be used fo…
alepane21 d38018e
chore: added description on the event filtering about authorization
alepane21 1ae023e
Merge branch 'main' into ale/eng-7470-rfc-cosmo-streams-v1-authorizat…
alepane21 f58970f
chore: add StreamHookError to allow error response customization from…
alepane21 8ac629c
chore: add more details and an example with kafka
alepane21 434c61c
chore: add an example on how to use the metadata field
alepane21 35e8077
fix: ignore marshal error
alepane21 fa562c9
chore: add PublishEventConfiguration, ProviderType and specialized ev…
alepane21 7ececf0
chore: remove local file
alepane21 93db159
Merge branch 'main' into ale/eng-7599-introduce-base-structures-to-pu…
alepane21 1ec4816
chore: use ProviderID()
alepane21 b938232
chore: update demo to use no Event structure
alepane21 f69b4cd
fix: align event configuration format
alepane21 74f32fc
fix: update MarshalJSONTemplate for new internal event format
alepane21 1649ef5
chore: remove duplicated test
alepane21 b83e4ef
chore: improve naming
alepane21 9ed94fd
chore: make the ADR from the approved RFC
alepane21 e61ad7a
Merge branch 'main' into ale/eng-7470-rfc-cosmo-streams-v1-authorizat…
alepane21 62a0882
chore: add an example to adr
alepane21 7d8a782
Merge branch 'ale/eng-7470-rfc-cosmo-streams-v1-authorization-init-ma…
alepane21 b4838be
Merge branch 'main' into ale/eng-7599-introduce-base-structures-to-pu…
alepane21 0e60603
feat: add SubscriptionOnStartHandler
alepane21 9fc67d2
Merge branch 'main' into ale/eng-7600-add-subscriptiononstarthandler
alepane21 73c3fb2
feat: add WriteEvent to context
alepane21 8b3d17b
chore: add test, improve method signature
alepane21 1977d3a
Merge branch 'main' into ale/eng-7600-add-subscriptiononstarthandler
alepane21 17984ce
feat: pass down additional event data to pubsub system
alepane21 0992ef6
chore: add SubscriptionEventUpdater to mockery
alepane21 6622459
chore: improved structure, add support for start hook also on subgrap…
alepane21 19ca6fd
chore: update deps
alepane21 79f05e5
chore: go mod tidy
alepane21 4b9c8a7
fix: properly escapes values
alepane21 9257565
chore: align MarshalJSONTemplate and improve the kafka one
alepane21 d6c6ec6
chore: small fix to MarshalJSONTemplate format
alepane21 a8b7f7d
chore: use the new subscription hooks on the engine
alepane21 18bee17
chore: update engine version
alepane21 bda2ed6
chore: tidy mods of router-tests
alepane21 5873131
Merge branch 'main' into ale/eng-7600-add-subscriptiononstarthandler
alepane21 638c6f7
chore: hooks can close subscription and specify custom errors
alepane21 cf1c868
chore: WriteEvents now calls directly resolveCtx.EmitSubscriptionUpdate
alepane21 831222e
Merge remote-tracking branch 'origin/main' into ale/eng-7600-add-subs…
alepane21 89832b9
fix: minor typos on adr
alepane21 7b8239f
chore: aligned names in the engine with the ones here
alepane21 9c8609f
chore: use new engine hooks
alepane21 d6dd642
chore: update engine
alepane21 6ad6f59
chore: update engine
alepane21 c330e46
Merge branch 'main' into ale/eng-7600-add-subscriptiononstarthandler
alepane21 c4dd131
fix: make CustomModuleError panic-free
alepane21 2e737da
fix: make NewPubSubOnSubscriptionStartHook and NewEngineOnSubscriptio…
alepane21 6ea1ee1
chore: clarify SubscriptionOnStartHookContext interface
alepane21 057a01f
chore: small coherency fixes
alepane21 73292a7
chore: small fixes and made names more coherent
alepane21 45a71e0
chore: add comments
alepane21 c58e79a
chore: add headers on kafka publish
alepane21 7c4a508
chore: use new TryEmitSubscriptionUpdate, added Headers on nats
alepane21 87faf10
chore: headers were not managed when nats was using channels
alepane21 4d4e675
Merge branch 'main' into ale/eng-7600-add-subscriptiononstarthandler
alepane21 9f661f3
chore: update graphql-go-tools to v2.0.0-rc.213 and use new Subscript…
alepane21 cb6d326
Revert "chore: update graphql-go-tools to v2.0.0-rc.213 and use new S…
alepane21 bff8717
chore: update graphql-go-tools to v2.0.0-rc.213 and use new Subscript…
alepane21 21c6366
chore: improve adr
alepane21 057d0f0
Merge branch 'topic/streams-v1' into ale/eng-7600-add-subscriptionons…
alepane21 35aceb0
refactor: rename ProviderLifecycle to Lifecycle and replaced hookedda…
alepane21 85a1bdb
chore: add a description to PubSubSubscriptionDataSource
alepane21 27e2b84
chore: add PubSubSubscriptionDataSource tests
alepane21 ffbd209
chore: implement PR suggestions
alepane21 ed22545
chore: implement suggestion
alepane21 d014b3a
chore: fix test
alepane21 82b5521
chore: update go.mod
alepane21 6ab1463
chore: go mod tidy
alepane21 4d93bd1
chore: change SubscriptionOnStartHandler to return only the error and…
alepane21 e309be2
chore: add what changes should be made to cosmo streams hooks with mo…
alepane21 cfc7a57
chore: add failing test
alepane21 fca32f6
chore: update engine
alepane21 61e0ddc
chore: update router
alepane21 cd9e4e4
chore: update engine
alepane21 1c4a1a9
chore: update router
alepane21 ceac255
chore: rename CloseConnection to CloseSubscription
alepane21 511a172
chore: remove close option from subscription start hook
alepane21 e34b6fe
chore: use updated engine
alepane21 70ef951
chore: use update router
alepane21 fb6c1a4
chore: fix test for new behaviour when an error is returned
alepane21 103443b
chore: remove closeSubscription field from StreamHookError and update…
alepane21 384d027
chore: update to new engine
alepane21 8177f80
chore: update engine
alepane21 0614486
chore: update graphql-go-tools dependency to latest version
alepane21 f3c67c7
chore: update graphql-go-tools dependency to new release version
alepane21 4a8bcbd
chore: update router and graphql-go-tools dependencies to latest vers…
alepane21 aa67e6d
chore: make the SubscriptionOnStartHookContext more restricted
alepane21 5caae33
chore: fix compile issues
StarpTech 0756819
chore: remove test module
alepane21 3ac47c4
chore: restore Authentication on SubscriptionOnStart context
alepane21 665269e
chore: update graphql-go-tools dependency to new release version
alepane21 806a9cf
chore: update graphql-go-tools dependency to latest release version
alepane21 31d35e9
chore: update graphql-go-tools dependency to new release version
alepane21 ba23381
chore: update router and graphql-go-tools dependencies to latest vers…
alepane21 4a4fdd0
chore: upgrade engine
alepane21 14b5007
chore: upgrade deps
alepane21 d046fcd
chore: tidy modules
alepane21 bd4263a
chore: updage engine
alepane21 02e79be
chore: update router and graphql-go-tools dependencies to latest vers…
alepane21 7f93003
chore: go mod tidy
alepane21 90dba99
chore: update graphql-go-tools dependency to latest version
alepane21 e0583e8
chore: update router and graphql-go-tools dependencies to latest vers…
alepane21 564837a
chore: go mod tidy
alepane21 2af75cb
chore: update ADR to reflect implementation of SubscriptionOnStart
alepane21 af3bb30
Merge branch 'topic/streams-v1' into ale/eng-7600-add-subscriptionons…
dkorittki 57bb4d9
chore: go mod tidy
dkorittki File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,397 @@ | ||
| --- | ||
| title: "Cosmo Streams v1" | ||
| author: Alessandro Pagnin | ||
| date: 2025-07-16 | ||
| status: Accepted | ||
| --- | ||
|
|
||
| # ADR - Cosmo Streams V1 | ||
|
|
||
| - **Author:** Alessandro Pagnin | ||
| - **Date:** 2025-07-16 | ||
| - **Status:** Accepted | ||
| - **RFC:** ../rfcs/cosmo-streams-v1.md | ||
|
|
||
| ## Abstract | ||
| This ADR describes new hooks that will be added to the router to support more customizable stream behavior. | ||
| The goal is to allow developers to customize the cosmo streams behavior. | ||
|
|
||
| ## Decision | ||
| A developer can implement a custom module by creating a struct that implements the following interfaces: | ||
|
|
||
| - `SubscriptionOnStartHandler`: Called once at subscription start. | ||
| - `StreamBatchEventHook`: Called each time a batch of events is received from the provider. | ||
| - `StreamPublishEventHook`: Called each time a batch of events is going to be sent to the provider. | ||
|
|
||
| ```go | ||
| // STRUCTURES TO BE ADDED TO PUBSUB PACKAGE | ||
| type ProviderType string | ||
| const ( | ||
| ProviderTypeNats ProviderType = "nats" | ||
| ProviderTypeKafka ProviderType = "kafka" | ||
| ProviderTypeRedis ProviderType = "redis" | ||
| } | ||
|
|
||
| // StreamHookError is used to customize the error messages and the behavior | ||
| type StreamHookError struct { | ||
| HttpError core.HttpError | ||
| CloseSubscription bool | ||
| } | ||
|
|
||
| // OperationContext already exists, we just have to add the Variables() method | ||
| type OperationContext interface { | ||
| Name() string | ||
| // the variables are currently not available, so we need to expose them here | ||
| Variables() *astjson.Value | ||
| } | ||
|
|
||
| // each provider will have its own event type with custom fields | ||
| // the StreamEvent interface is used to allow the hooks system to be provider-agnostic | ||
| // there could be common fields in future, but for now we don't need them | ||
| type StreamEvent interface {} | ||
|
|
||
| // SubscriptionEventConfiguration is the common interface for the subscription event configuration | ||
| type SubscriptionEventConfiguration interface { | ||
| ProviderID() string | ||
| ProviderType() string | ||
| // the root field name of the subscription in the schema | ||
| RootFieldName() string | ||
| } | ||
|
|
||
| // PublishEventConfiguration is the common interface for the publish event configuration | ||
| type PublishEventConfiguration interface { | ||
| ProviderID() string | ||
| ProviderType() string | ||
| // the root field name of the mutation in the schema | ||
| RootFieldName() string | ||
| } | ||
|
|
||
| type SubscriptionOnStartHookContext interface { | ||
| // the request context | ||
| RequestContext() RequestContext | ||
| // the stream context | ||
| StreamContext() StreamContext | ||
| // the subscription event configuration | ||
| SubscriptionEventConfiguration() SubscriptionEventConfiguration | ||
| // write an event to the stream of the current subscription | ||
| WriteEvent(event core.StreamEvent) | ||
| } | ||
|
|
||
| type SubscriptionOnStartHandler interface { | ||
| // OnSubscriptionOnStart is called once at subscription start | ||
| // Returning an error will result in a GraphQL error being returned to the client, could be customized returning a StreamHookError. | ||
| SubscriptionOnStart(ctx SubscriptionOnStartHookContext) error | ||
|
StarpTech marked this conversation as resolved.
|
||
| } | ||
|
|
||
| type StreamBatchEventHookContext interface { | ||
| // the request context | ||
| RequestContext() RequestContext | ||
| // the subscription event configuration | ||
| SubscriptionEventConfiguration() SubscriptionEventConfiguration | ||
| } | ||
|
|
||
| type StreamBatchEventHook interface { | ||
| // OnStreamEvents is called each time a batch of events is received from the provider | ||
| // Returning an error will result in a GraphQL error being returned to the client, could be customized returning a StreamHookError. | ||
| OnStreamEvents(ctx StreamBatchEventHookContext, events []StreamEvent) ([]StreamEvent, error) | ||
| } | ||
|
|
||
| type StreamPublishEventHookContext interface { | ||
| // the request context | ||
| RequestContext() RequestContext | ||
| // the publish event configuration | ||
| PublishEventConfiguration() PublishEventConfiguration | ||
| } | ||
|
|
||
| type StreamPublishEventHook interface { | ||
| // OnPublishEvents is called each time a batch of events is going to be sent to the provider | ||
| // Returning an error will result in a GraphQL error being returned to the client, could be customized returning a StreamHookError. | ||
| OnPublishEvents(ctx StreamPublishEventHookContext, events []StreamEvent) ([]StreamEvent, error) | ||
| } | ||
| ``` | ||
|
|
||
| ## Example Use Cases | ||
|
|
||
| - **Authorization**: Implementing authorization checks at the start of subscriptions | ||
| - **Initial message**: Sending an initial message to clients upon subscription start | ||
| - **Data mapping**: Transforming events data from the format that could be used by the external system to/from Federation compatible Router events | ||
| - **Event filtering**: Filtering events using custom logic | ||
|
|
||
| ## Backwards Compatibility | ||
|
|
||
| The new hooks can be integrated in the router in a fully backwards compatible way. | ||
| When the new module system will be released, some changes will be needed. | ||
|
StarpTech marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Example Modules | ||
|
|
||
| __All examples are pseudocode and not tested, but they are as close as possible to the final implementation__ | ||
|
|
||
| ## Filter and remap events | ||
|
|
||
| This example will show how to filter the events based on the client's scopes and remapping the messages as they are expected from the `Employee` type. | ||
|
|
||
| ### 1. Add a subscription to the cosmo streams graphql schema | ||
|
|
||
| The developer will start by adding a subscription to the cosmo streams graphql schema. | ||
|
|
||
| ```graphql | ||
| type Subscription { | ||
| employeeUpdates(): Employee! @edfs__natsSubscribe(subjects: ["employeeUpdates"], providerId: "my-nats") | ||
| } | ||
|
|
||
| type Employee @key(fields: "id", resolvable: false) { | ||
| id: Int! @external | ||
| } | ||
| ``` | ||
| After publishing the schema, the developer will need to add the module to the cosmo streams engine. | ||
|
|
||
| ### 2. Write the custom module | ||
|
|
||
| The developer will need to write the custom module that will be used to subscribe to the `employeeUpdates` subject and filter the events based on the client's scopes and remapping the messages as they are expected from the `Employee` type. | ||
|
|
||
| ```go | ||
| package mymodule | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "slices" | ||
| "github.com/wundergraph/cosmo/router/core" | ||
| "github.com/wundergraph/cosmo/router/pkg/pubsub/nats" | ||
| ) | ||
|
|
||
| func init() { | ||
| // Register your module here and it will be loaded at router start | ||
| core.RegisterModule(&MyModule{}) | ||
| } | ||
|
|
||
| type MyModule struct {} | ||
|
|
||
| func (m *MyModule) OnStreamEvents(ctx StreamBatchEventHookContext, events []core.StreamEvent) ([]core.StreamEvent, error) { | ||
| // check if the provider is nats | ||
| if ctx.StreamContext().ProviderType() != pubsub.ProviderTypeNats { | ||
| return events, nil | ||
| } | ||
|
|
||
| // check if the provider id is the one expected by the module | ||
| if ctx.StreamContext().ProviderID() != "my-nats" { | ||
| return events, nil | ||
| } | ||
|
|
||
| // check if the subject is the one expected by the module | ||
| natsConfig := ctx.SubscriptionEventConfiguration().(*nats.SubscriptionEventConfiguration) | ||
| if natsConfig.Subjects[0] != "employeeUpdates" { | ||
| return events, nil | ||
| } | ||
|
|
||
| // check if the client is authenticated | ||
| if ctx.RequestContext().Authentication() == nil { | ||
| // if the client is not authenticated, return no events | ||
| return events, nil | ||
| } | ||
|
|
||
| // check if the client is allowed to subscribe to the stream | ||
| clientAllowedEntitiesIds, found := ctx.RequestContext().Authentication().Claims()["allowedEntitiesIds"] | ||
| if !found { | ||
| return events, fmt.Errorf("client is not allowed to subscribe to the stream") | ||
| } | ||
|
|
||
| newEvents := make([]core.StreamEvent, 0, len(events)) | ||
|
|
||
| for _, evt := range events { | ||
| natsEvent, ok := evt.(*nats.NatsEvent); | ||
| if !ok { | ||
| newEvents = append(newEvents, evt) | ||
| continue | ||
| } | ||
|
|
||
| // decode the event data coming from the provider | ||
| var dataReceived struct { | ||
| EmployeeId string `json:"EmployeeId"` | ||
| OtherField string `json:"OtherField"` | ||
| } | ||
| err := json.Unmarshal(natsEvent.Data, &dataReceived) | ||
| if err != nil { | ||
| return events, fmt.Errorf("error unmarshalling data: %w", err) | ||
| } | ||
|
|
||
| // filter the events based on the client's scopes | ||
| if !slices.Contains(clientAllowedEntitiesIds, dataReceived.EmployeeId) { | ||
| continue | ||
| } | ||
|
|
||
| // prepare the data to send to the client | ||
| var dataToSend struct { | ||
| Id string `json:"id"` | ||
| TypeName string `json:"__typename"` | ||
| } | ||
| dataToSend.Id = dataReceived.EmployeeId | ||
| dataToSend.TypeName = "Employee" | ||
|
|
||
| // marshal the data to send to the client | ||
| dataToSendMarshalled, err := json.Marshal(dataToSend) | ||
| if err != nil { | ||
| return events, fmt.Errorf("error marshalling data: %w", err) | ||
| } | ||
|
|
||
| // create the new event | ||
| newEvent := &nats.NatsEvent{ | ||
| Data: dataToSendMarshalled, | ||
| Metadata: natsEvent.Metadata, | ||
| } | ||
| newEvents = append(newEvents, newEvent) | ||
| } | ||
| return newEvents, nil | ||
| } | ||
|
|
||
| func (m *MyModule) Module() core.ModuleInfo { | ||
| return core.ModuleInfo{ | ||
| ID: myModuleID, | ||
| Priority: 1, | ||
| New: func() core.Module { | ||
| return &MyModule{} | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| // Interface guards | ||
| var ( | ||
| _ core.StreamBatchEventHook = (*MyModule)(nil) | ||
| ) | ||
| ``` | ||
|
|
||
| ### 3. Add the provider configuration to the cosmo router | ||
| ```yaml | ||
| version: "1" | ||
|
|
||
| events: | ||
| providers: | ||
| nats: | ||
| - id: my-nats | ||
| url: "nats://localhost:4222" | ||
| ``` | ||
|
|
||
| ## Check authorization at subscription start | ||
|
|
||
| This example will show how to check the authorization at subscription start. | ||
|
|
||
| ### 1. Add a subscription to the cosmo streams graphql schema | ||
|
|
||
| The developer will start by adding a subscription to the cosmo streams graphql schema. | ||
|
|
||
| ```graphql | ||
| type Subscription { | ||
| employeeUpdates(): Employee! @edfs__natsSubscribe(subjects: ["employeeUpdates"], providerId: "my-nats") | ||
| } | ||
|
|
||
| type Employee @key(fields: "id", resolvable: false) { | ||
| id: Int! @external | ||
| } | ||
| ``` | ||
| After publishing the schema, the developer will need to add the module to the cosmo streams engine. | ||
|
|
||
| ### 2. Write the custom module | ||
|
|
||
| The developer will need to write the custom module that will be used to check the authorization at subscription start. | ||
|
|
||
| ```go | ||
| package mymodule | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "slices" | ||
| "github.com/wundergraph/cosmo/router/core" | ||
| "github.com/wundergraph/cosmo/router/pkg/pubsub/nats" | ||
| ) | ||
|
|
||
| func init() { | ||
| // Register your module here and it will be loaded at router start | ||
| core.RegisterModule(&MyModule{}) | ||
| } | ||
|
|
||
| type MyModule struct {} | ||
|
|
||
| func (m *MyModule) SubscriptionOnStart(ctx SubscriptionOnStartHookContext) error { | ||
| // check if the provider is nats | ||
| if ctx.StreamContext().ProviderType() != pubsub.ProviderTypeNats { | ||
| return nil | ||
| } | ||
|
|
||
| // check if the provider id is the one expected by the module | ||
| if ctx.StreamContext().ProviderID() != "my-nats" { | ||
| return nil | ||
| } | ||
|
|
||
| // check if the subject is the one expected by the module | ||
| natsConfig := ctx.SubscriptionEventConfiguration().(*nats.SubscriptionEventConfiguration) | ||
| if natsConfig.Subjects[0] != "employeeUpdates" { | ||
| return nil | ||
| } | ||
|
|
||
| // check if the client is authenticated | ||
| if ctx.RequestContext().Authentication() == nil { | ||
| // if the client is not authenticated, return an error | ||
| return &StreamHookError{ | ||
| HttpError: core.HttpError{ | ||
| Code: http.StatusUnauthorized, | ||
| Message: "client is not authenticated", | ||
| }, | ||
| CloseSubscription: true, | ||
| } | ||
| } | ||
|
|
||
| // check if the client is allowed to subscribe to the stream | ||
| clientAllowedEntitiesIds, found := ctx.RequestContext().Authentication().Claims()["readEmployee"] | ||
| if !found { | ||
| return &StreamHookError{ | ||
| HttpError: core.HttpError{ | ||
| Code: http.StatusForbidden, | ||
| Message: "client is not allowed to read employees", | ||
| }, | ||
| CloseSubscription: true, | ||
| } | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (m *MyModule) Module() core.ModuleInfo { | ||
| return core.ModuleInfo{ | ||
| ID: myModuleID, | ||
| Priority: 1, | ||
| New: func() core.Module { | ||
| return &MyModule{} | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| // Interface guards | ||
| var ( | ||
| _ core.SubscriptionOnStartHandler = (*MyModule)(nil) | ||
| ) | ||
| ``` | ||
|
|
||
| ### 3. Add the provider configuration to the cosmo router | ||
| ```yaml | ||
| version: "1" | ||
|
|
||
| events: | ||
| providers: | ||
| nats: | ||
| - id: my-nats | ||
| url: "nats://localhost:4222" | ||
| ``` | ||
|
|
||
| ### 4. Build the cosmo router with the custom module | ||
|
|
||
| Build and run the router with the custom module added. | ||
|
|
||
| # Outlook | ||
|
|
||
| ## Using AsyncAPI for Event Data Structure | ||
|
|
||
| We could use AsyncAPI specifications to define the event data structure and generate the Go structs automatically. This would make the development of custom modules easier and more maintainable. | ||
| We could also generate the AsyncAPI specification from the schema and the events data, to make it easier for external systems to use the events published by cosmo streams engine. | ||
|
|
||
| ## Generate hooks from AsyncAPI specifications | ||
|
|
||
| Building on the AsyncAPI integration, we could allow the user to define their streams using AsyncAPI and generate fully typesafe hooks with all events structures generated from the AsyncAPI specification. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.