Openapi-generator: generate a document using annotations

Hello there :slight_smile:

I never posted in the forum before but I’ve been lurking around for some time. I’m a relatively new user of the language and it’s been a few months that I’ve started programming with it.

I’ve liked it so much that I’m now using it in my day to day work, building a web back-end (relying on Amber) for my company that will be ready for production in a couple of months.

So thanks a bunch to the core team and all the contributors for this wonderful language :bowing_man:!

One thing I noticed is that I could not find a shard to generate an OpenAPI file based on the Model and Controller definitions. (especially having a single source of truth - which is the model properties types and that gets reflected to the openapi document automatically)

So I created one, sharing it here just in case someone is interested:

6 Likes

I have created a new framework to prevent to write this boilerplate, for the big part: https://github.com/ricr-web/ricr

I have created a new framework to prevent to write this boilerplate, for the big part: https://github.com/ricr-web/ricr

That’s cool, but it’s not exactly the same thing :wink:.

openapi-generator is flexible and can adapt to any web framework, including Amber which I am using.

this is awesome! Thank you for posting this.

1 Like

A small update: openapi-generator now supports the Lucky Framework out of the box :partying_face:.

require "openapi-generator/helpers/lucky"

class Coordinates
  include JSON::Serializable
  extend OpenAPI::Generator::Serializable

  def initialize(@x, @y); end

  property x  : Int32
  property y  : Int32
end

class Api::Coordinates::Create < Lucky::Action
  include OpenAPI::Generator::Helpers::Lucky

  disable_cookies
  default_format :json

  # Infer query parameter.
  param add : Int32, description: "Add this number to the coordinates."

  route do
    # Infer body as a Coordinate json payload.
    coordinates = body_as! ::Coordinates, description: "Some coordinates"
    coordinates.x += add
    coordinates.y += add

    # Infer responses.
    if json?
      json coordinates, type: ::Coordinates
    elsif  xml?
      xml %(<coordinate x="#{coordinates.x}" y="#{coordinates.y}"></coordinate>), schema: OpenAPI::Schema.new(type: "string")
    elsif plain_text?
      plain_text "Coordinates (#{coordinates.x}, #{coordinates.y})"
    else
      head 406
    end
  end
end

Produces:

---
openapi: 3.0.1
info:
  title: Test
  version: 0.0.1
paths:
  /api/coordinates:
    post:
      parameters:
      - name: add
        in: query
        description: Add this number to the coordinates.
        required: true
        schema:
          type: integer
      requestBody:
        description: Some coordinates
        content:
          application/json:
            schema:
              allOf:
              - $ref: '#/components/schemas/Coordinates'
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/Coordinates'
            text/xml:
              schema:
                type: string
            text/plain:
              schema:
                type: string
        "406":
          description: Not Acceptable
components:
  schemas:
    Coordinates:
      required:
      - x
      - y
      type: object
      properties:
        x:
          type: integer
        y:
          type: integer
  responses: {}
  parameters: {}
  examples: {}
  requestBodies: {}
  headers: {}
  securitySchemes: {}
  links: {}
  callbacks: {}

4 Likes