Event-Driven Architectures & AsyncAPI
We, as engineers, often forget that APIs are not just HTTP APIs. We got so used to think about HTTP and REST APIs that we even have to stop for a moment to remember what the API term means. API stands for ”Application Programming Interface”. It’s exactly on the “Interface” piece where I want to focus. According to Oxford Dictionaries, an interface is:
A point where two systems, subjects, organizations, etc. meet and interact.
In software engineering, high-quality architectures always go hand in hand with well-defined interfaces and responsibility boundaries. Likewise, poorly-defined interfaces and boundaries are frequently the top reason for a bad design.
When designing Event-Driven Architectures (EDA), you are also building APIs. These APIs will sit in the boundaries of your services and will allow them to communicate.
Topics and messages are first-class citizens because they precisely represent services interfaces. Consider the following example:
Email Service expects to receive a message on
users/created topic. The message must contain information about the user's name and email, to be able to send a proper welcome email.
Can you imagine what happens if we change the Accounts Service and now it sends the message via the
accounts/created topic? Or what if we change the message and now it specifies the email in an
emailAddress field instead of
As you can see, topics and messages are the interfaces of our services, and so we have to care about them, especially as the number of services grows. We should pay attention in the same way we do with endpoints, and requests and response payloads in our HTTP APIs.
AsyncAPI provides a specification that allows you to define Message-Driven APIs in a machine-readable format. The spec is very similar to OpenAPI/Swagger so, if you’re familiar with them, AsyncAPI should be easy for you.
How does it work?
Your API definition consists of a file, or a set of them, where you define the topics, messages, servers, and more. You can afterward use the file(s) to create documentation, tooling or for whatever you need it.
There are many use cases where AsyncAPI can be helpful, mostly to generate human-readable documentation and bootstrap code for your API. However, other use cases include:
- Documentation-first development: Your API implementation doesn’t change unless you change its documentation.
- API testing: Since you have all the API information, you could easily generate integration tests.
- API management: You can build API management solutions gathering information from AsyncAPI files.
- Monitoring: You can create tooling to help you monitor your APIs.