Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Swagger automatic docs generator #15

Open
kazzkiq opened this issue Mar 25, 2019 · 2 comments

Comments

@kazzkiq
Copy link

commented Mar 25, 2019

First of all, thanks for this awesome and fully featured project.

Some frameworks I've worked with in other languages have an extremely useful feature that is generating Swagger docs automatically, just by "reading" the code you wrote.

Screen Shot 2019-03-25 at 12 29 35

Dynamic and interpreted languages have some trouble generating all the contracts (including param types, etc). But from the nature of Crystal (as a compiled, statically type checked language) it should be possible to create high fidelity contracts based on the project code.

The advantages of generating docs dynamically are as clear as it can get. It would be a great feature for Onyx Framework.

There is already a shard that let's you create such docs programmatically. Perhaps that could be used as a starting point.

@kazzkiq kazzkiq changed the title Implement Swagger automatic API generator Implement Swagger automatic docs generator Mar 25, 2019
@vladfaust

This comment has been minimized.

Copy link
Member

commented Apr 2, 2019

Below goes an example of annotations-based syntax. RFC.

require "onyx/http"
require "onyx/http/swagger"

Onyx::HTTP::Swagger.configure do
  title "App API"
  version "1.0.0"

  contact do
    name "John Doe"
    email "john@doe.com"
  end

  license do
    name "MIT"
  end

  authorizations do
    jwt do
      description "Auth via JWT"
    end

    api_key do
      name "API key auth"
      location "header"
    end
  end
end

@[Onyx::HTTP::Swagger::Action(summary: %Q[Say "Hello World!"])]
@[Onyx::HTTP::Swagger::Response(code: 200, description: "Always returns 200")]
Onyx::HTTP.get "/" do |env|
  env.response << "Hello World!"
end

@[Onyx::HTTP::Swagger::Controller(name: "User", description: "User resources")]
Onyx::HTTP.on "/users" do
  post "/", Endpoint::User::Create
  get "/:id", Endpoint::User::Get
  get "/", Endpoint::User::Index
end

Onyx::HTTP.get "/swagger", Onyx::HTTP::Swagger::Web
Onyx::HTTP.get "/swagger/api", Onyx::HTTP::Swagger::API

@[Onyx::HTTP::Swagger::Action(
  summary: "Create a user",
  description: "Creates a user from the request")]
@[Onyx::HTTP::Swagger::Response(
  code: 201,
  description: "Returned when user is created",
  content_type: "application/json")] # Onyx has content-type depending on Accept header...
struct Endpoint::User::Create
  include Onyx::HTTP::Endpoint

  params do
    # Generates a single Swagger::Request
    json require: true do
      @[Onyx::HTTP::Swagger::Property(description: "A user name", example: "Bob")]
      type name : String

      @[Onyx::HTTP::Swagger::Property(
        description: "A user email",
        example: "bob@example.com")]
      type email : String
    end
  end

  errors do
    @[Onyx::HTTP::Swagger::Response(description: "Returned if e-mail is already registered")]
    type EmailAlreadyRegistered(422)
  end
end

@[Onyx::HTTP::Swagger::Action(
  summary: "Retrieve a user",
  description: "Fetches a user from database by its ID")]
@[Onyx::HTTP::Swagger::Response(
  code: 200,
  description: "Returned when user is found",
  content_type: "application/json")]
struct Endpoint::User::Get
  include Onyx::HTTP::Endpoint

  params do
    # Generates Swagger::Parameter for every param
    path do
      @[Onyx::HTTP::Swagger::Parameter(description: "A user's ID")]
      type id : Int32
    end
  end

  errors do
    @[Onyx::HTTP::Swagger::Response(description: "Returned if user is not found")]
    type EmailAlreadyRegistered(404)
  end
end

@[Onyx::HTTP::Swagger::Action(summary: "Get many users")]
@[Onyx::HTTP::Swagger::Response(code: 200, content_type: "application/json")]
struct Endpoint::User::Index
  include Onyx::HTTP::Endpoint

  params do
    # Generates Swagger::Parameter for every param
    query do
      type limit : Int32 = 10
      type offset : Int32 = 0
    end
  end
end

It would also be possible to export Swagger JSON via Onyx CLI, I suppose.

@aemadrid

This comment has been minimized.

Copy link

commented May 24, 2019

I'd prefer being able to annotate endpoints with a DSL instead of annotations. They just look ugly to me: add a lot of noise that a clean DSL could clean up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.