How to use OpenAPI / Swagger spec for Events?
OpenAPI / Swagger spec can support defining schemas only and thus would be useful to define events in an event-driven system. Such definitions can also be used by codegen tools like OpenAPI Generator to autocreate schema objects for languages like Java, Swift, Go, etc.
When designing event schemas, it is useful to avoid polymorphism. While OpenAPI 3.0 spec now supports such definitions, tooling is still limited.
OpenAPI 3.0
With OpenAPI Spec 3.0, you can support multiple event types in one definition using its oneOf
, anyOf
, allOf
support. More information is in the OpenAPI 3.0 docs here:
- https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/
I haven't experimented with this yet because OpenAPI 3.0 spec isn't supported in Swagger Codegen for Go yet. However, they are actively working on Java so if that's your language of choice, you can give it a shot.
You can follow Swagger Codgen support for OpenAPI 3.0 spec in this GitHub issue:
- https://github.com/swagger-api/swagger-codegen/issues/4669
OpenAPI/Swagger 2.0
For Swagger Spec 2.0 (aka OpenAPI Spec 2.0), you can include definitions in the Swagger spec as mentioned by alamar. Swagger Codegen will automatically create model classes for these definitions, even if they are not associated with any paths. I build and maintain a Swagger Spec/Codegen-built SDK in Go for the RingCentral API that has events like this. You can see the auto-generated classes/structs Swagger Codegen builds in the following folder, filtering for the 20 files that end in _event.go
. These are currently created using swagger-codegen
2.3.1.
- Generated files: https://github.com/grokify/go-ringcentral/tree/master/client
- Codegen info: https://github.com/grokify/go-ringcentral/tree/master/codegen
If you have multiple event types, having an event property that can distinguish message types you are receiving can help parse it into the correct event class/struct. In Go, you can unmarshal the data twice, once into a generic struct to peek at the event type property, and then a second time for the actual event type.
I also maintain a collection of example events and parsing code in the Chathooks webhook reformatter project you can use for reference. You can see the example events and (hand-rolled) language definitions here:
- Examples: https://github.com/grokify/chathooks/tree/master/docs/handlers
- Definitions: https://github.com/grokify/chathooks/tree/master/src/handlers
I think you can have definitions in Swagger even if they aren't used by any endpoints. Just declare any types that you need in a dedicated section, e.g. "definitions". You can refer ones that you're using in the endpoints as e.g. "$ref": "#/definitions/User"
, as per main Swagger live example.
I expect that code will be generated for them, so you can write tests against any of definitions.