apigenie-generatorAsyncAPI clientsclient elixir (AsyncAPI)

client elixir (AsyncAPI)

Generate an Elixir client library of the WebSocket and Kafka channels of an AsyncAPI document.

Usage

apigenie-generator client elixir [...OPTIONS] INPUT_FILE

Description

apigenie-generator client elixir generates from OpenAPI documents (see apigenie-generator client elixir) and from AsyncAPI 3.x documents, telling them apart by their openapi or asyncapi field. Documents referencing other files are bundled first.

From an AsyncAPI document it generates a Mix library (Elixir 1.18 or later) for the counterpart of the described application, by default: it sends what the application receives and receives what it sends. The WebSocket channels connect on Mint.WebSocket, the Kafka channels use brod. Set the perspective option to application for the application’s Kafka library; WebSocket channels are connected to in the counterpart perspective only. With Kafka channels the library depends on snappyer, a NIF that needs a C++ compiler, so that brod reads Snappy-compressed records (the default of Go’s franz-go producers); LZ4 and zstd records need lz4b or ezstd added by hand.

The generator writes the channels of servers with the ws/wss and kafka/kafka-secure protocols, and channels with a WebSocket or Kafka binding in documents without servers. Channels of other protocols (MQTT, AMQP, HTTP) are skipped and reported as info.

{:ok, socket} =
  CarpetExpressEvents.WebSocket.TrackingStream.connect("shp_8Yb2Kk1qP0wZcT3uXr5sN7aD",
    url: "ws://localhost:4000",
    query: [include: ["location"]],
    handler: MyApp.Tracking
  )

{:ok, pickup} = CarpetExpressEvents.WebSocket.PickupDesk.connect(url: "ws://localhost:4000")
{:ok, %CarpetExpressEvents.Models.PickupConfirmed{}} =
  CarpetExpressEvents.WebSocket.PickupDesk.request_pickup(pickup, request)

The library, for the application carpet_express_events (named by app, --package-name or the document’s title):

File Contents
lib/<app>/models/*.ex the structs of the schemas the payloads use, decoded and encoded by decode.ex and encode.ex
lib/<app>/websocket/<channel>.ex per WebSocket channel, connect, and the functions sending its messages and requests
lib/<app>/websocket/<channel>/handler.ex the behaviour of the callbacks receiving what the server sends on the channel
lib/<app>/messages/*.ex per Kafka message, a struct (payload, headers, key) and the description of its record
lib/<app>/kafka.ex the supervisor of the Kafka processes and a function per topic
lib/<app>/kafka/<operation>.ex per sent operation, its send (and request) functions; per received operation, the behaviour of its callbacks
lib/<app>/kafka/<operation>_consumer.ex per received operation, its group subscriber
lib/<app>/runtime/ the WebSocket connection (ChannelSocket) and the Kafka runtime
mix.exs, .formatter.exs, .credo.exs the project, a library without application
  • WebSocket channels, two framings. connect (with the channel’s address parameters first) opens a connection to the server of :url and joins the channel. With framing: :phoenix, the default, it speaks the Phoenix Channels protocol (version 2) of apigenie-generator server phoenix: the socket /socket/websocket, the channel’s topic (the address segments joined by :), the ws binding’s :query as the join payload, a heartbeat every 30 seconds. With framing: :plain it connects to the channel’s address, the query in the URL, and the frames are the messages of the AsyncAPI document. send_<message> sends a message; for a request, the function named after it waits for the reply: the reply to its ref in the Phoenix framing, the next message with the request’s correlation id in the plain one. What the server sends is decoded into its struct and given to the callbacks of the channel’s Handler behaviour (the :handler option), or sent to the calling process.
  • Kafka. Add {CarpetExpressEvents.Kafka, brokers: "localhost:9092"} to your supervision tree. send_<message>/1 checks a message’s headers and returns once the brokers have the record; request_<message>/2 waits for the reply on the reply topic, matched by the correlation id (generated when the request has none; :timeout, 30 seconds by default). Each received operation has a consumer group (:brod_group_subscriber_v2) handing its records to the behaviour’s callbacks, as server phoenix does: told apart by a constant header (ce_type), payload property or decoding, with the optional on_unknown/1 and on_invalid/2; a replier’s callback returns its reply, sent with the request’s correlation id.

Group ids come from the groupId schemas of the Kafka operation bindings, else <app in kebab case>-<operation>, and the consumer modules’ configuration overrides them (config :app, <Consumer>, group_id: ..., offset_reset_policy: :earliest).

Not supported, and reported as warnings: Avro payloads and payloads of other non-JSON schema formats, reply addresses given by runtime expressions, Kafka topics with parameters, and WebSocket addresses whose segments mix text and parameters. Security is not generated: the WebSocket connections carry no credentials (the streamToken is a query parameter) and the Kafka clients connect without SASL or TLS. The client ids of the Kafka bindings are not applied, the headers schema of the ws binding is not sent, and the models decode by type.

Options

-c, –config

Path to the configuration file to use. See the “Configuration” section for more information.

-o, –output

Directory where the library is generated.

–package-name

Name of the Mix application, converted to snake_case (carpet-express-events gives carpet_express_events, root module CarpetExpressEvents); defaults to the title of the API. Its kebab case is the base of default group ids.

–package-version

Version of the Mix project; 0.1.0 by default.

-p, –property

Applies to OpenAPI documents only; using it with an AsyncAPI document is an error.

Configuration

The options are read from the asyncapi section of the configuration of apigenie-generator client elixir; its other keys configure the generation from OpenAPI documents.

version: '1.0'
commands:
  generate:
    client_elixir:
      asyncapi:
        app: carpet_express_events
        perspective: counterpart
Option Type Default Description
app string from --package-name or the title Name of the Mix application (snake_case)
namespace string the application in PascalCase Root module of the generated modules
perspective counterpart | application counterpart The counterpart of the described application, or the application itself
field_prefix string field_ Prefix of struct fields whose property names give no valid name
module_overrides map Module names of payload schemas, e.g. ShipmentId: ShipmentRef
dev_deps boolean true credo and dialyxir as dependencies of the dev and test environments