Designing Event-Driven Architectures with AsyncAPI: A Step-by-Step Guide

axeldlv

Axel

Posted on October 6, 2024

Designing Event-Driven Architectures with AsyncAPI: A Step-by-Step Guide

Introduction

AsyncAPI streamlines the implementation of event-driven architectures by standardizing asynchronous message communication, much like OpenAPI does for RESTful APIs. With various tools available, integrating AsyncAPI into your application is simplified, allowing you to define, generate, and implement event-driven APIs efficiently.

Steps for AsyncAPI Implementation

1. Define AsyncAPI Document

The AsyncAPI document describes the structure of your messaging API (e.g., message brokers like Kafka, RabbitMQ). You can either write it manually in YAML or JSON or you can also use the AsyncAPI Studio to visualise your AsyncAPI.

Here’s an example of an AsyncAPI document using version 2.6.0 (version 3.0.0 is currently unsupported for Spring Boot or Spring Cloud Stream code generation):

asyncapi: 2.6.0
id: https://axeldlv.id.be/asyncapi-aircraft-booking

info:
  title: Aircraft Booking Service API
  version: 1.0.0
  contact: 
      name : "AxelDlv"
      url : "https://axeldlv.aircraft.be/asyncapi-aircraft-booking"
      email : "axeldlv@nomail.be"
  license: 
      name : noLicense
  description: >
    This AsyncAPI document describes the message flows between different services in the aircraft booking processing system.

tags:
  - name: AircraftBookingEvent
    description: Tag it as Aircraft booking Event
defaultContentType: application/json

servers:
  development:
    url: localhost:9092
    protocol: kafka
    description: Local Kafka broker for development

  production:
    url: kafka.broker.url:9092
    protocol: kafka
    description: Production Kafka broker
    security:
      - certs: []

channels:
  aircraftBooked:
    description: Channel for booking aircraft events
    subscribe:
      operationId: aircraftBookedEvent
      message:
        messageId: aircraftBookedEvent 
        name: aircraftBooked
        schemaFormat: application/vnd.aai.asyncapi+yaml;version=2.6.0
        contentType: application/json       
        payload:
          $ref: '#/components/messages/aircraftBookedEvent'
    bindings:
      kafka:
        topic: aircraftBookedEvent

components:
  messages:
    aircraftBookedEvent:
      messageId: aircraftBookedEvent        
      name: aircraftBooked
      title: Aircraft booking notification
      summary: A message containing details of a new order
      description: >-
        More info about how to book an aircraft.
      tags:
        - name: AircraftBookingEvent
          description: Resources relating to AircraftBooking  
      payload:
        type: object
        $ref: '#/components/schemas/AircraftBooked'
      examples:
        - name : aircraftBookedEvent
          summary: aircraft booked
          payload:
            aircraftBookedEvent:
              bookingId: "12345"
              aircraftId: "01921f5d-98de-7f36-8ae7-196d5fb6f9b0"
              aircraftType: "DA-40"
              studentId: "01921f5d-98de-7f36-8ae7-196d5fb6f9b0"
              instructorId: "01921f5d-98de-7c8a-9333-36a4c9fcde1b"
              location: "EBSG"
              purpose: "Training Flight"
              bookingDate: "2024-09-26T10:00:28Z"
              startTime: "2024-09-27T17:00:28Z"
              endTime: "2024-09-27T17:30:28Z"
              status: "confirmed"
              notes: "Notes about the flight"

  schemas:
    AircraftBooked:
      type: object
      properties:
        bookingId:
          type: string
          format: uuid          
          description: Unique ID for the booking
        aircraftId:
          type: string
          description: Unique ID of the aircraft
        aircraftType:
          type: string
          description: Type of the aircraft
        studentId:
          type: string
          format: uuid
          description: Unique ID of the student booking the aircraft
        instructorId:
          type: string
          format: uuid
          description: Unique ID of the instructor
        location:
          type: string
          description: Location of the booking
        purpose:
          type: string
          description: Purpose of the booking (e.g., Training Flight)
        bookingDate:
          type: string
          format: date-time
          description: The date when the booking was created
        startTime:
          type: string
          format: date-time
          description: Start time of the booking
        endTime:
          type: string
          format: date-time
          description: End time of the booking
        status:
          type: string
          description: Status of the booking (e.g., CONFIRMED)
        notes:
          type: string
          description: Additional notes about the booking

  securitySchemes:
    certs:
      type: X509
      description: Certificate-based authentication for secure communication
Enter fullscreen mode Exit fullscreen mode

2. Choose a Messaging Protocol

Select the appropriate messaging protocol depending on your application needs. Some common ones are:

  • Kafka
  • RabbitMQ
  • MQTT
  • WebSockets

For example, in your AsyncAPI document:

servers:
  development:
    url: localhost:9092
    protocol: kafka
    description: Local Kafka broker for development

  production:
    url: kafka.broker.url:9092
    protocol: kafka
    description: Production Kafka broker
    security:
      - certs: []
Enter fullscreen mode Exit fullscreen mode

You can use the AsyncAPI Studio to visualize this definition.

AsyncAPI Studio view

To convert the document to version 3.0.0, run the following command :

asyncapi convert yourTemplate-in-2.6.0.yaml --output=new_asyncapi-3.0.0.yaml --target-version=3.0.0
Enter fullscreen mode Exit fullscreen mode

3. Generate Code using AsyncAPI Generator

Use the AsyncAPI Generator to automatically generate code based on your AsyncAPI document.

You can generate different types of code:

  • Client libraries for different languages like Java, Python, etc.
  • Server stubs.
  • Documentation.

Install the AsyncAPI Generator via npm:

npm install -g @asyncapi/generator
Enter fullscreen mode Exit fullscreen mode

To generate code:

asyncapi generate fromTemplate yourTemplate-in-2.6.0.yaml @asyncapi/java-spring-template -o asyncapi-spring-boot
Enter fullscreen mode Exit fullscreen mode

Replace @asyncapi/java-spring-template with the template of your choice, depending on the language and framework you're using.

4. Integrate with Your Application

Once the code is generated, integrate it into your application. The structure of the generated code will follow conventions set by the template used.

Structure of AsyncAPI Spring Boot Generator

Example AsyncAPI Tools

AsyncAPI Studio: A visual editor to create and edit AsyncAPI documents.

AsyncAPI Generator: Used for generating code and documentation.

AsyncAPI React: A tool to render the AsyncAPI document as interactive HTML documentation.

Conclusion

AsyncAPI provides a robust framework for building and managing event-driven architectures by standardizing asynchronous communication, similar to how OpenAPI simplifies RESTful API development. By following the steps outlined—defining the AsyncAPI document, choosing the appropriate messaging protocol, generating code with the AsyncAPI Generator, and integrating it into your application—you can streamline the development process for event-based systems. Additionally, tools like AsyncAPI Studio and AsyncAPI React further simplify document creation and visualization, making it easier to adopt event-driven patterns in modern microservices environments. With these tools and practices, you can quickly implement scalable and efficient asynchronous APIs.

💖 💪 🙅 🚩
axeldlv
Axel

Posted on October 6, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related