GithubHelp home page GithubHelp logo

icyleaf / swagger Goto Github PK

View Code? Open in Web Editor NEW
40.0 4.0 10.0 3.85 MB

Swagger contains a OpenAPI / Swagger universal documentation generator and HTTP server handler.

License: MIT License

Crystal 94.93% HTML 5.07%
crystal crystal-http-handler crystal-api-document swagger swagger-generator swagger-documentation

swagger's Introduction

Swagger

Language Tag Source Document Build Status

Swagger is a low-level library which generates a document compatible with Swagger / OpenAPI Spec 3.0.3, and wrapped many friendly APIs let developer understand and use it easier.

Installation

dependencies:
  swagger:
    github: icyleaf/swagger

Quick look

require "swagger"

builder = Swagger::Builder.new(
  title: "App API",
  version: "1.0.0",
  description: "This is a sample api for users",
  terms_url: "http://yourapp.com/terms",
  contact: Swagger::Contact.new("icyleaf", "[email protected]", "http://icyleaf.com"),
  license: Swagger::License.new("MIT", "https://github.com/icyleaf/swagger/blob/master/LICENSE"),
  authorizations: [
    Swagger::Authorization.jwt(description: "Use JWT Auth"),
  ]
)

builder.add(Swagger::Controller.new("Users", "User resources", [
  Swagger::Action.new("get", "/users", description: "All users", responses: [
    Swagger::Response.new("200", "Success response")
  ]),
  Swagger::Action.new("get", "/users/{id}", description: "Get user by id", parameters: [
    Swagger::Parameter.new("id", "path")
  ], responses: [
    Swagger::Response.new("200", "Success response"),
    Swagger::Response.new("404", "Not found user")
  ], authorization: true),
  Swagger::Action.new("post", "/users", description: "Create User", responses: [
    Swagger::Response.new("201", "Return user resource after created"),
    Swagger::Response.new("401", "Unauthorizated")
  ], authorization: false)
]))

document = builder.built
puts document.to_json

Structure

Structure in src directory:

.
├── xxx.cr                        # Friendly APIs
├── http                          # HTTP assets and libraries
└── objects                       # OpenAPI objects

Running on web

Swagger provids a built-in web server, if you have no idea how to preview it:

require "swagger"
require "swagger/http/server"

# made your document (See `builder` code example above)
document = builder.built

# Run web server
Swagger::HTTP::Server.run(document)

Integrating

Swagger has two HTTP handlers which you can integrate it to bult-in HTTP Server and mostly frameworks (like kemal, amber, lucky etc):

  • Swagger::HTTP::APIHandler
  • Swagger::HTTP::WebHandler

Examples

See more examples.

Todo

  • openapi
  • Info Object
  • Paths Object
    • PathItem Object
      • Parameter Object
      • RequestBody Object
      • Responses Object
      • Security Object
      • Tag Object
  • Tags Object
  • Servers Objec
    • ServerVariables Object
  • Security Object
  • Components Object
    • Schemas Object
    • SecuritySchemes Object
      • Basic
      • Bearer (include JWT)
      • APIKey
      • OAuth2
  • ExternalDocs Object

How to Contribute

Your contributions are always welcome! Please submit a pull request or create an issue to add a new question, bug or feature to the list.

Here is a throughput graph of the repository for the last few weeks:

All Contributors are on the wall.

You may also like

  • halite - HTTP Requests Client with a chainable REST API, built-in sessions and middlewares.
  • totem - Load and parse a configuration file or string in JSON, YAML, dotenv formats.
  • markd - Yet another markdown parser built for speed, Compliant to CommonMark specification.
  • poncho - A .env parser/loader improved for performance.
  • popcorn - Easy and Safe casting from one type to another.
  • fast-crystal - 💨 Writing Fast Crystal 😍 -- Collect Common Crystal idioms.

License

MIT License © icyleaf

swagger's People

Contributors

erdnaxeli avatar grkek avatar icyleaf avatar j8r avatar jackharrhy avatar lribeiro avatar mrexox avatar nephos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

swagger's Issues

Use git submodule/subtree for Swagger UI?

Swagger UI is an entirely other project than this Crystal onel.
It would be better to use git module/subtree to easily update the files, instead of vendoring the JS/CSS files. It would also keep the history.

In my opinion, the whole Swagger HTTP server can even be an new Crystal project, based on this shard (but I agree it can be practical to have it here).

Support YAML format

The spec allows for YAML format of the documentation. Would be nice if we could also call to_yaml.

nested structures

Hey thank you so much for this project!

I am currently trying to define arrays of custom types as properties and I'm not exactly sure how that works?

So far I am getting the impression that I can only reference other objects for responses, but nothing else.

I have an object called Songs and I want to have an object called Queue that's just an array of songs

builder.add(Swagger::Object.new("Song", "object", [
  Swagger::Property.new("id", "string"),
  Swagger::Property.new("name", "string"),
  Swagger::Property.new("artist", "string"),
  Swagger::Property.new("image", "string"),
  Swagger::Property.new("length", "integer"),
]))

builder.add(Swagger::Object.new("Queue", "object", [
  Swagger::Property.new("songs", "array"),
]))

but instead of array I really want to have something like array[Song]. In general the examples don't seem to go over any kind of nesting so I'm having trouble conceptualising how I would go about this.

Using macros for a DSL

I came across this repo when looking for a way to parse swagger files. This project doesn't accomplish that, but it'd be cool if you could generate the swagger schema in Crystal with a DSL instead of building up via classes.

Maybe Swagger::Object accept Crystal Class or Struct?

I dig how macro works in Crystal and done a simple Reflect class, but Crystal can not accept Any Class or Struct as args of method. (also thanks @jhass in gitter)

module Swagger
  struct Object(T)
    property object : T
    property default_name : String
    property custom_name : String?

    def initialize(@object : T, @custom_name : String? = nil)
      @default_name = @custom_name ? @custom_name.as(String) : @object.class.name
    end

    def properties
      @object.instance_vars
    end
  end

  struct Mirror(T)
    property object

    def initialize(reflecting @object : T)
    end

    def instance_vars
      {% begin %}
        {{ ikeys = T.instance.instance_vars.map {|var| "#{var.type}.class" }.join('|').id }}
        vars = [] of Child({{ T.instance.instance_vars.map {|var| "#{var.type}.class" }.join('|').id }}, {{ T.instance.instance_vars.map {|var| var.type }.join('|').id }})
        {% for ivar in T.instance.instance_vars %}
          {{ iname = ivar.name.stringify }}
          {{ itype = ivar.type }}
          {{ irequired = !ivar.type.union? }}
          value = {% if T.class? || T.struct? %} @object.{{ ivar.name }} {% else %} {{ ivar.default_value }} {% end %}
          vars << Child.new({{ iname }}, {{ itype }}, value, {{ irequired }})
        {% end %}

        vars
      {% end %}
    end

    struct Child(K, V)
      getter :name, :type, :value, :required

      def initialize(@name : String, @type : K, @value : V, @required : Bool)
      end
    end
  end
end

Next add Object will be simple to add:

struct User
  property id, nickname, username, email, bio

  def initialize(@id : String, @nickname : String, @username : String, @email : String, @bio : String? = nil)
  end
end

user = User.new(
  UUID.random.to_s, "icyleaf wang", "icyleaf", "[email protected]", "Personal bio"
)

builder.add(Swagger::Object.new(user))

Support array for Swagger::Objects::Schema

Hi,

If I'm right, currently there is no way to do this:

    /pets:
      get:
        description: Returns all pets from the system that the user has access to
        responses:
          '200':
            description: A list of pets.
            content:
              application/json:
                schema:
                  type: array
                  items:
                    $ref: '#/components/schemas/pet'

Adding an item attribute to Swagger::Objects::Schema is enough. The struct must also become a class because item is itself of type Schema, and recursive structs are not allowed. I tested and it works.

If that's ok with you I could propose a PR.

Release a patch v0.1.1

Could you please release a new version with these changes: #3 ? There could be projects (like mine) that depend on this change.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.