From 246a1cfd6ff214ca0577b507f6fe22f151585712 Mon Sep 17 00:00:00 2001 From: Mike Ralphson Date: Thu, 24 Oct 2024 00:00:58 +0000 Subject: [PATCH] build: deploy docs --- docs/_data/readme.yaml | 116845 +++++--------------------------------- docs/_data/tools.yaml | 1799 +- 2 files changed, 15938 insertions(+), 102706 deletions(-) diff --git a/docs/_data/readme.yaml b/docs/_data/readme.yaml index d7d05c31..d9cc7c4c 100644 --- a/docs/_data/readme.yaml +++ b/docs/_data/readme.yaml @@ -1,175 +1,10 @@ -luckymarmot/API-Flow: > - [![Build - Status](https://travis-ci.org/luckymarmot/API-Flow.svg?branch=master)](https://travis-ci.org/luckymarmot/API-Flow) - - - # API-Flow - - - A flow written in ES6 using Immutable to convert between API description formats (Swagger, etc.) and other programs such as cURL command lines. - - - ## What formats are supported and what will be in the future - - We currently support: - - - `Swagger v2.0 (in/out)` - - - `RAML v1.0 (in/out)` - - - `Postman Collection v2.0 (in/out)` - - - `Paw v3.1 (in/out)` - - - We intend to support: - - - `Swagger v3.0` - - - `RAML v0.8` - - - `Postman Collection v1.0` - - - `Postman Dump v1.0` - - - `Insomnia v3.0` - - - `Api-Blueprint` - - - and many more. - - - ## Installation - - ### from a cloned repository - - - just run - - - ```sh - - git clone https://github.com/luckymarmot/API-Flow.git - - cd API-Flow - - make install - - ``` - - - This will install the node module dependencies - - - ## Building the different libraries - - ### node, web, and webworker - - - run the following command to build API-Flow for the different environments that you need - - - ```sh - - # use TARGET="node" if you only want the node library - - make runners TARGET="node web webworker" - - ``` - - - ### Paw - - - You can use the following command to add the different extensions to Paw - - - ```sh - - # use TARGET="swagger" if you only want the swagger bindings - - make transfer TARGET="swagger raml1 postman2" - - ``` - - - ## Using the npm module - - ### as a standard library - - - ```js - - const ApiFlow = require('api-flow'); // if from npm - - const ApiFlow = require('./dist/node/api-flow.js'); // if from `make runners TARGET="node"` - - - const options = { - source: { - format: 'swagger', - version: 'v2.0' - }, - target: { - format: 'raml', - version: 'v1.0' - } - } - - - const promise = ApiFlow.transform({ - options, - uri: path.resolve(__dirname, './my_super_swagger.yml') - }) - - - promise.then((data) => { - // do some cool stuff with the data - }) - - ``` - - - ### Using as a CLI (coming soon) - - ```sh - - node ./bin/api-flow.js some_swagger.json -f swagger -t raml > converted.yml - - ``` - - - ### User Interface - - - API-Flow is one of the main components of [Console.REST](https://github.com/luckymarmot/console-rest). If you're an API user, you can easily use [https://console.rest/](https://console.rest/) to convert API description files. If you're an API provider, you can add a button to your API docs to let your users open and play with your API in client apps including Paw or Postman. - - - ## Contributing - - - PRs are welcomed! - - Our sole requirement is that organizations that want to extend API-Flow to support their format write both a parser and a serializer, and not simply a serializer. - - - ## Documentation - - You can find more information about the internal structure of API-Flow in [src](https://github.com/luckymarmot/API-Flow/tree/develop/src). We've also created a set of templates to help speed up the extension process: [loader](https://github.com/luckymarmot/API-Flow/tree/develop/src/loaders/template/v1.0), [parser](https://github.com/luckymarmot/API-Flow/tree/develop/src/parsers/template/v1.0/), and [environment](https://github.com/luckymarmot/API-Flow/tree/develop/src/environments/template) - - - ## License - - - This repository is released under the [MIT License](LICENSE). Feel free to fork, and modify! - - Copyright © 2016 Paw Inc. - - - ## Contributors - - - See [Contributors](https://github.com/luckymarmot/API-Flow/graphs/contributors). +luckymarmot/API-Flow: "{\"message\":\"API rate limit exceeded for 74.249.13.182. + (But here's the good news: Authenticated requests get a higher rate limit. + Check out the documentation for more details.) If you reach out to GitHub + Support for help, please include the request ID + B4EA:ED9B9:33AFA6:60BB4C:67198DEA and timestamp 2024-10-23 23:59:38 + UTC.\",\"documentation_url\":\"https://docs.github.com/rest/overview/rate-lim\ + its-for-the-rest-api\",\"status\":\"403\"}" googleapis/gnostic: > [![Build Status](https://travis-ci.org/googleapis/gnostic.svg?branch=master)](https://travis-ci.org/googleapis/gnostic) @@ -398,103 +233,20 @@ Mermade/swagger2openapi: > * [APIs.guru open-collective](https://opencollective.com/openapi-directory) * [Linode VPS referral link](https://www.linode.com/?r=5734be467cc501b23267cf66d451bc339042ddfa) -oasis-tcs/odata-openapi: > -
- -

README

- - -

Members of the OASIS Open Data Protocol (OData) Technical Committee create and manage technical content in this TC GitHub repository ( https://github.com/oasis-tcs/odata-openapi ) as part of the TC's chartered work (i.e., the program of work and deliverables described in its charter).

- - -

OASIS TC GitHub repositories, as described in GitHub Repositories for OASIS TC Members' Chartered Work, are governed by the OASIS TC Process, IPR Policy, and other policies, similar to TC Wikis, TC JIRA issues tracking instances, TC SVN/Subversion repositories, etc. While they make use of public GitHub repositories, these TC GitHub repositories are distinct from OASIS Open Repositories, which are used for development of open source licensed content.

- -
- - -
- -

Description

- - -

The purpose of this repository is to support development of tools for producing OpenAPI descriptions for OData services.

- -

Planned work items include: - -

- - -
- - -
- -

Contributions

- -

As stated in this repository's CONTRIBUTING file, contributors to this repository are expected to be Members of the OASIS OData TC, for any substantive change requests. Anyone wishing to contribute to this GitHub project and participate in the TC's technical activity is invited to join as an OASIS TC Member. Public feedback is also accepted, subject to the terms of the OASIS Feedback License.

- -
- - -
- -

Licensing

- -

Please see the LICENSE file for description of the license terms and OASIS policies applicable to the TC's work in this GitHub project. Content in this repository is intended to be part of the OData TC's permanent record of activity, visible and freely available for all to use, subject to applicable OASIS policies, as presented in the repository LICENSE file.

- -
- - - -

Further Description of this Repository

- - - The OData TC has published the [OData to OpenAPI Mapping Version 1.0](http://docs.oasis-open.org/odata/odata-openapi/v1.0/odata-openapi-v1.0.html), a recommendation on how to create OpenAPI descriptions for OData services. This project contains two proof-of-concept implementations of that mapping, [one using JavaScript](lib), and [one using XSLT](tools). - - - The [`examples` folder](examples) contains [OpenAPI 3.0.2](https://github.com/OAI/OpenAPI-Specification) descriptions that have been created from the XML `$metadata` documents of live and example OData services with these proof-of-concept implementations. - - - The entity-relationship diagrams visualizing the resource models of each service are generated on-the-fly with [yUML](http://yuml.me/). - - - OpenAPI descriptions for live example OData services at [www.odata.org](http://www.odata.org/) - - [TripPin (read/write)](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/oasis-tcs/odata-openapi/master/examples/TripPin.openapi3.json) - - [Simple read/write service](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/oasis-tcs/odata-openapi/master/examples/example.openapi3.json) - - [Northwind (read)](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/oasis-tcs/odata-openapi/master/examples/Northwind.openapi3.json) - - OpenAPI descriptions for OData services that reference each other (cross-service references) - - [People](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/oasis-tcs/odata-openapi/master/examples/People.openapi3.json) - - [Products](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/oasis-tcs/odata-openapi/master/examples/Products.openapi3.json) - -
- -

Contact

- -

Please send questions or comments about OASIS TC GitHub repositories to the OASIS TC Administrator. For questions about content in this repository, please contact the TC Chair or Co-Chairs as listed on the the OData TC's home page.

- -
-xuzhg/OData.OpenAPI: > - # OData.OpenAPI - - - A project to convert an Edm (Entity Data Model) to [OpenApi 3.0](https://swagger.io/specification/). - - - Now, the Whole project is moving to: https://github.com/microsoft/openapi.net for basic Open API DOM and - - - https://github.com/microsoft/openapi.net.odata for basic CSDL to Open API DOM. +oasis-tcs/odata-openapi: "{\"message\":\"API rate limit exceeded for + 74.249.13.182. (But here's the good news: Authenticated requests get a higher + rate limit. Check out the documentation for more details.) If you reach out to + GitHub Support for help, please include the request ID + B493:A0544:3ADB26:6EA908:67198DEE and timestamp 2024-10-23 23:59:42 + UTC.\",\"documentation_url\":\"https://docs.github.com/rest/overview/rate-lim\ + its-for-the-rest-api\",\"status\":\"403\"}" +xuzhg/OData.OpenAPI: "{\"message\":\"API rate limit exceeded for 74.249.13.182. + (But here's the good news: Authenticated requests get a higher rate limit. + Check out the documentation for more details.) If you reach out to GitHub + Support for help, please include the request ID + B4C8:15E92A:17DBD12:2D5521E:67198E01 and timestamp 2024-10-24 00:00:01 + UTC.\",\"documentation_url\":\"https://docs.github.com/rest/overview/rate-lim\ + its-for-the-rest-api\",\"status\":\"403\"}" mission-liao/pyswagger: >+ pyswagger @@ -877,294 +629,20 @@ koumoul-dev/openapi-viewer: > * **headers** : URI encoded JSON dictionnary of headers that will be used to prefill parameters if they match. Can be usefull to prefill *x-api-key* or *authorization* headers. * **query-params** : URI encoded JSON dictionnary of query parameters that will be used to prefill parameters if they match. Can be usefull to prefill an *organizationId* parameter in a multi-tenant application. * **hide-toolbar** : true or false of you want to hide toolbar. This can be usefull for iframe integration. Defaults to false. -contentjet/openapi-ui: > - # OpenAPI UI - - - This is a React based single page app which renders documentation from a valid OpenAPI 3.0.0-RC0 document. - - - # NOTE - - - This project was experimental and is not being actively maintained. - - - ## Getting started - - - #### Project setup - - - Install project dependencies: - - - ``` - - npm install - - ``` - - - #### Run development server - - - ``` - - npm start - - ``` - - - #### Run linter - - - ``` - - npm run lint - - ``` - - - #### Create production build - - - ``` - - npm run build - - ``` -sourcey/spectacle: > - # Spectacle - - - > The gentleman at REST - - - [![CircleCI](https://circleci.com/gh/sourcey/spectacle.svg?style=svg)](https://circleci.com/gh/sourcey/spectacle) - - - Spectacle generates beautiful static HTML5 documentation from [OpenAPI](https://openapis.org)/[Swagger](http://swagger.io) 2.0 API specifications. - - - The goal of Spectacle is help you "save time and look good" by providing an extensible platform for auto generating your REST API docs. The default layout is a three column single page, similar to those - - employed by [Stripe](https://stripe.com/docs/api) and [Intercom](https://developers.intercom.com/reference). - - - See a demo of Spectacle in action here: [http://cheesestore.github.io](http://cheesestore.github.io) - - - --- - - - ![Demo Screenshot](screenshot.jpg) - - - --- - - - ## Features - - - * **OpenAPI/Swagger 2.0 support**: Support for the latest OpenAPI/Swagger specification. - - * **Highly configurable**: Easily configurable Handlebars templates and SCSS styles so you can add your own design and flavour without going bald. See [Custom Builds](#custom-builds) - - * **Markdown support**: Render markdown written in any of your API descriptions. - - * **Remote file references**: Support for swagger specs split across multiple files. - - * **Clean responsive design**: Responsive HTML5 and CSS3 layout built with [Foundation 6](http://foundation.zurb.com/sites.html) that looks great on all devices and screen sizes. - - * **Embed into your existing website**: An embedded option so that generate partial docs without a HTML `` for convenient integration into your existing website. - - * **Live preview developer mode**: Development mode that starts a local HTTP server with a file watcher and live reload so you can preview live changes in your browser as you update your spec. - - - ## Usage - - - Simply install Spectacle from `npm` like so: - - - ```bash - - npm install -g spectacle-docs - - ``` - - - Next pass your `swagger.json` document use the CLI to generate your documentation. - - - ```bash - - spectacle -d your_swagger_api.json - - - # Or use the cheese.json example to test it out - - # spectacle -d -l test/fixtures/cheese.png test/fixtures/cheese.yml - - ``` - - - Your generated documentation will be located in the `public` directory by default. You can either copy the generated HTML to your web server, or view your docs by pointing your browser to [http://localhost:4400/](http://localhost:4400/). - - - ### Docker - - - [Docker](https://hub.docker.com/r/sourcey/spectacle/) images are included that allow Spectacle to be run from the inside. It's useful, for instance, in a Gitlab CI pipeline. Thanks @alexeiaguiar. - - - How to use it: `docker run -it sourcey/spectacle /bin/sh` - - - ## Configuration Options - - - The basic CLI options are detailed below: - - - ```bash - - $ spectacle -h - - Usage: spectacle [options] - - Options: - - -h, --help output usage information - -V, --version output the version number - -C, --disable-css omit CSS generation (default: false) - -J, --disable-js omit JavaScript generation (default: false) - -e, --embeddable omit the HTML and generate the documentation content only (default: false) - -d, --development-mode start HTTP server with the file watcher (default: false) - -D, --development-mode-live start HTTP server with the file watcher and live reload (default: false) - -s, --start-server start the HTTP server without any development features - -p, --port the port number for the HTTP server to listen on (default: 4400) - -P, --port-live the port number for the live reload to listen on (default: 4401) - -t, --target-dir the target build directory (default: public) - -f, --target-file the target build HTML file (default: index.html) - -a, --app-dir the application source directory (default: app) - -l, --logo-file specify a custom logo file (default: null) - -c, --config-file specify a custom configuration file (default: app/lib/config.js) - ``` - - - Most options are self explanatory, but the following options warrant some further explanation: - - - * **--development-mode** `-d`: This option starts a development server with a file watcher, and will automatically regenerate your docs when any of your spec or app files change. - - - * **--development-mode-live** `-D`: This option starts a development server with a file watcher and live reload, and will automatically regenerate your docs when any of your spec or app files change. - - - * **--start-server** `-s`: This option starts a production server without any development options enabled that serves the contents of your `--target-dir`. - - - * **--embeddable** `-e`: This option lets you build a minimal version of the documentation without the HTML `` tags, so you can embed Spectacle into your own website template. More info on [custom builds](#custom-builds) here. - - - * **--app-dir** `-a`: This option overrides the default directory which contains all the Handlebars templates, SCSS, and JavaScript source files. This option is useful for development because you can copy the contents of `app` to a remote location or a separate repo for custom builds. - - - * **--target-dir** `-t`: This option specifies where the generated documentation HTML files will be output. - - - ## Custom Builds - - - The best option for building your own custom functionality into Spectacle is to [fork Spectacle on GitHub](https://help.github.com/articles/fork-a-repo/), and make your own modifications in source. This way you can keep up to date by merging changes from the `master` branch, and your can also contribute your updates back to `master` by creating a [Pull Request](https://help.github.com/articles/creating-a-pull-request/) if you think they improve Spectacle somehow. - - - To fork Spectacle go to `https://github.com/sourcey/spectacle`, and press the 'Fork' button. Now you can `git clone git@github.com:/spectacle.git` to make your own changes. - - - Alternatively, you can just copy the contents of `app` from the main repo which contains all the source files such as templates, stylesheets and JavaScripts. Now just pass the path to your custom `app` path to the CLI like so: `spectacle -a /path/to/your/app your_swagger_api.json` - - - ## Optimizing Your Workflow - - - Using an API spec to generate your docs has a number of great advantages, such as: - - - * **Maintain a single source**: Save time by removing the need to maintain a separate API spec and API documentation. - - * **No more out-of-date documentation**: Your documentation will always be up-to-date with your API spec. - - * **Be a better developer**: Your entire API system will be more stable and robust when built around your spec as a single source of truth. - - - As developer we're always looking for ways to improve and optimize our workflow, and documentation is just the beginning. With a well written Swagger you can automate and generate many parts of your API system, such as: - - - * **Inline Code Generators**: Generate your Swagger JSON or YAML from your source code comments. - - * **Automate Testing**: Automate testing for all your API endpoints. - - * **Code Generation**: Automatically generate client and server code from your spec. - - * **Generate Documentation**: Really? - - - For a list of open source Swagger based libraries in many languages check here: http://swagger.io/open-source-integrations/ - - - ## Development - - - ### Testing - - - Testing is powered by [Mocha](https://mochajs.org/)/[Chai](http://chaijs.com/), and automated testing is run via [CircleCI](https://circleci.com/). - - - At this stage, unit tests have not been written for all parts of the codebase. However, new code should be tested, and unit tests for the existing code will be added in the future. - - - Run `npm test` on the repository to start the automated tests. - - Some parts of testing can be configured using environment variables. - - - - `OFFLINE=true` - Some tests use HTTP connections to test giving Spectacle remote API specifications. - Use `OFFLINE=true` to skip tests that require an internet connection. - - Include environment variables before calling `npm test`. For example, `OFFLINE` mode can be enabled via `OFFLINE=true npm test`. - - - - - - - - ## More Information - - - More info is available on the [Spectacle homepage](http://sourcey.com/spectacle). - - - Please use the [GitHub issue tracker](https://github.com/sourcey/spectacle/issues) if you have any ideas or bugs to report. - - - All contributions are welcome. - - - Good luck and enjoy Spectacle! +contentjet/openapi-ui: "{\"message\":\"API rate limit exceeded for + 74.249.13.182. (But here's the good news: Authenticated requests get a higher + rate limit. Check out the documentation for more details.) If you reach out to + GitHub Support for help, please include the request ID + B4C6:C36BC:3A6CD2:6DDCC3:67198DDC and timestamp 2024-10-23 23:59:24 + UTC.\",\"documentation_url\":\"https://docs.github.com/rest/overview/rate-lim\ + its-for-the-rest-api\",\"status\":\"403\"}" +sourcey/spectacle: "{\"message\":\"API rate limit exceeded for 74.249.13.182. + (But here's the good news: Authenticated requests get a higher rate limit. + Check out the documentation for more details.) If you reach out to GitHub + Support for help, please include the request ID + B4D4:161B14:3793FC:6819CD:67198DF6 and timestamp 2024-10-23 23:59:50 + UTC.\",\"documentation_url\":\"https://docs.github.com/rest/overview/rate-lim\ + its-for-the-rest-api\",\"status\":\"403\"}" Rebilly/ReDoc: >
ReDoc logo @@ -2249,584 +1727,27 @@ Rebilly/generator-openapi-repo: > [daviddm-image]: https://david-dm.org/Rebilly/generator-openapi-repo.svg?theme=shields.io [daviddm-url]: https://david-dm.org/Rebilly/generator-openapi-repo -temando/open-api-renderer: > - # Lincoln - - - Lincoln - - - [![NPM](https://img.shields.io/npm/v/react-lincoln.svg)](https://npmjs.org/packages/react-lincoln/) - - [![Travis CI](https://img.shields.io/travis/temando/open-api-renderer.svg)](https://travis-ci.org/temando/open-api-renderer) - - [![MIT License](https://img.shields.io/github/license/temando/open-api-renderer.svg)](https://en.wikipedia.org/wiki/MIT_License) - - [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) - - - Meet Lincoln, a [React](https://facebook.github.io/react/) component for rendering [OpenAPI](https://www.openapis.org) documents. The project is tracking against [v3.0.0](docs/open-api-v3-support.md) of the OpenAPI specification. - - - Lincoln aims to support evergreen browsers, such as Chrome, Firefox, Safari and IE11+. It is responsive and should be usable on most modern devices. - - - [Demo](https://temando.github.io/open-api-renderer/demo/?url=https://temando.github.io/open-api-renderer/petstore-open-api-v3.0.0-RC2.json) - - - ## Installation - - - ```sh - - npm install --save react react-dom react-lincoln - - ``` - - - ## Usage - - - To use Lincoln in your React project: - - - ```js - - import React from 'react' - - import ReactDOM from 'react-dom' - - import Lincoln from 'react-lincoln' - - - ReactDOM.render( - , - document.body - ) - - ``` - - - Alternatively, you can pass the contents of the definition directly to Lincoln: - - - ```js - - import React from 'react' - - import ReactDOM from 'react-dom' - - import Lincoln from 'react-lincoln' - - import definition from './myApi.yml' - - - ReactDOM.render(, document.body) - - ``` - - - ## Configuration - - - The following configuration options are available: - - - | property | required | type | description | - - | ------------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - - | `definitionUrl` or `definition` | ✔ | string | CORS-enabled URL to, or contents of, OpenAPI v3 document to render. Supports JSON or YAML. | - - | `navSort` | | enum | This property applies when your definition uses `tags`. Valid values are `alpha` which sorts by HTTP method, then path or `false`, which will display paths as defined. Defaults to `false`. | - - | `validate` | | boolean | If `true`, uses [Mermade](https://openapi-converter.herokuapp.com/) to validate definition. Defaults to `false`. | - - | `initialSchemaTreeDepth` | | number | The initial opened tree depth for schema visualiser when first rendered. This is useful when the schema's actual contents is a couple of levels deep, and you want to expand the tree to the contents automatically. Defaults to 0. | - - | `navigationMethodDisplayType` | | string | Regulates how the navigation items are rendered - path only, summary only, or both. The possible values are `summary` (default), `path`, or `all`. In case of any other value only the summary is rendered. | - - - ## Philosophy - - - While this project is currently focused on visualising OpenAPI V3 specifications, it is architected in such a way that the React components deal with a `UIReadySchema`, which is a generic specification (admittedly heavily based on OpenAPI V3). - - - The dream is that this renderer could visualise other formats by introducing new parsers which transform documents into the common `UIReadySchema` format. This approach allows us to build something sustainable and scalable, where the community can help contribute new parsers (among other things!) as required. - - - The project is definitely in its infancy and we are not ready for that yet, but we hope by sharing this vision early, others can help make it a reality. For contributing information, see [CONTRIBUTING.md](CONTRIBUTING.md). - - - ## Credit - - - - The [ReDoc](https://github.com/Rebilly/ReDoc) project inspired Lincoln. If you're looking for an alternative renderer, give ReDoc a try! - - - [swagger2openapi](https://github.com/mermade/swagger2openapi) which Lincoln uses to validate definitions. - - - ## Maintainers - - - Lincoln is an open source project from [Temando](http://temando.com/)'s Developer Experience team. Temando connects carriers with retailers and retailers to people. The Temando Platform combines shipping experiences, multi-carrier connectivity and lightning fast fulfillment in one solution. If this sounds like fun, [work with us](http://temando.com/en/about/careers)! -RepreZen/KaiZen-OpenAPI-Editor: > - KaiZen OpenAPI Editor Logo - - - # KaiZen OpenAPI Editor for Eclipse - - - _KaiZen OpenAPI Editor_ is an Eclipse editor for the [industry standard API description language](http://openapis.org), formerly known as [Swagger](http://swagger.io). It now supports both [Swagger-OpenAPI version 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) and [OpenAPI version 3.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md). - - - KaiZen Editor is a core component of [RepreZen API Studio](http://reprezen.com/swagger-tools), a comprehensive solution for API modeling, documentation, visualization, testing and code generation, built on Eclipse. - - - We welcome your suggestions and contributions! - - - ## Eclipse Installer - - - KaiZen OpenAPI Editor is available on [Eclipse Marketplace](https://marketplace.eclipse.org/content/kaizen-openapi-editor). Drag-and-drop this button into Eclipse Oxygen or later to install, or [see below](#installing-kaizen-openapi-editor) for other options: - - - [![Drag to your running Eclipse workspace.](./etc/img/btn-install.png)](http://marketplace.eclipse.org/marketplace-client-intro?mpc_install=3429028 "Drag to your running Eclipse workspace.") - - - ## NEW! OpenAPI 3.0 Editing - - - KaiZen OpenAPI Editor now features full support for the [OpenAPI version 3.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md) specification. [See here for further details.](https://github.com/RepreZen/KaiZen-OpenAPI-Editor/blob/master/OPEN_API_V3_SUPPORT.md) - - ## Feature Highlights - - - Drawing - - - ### Validation - - Validation_screenshot - - - ### Code Assist - - Code templates: - - Code_template - - - Keywords and values: - - CodeAssist_keys_and_values - - - ### Code Assist for References - - Code assist for references has several scopes which can be viewed in sequence by pressing `Ctrl`+`Space` repeatedly: - - - * The first scope shows only elements from the current document. - - * The second expands it to elements from the containing project. - - * The third shows elements from the entire workspace. - - - CodeAssist_for_references - - - Pressing the hotkey a fourth time starts the cycle over again, with document scope. - - - ### Navigation to a Reference - - You can navigate to a reference using `Ctrl`+`Click`: - - Navigation_to_references - - - ### Quick Outline - - Quick Outline can be invoked with `Ctrl`+`o`. Similar to code assist for references, it has three scopes: model, project, and workspace. It also allows filtering: - - Navigation_to_references - - - ### Outline - - Outline View shows the contents of the active OpenAPI spec: - - Navigation_to_references - - - ## Installing KaiZen OpenAPI Editor - - KaiZen OpenAPI Editor requires Java 8 (64-bit) and Eclipse Oxygen or later. - - - ### Installing from Eclipse Marketplace - - The [Eclipse Marketplace solution](https://marketplace.eclipse.org/content/kaizen-openapi-editor) is the easiest way to install KaiZen Editor into an Eclipse IDE. You can drag-and-drop the Install button from the browser into your Eclipse IDE, or use the built-in Eclipse Marketplace Client. - - - [![Drag to your running Eclipse workspace.](./etc/img/btn-install.png)](http://marketplace.eclipse.org/marketplace-client-intro?mpc_install=3429028 "Drag to your running Eclipse workspace.") - - - ### Installing from the Update Site - - You can install KaiZen OpenAPI Editor into your Eclipse IDE by clicking `Help > Install New Software... > Add...` - - This will show a dialog box where you can select the location of the update site. - - Use the update site http://products.reprezen.com/swagedit/latest/ as the URL. - - - ### Installing RepreZen API Studio - - KaiZen Editor is included as a core component of RepreZen API Studio, which adds live documentation and diagram views, sandbox testing with the built-in mock service and Swagger-UI, powerful code generation, and other features. - - - RepreZen API Studio is available through two different installation options: - - * [API Studio Desktop](http://www.reprezen.com/OpenAPI) installs as a standalone desktop application on Windows, MacOS or Linux. - - * [API Studio for Eclipse](https://marketplace.eclipse.org/content/reprezen-api-studio) installs into an Eclipse IDE distribution, allowing you to use RepreZen's API design, documentation and development features in your primary Eclipse development environment.
- - [![Drag to your running Eclipse workspace.](./etc/img/btn-install.png)](http://marketplace.eclipse.org/marketplace-client-intro?mpc_install=3138718 "Drag to your running Eclipse workspace.") - - - ## Troubleshooting - - See the [Troubleshooting Guide](https://github.com/RepreZen/SwagEdit/blob/master/TROUBLESHOOTING.md) for solutions to common problems. - - - ## Contributing to KaiZen OpenAPI Editor - - We welcome contributions - documentation, bug reports or bug fixes. - - If you are interested in contributing to KaiZen Editor, please see the [Developer's Guide](https://github.com/RepreZen/SwagEdit/blob/master/DEVELOPERS_GUIDE.md). - - - We also created a list of [good first bugs](https://github.com/RepreZen/SwagEdit/labels/Good%20First%20Bug) - - that are relatively easy to fix. - - - ## License - - KaiZen OpenAPI Editor is provided under the [Eclipse Public License v1.0](https://www.eclipse.org/legal/epl-v10.html) - - - ## Video: KaiZen Editor in RepreZen API Studio - - - [![Editing Swagger-OpenAPI in RepreZen API Studio](http://img.youtube.com/vi/KX_tHp_KQkE/0.jpg)](https://www.youtube.com/watch?v=KX_tHp_KQkE) - - - _**Note:** KaiZen Editor includes code assist, real-time validation, syntax highlighting, and outline view.
- - [Eclipse Color Theme](https://marketplace.eclipse.org/content/eclipse-color-theme) and [EditBox](http://marketplace.eclipse.org/content/nodeclipse-editbox-background-colors-themes-highlight-code-blocks-c-java-javascript-python) are available as separate plugins.
- - [RepreZen API Studio](http://reprezen.com/swagger-tools) includes the mock service, live Swagger-UI, advanced code generation, and other features that are not part of KaiZen Editor. See the [feature comparison here](https://support.reprezen.com/support/solutions/articles/24000046272-what-s-the-difference-between-kaizen-openapi-editor-and-reprezen-api-studio-)._ -swagger-api/swagger-editor: > - # - - [![NPM version](https://badge.fury.io/js/swagger-ui.svg)](http://badge.fury.io/js/swagger-editor) - - [![Build Status](https://jenkins.swagger.io/buildStatus/icon?job=oss-swagger-editor-master)](https://jenkins.swagger.io/job/oss-swagger-editor-master/) - - [![Code Climate](https://codeclimate.com/github/swagger-api/swagger-editor/badges/gpa.svg)](https://codeclimate.com/github/swagger-api/swagger-editor) - - [![Build Status](https://jenkins.swagger.io/view/OSS%20-%20JavaScript/job/oss-swagger-editor-master/badge/icon?subject=jenkins%20build)](https://jenkins.swagger.io/view/OSS%20-%20JavaScript/job/oss-swagger-editor-master/) - - - **🕰️ Looking for the older version of Swagger Editor?** Refer to the [*2.x* branch](https://github.com/swagger-api/swagger-editor/tree/2.x). - - - Swagger Editor lets you edit [OpenAPI API definitions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md) in YAML inside your browser and to preview documentations in real time. - - Valid Swagger JSON descriptions can then be generated and used with the full Swagger tooling (code generation, documentation, etc). - - - As a brand new version, written from the ground up, there are some known issues and unimplemented features. Check out the [Known Issues](#known-issues) section for more details. - - - This repository publishes to two different NPM modules: - - - * [swagger-editor](https://www.npmjs.com/package/swagger-editor) is a traditional npm module intended for use in single-page applications that are capable of resolving dependencies (via Webpack, Browserify, etc). - - * [swagger-editor-dist](https://www.npmjs.com/package/swagger-editor-dist) is a dependency-free module that includes everything you need to serve Swagger Editor in a server-side project, or a web project that can't resolve npm module dependencies. - - - If you're building a single-page application, using `swagger-editor` is strongly recommended, since `swagger-editor-dist` is significantly larger. - - - For the older version of swagger-editor, refer to the [*2.x branch*](https://github.com/swagger-api/swagger-editor/tree/2.x). - - - ## Helpful scripts - - - Any of the scripts below can be run by typing `npm run - + You can select the backend in the constructor of the parser(s): - - Pet: {{ pet.name || 'Loading...' }} - + .. code:: python - - + parser = ResolvingParser('http://petstore.swagger.io/v2/swagger.json', backend = 'openapi-spec-validator') - - + No backend is included in the dependencies; they are detected at run-time. If you install them, - + they can be used: - ``` + .. code:: bash - # Real-world Example + $ pip install openapi-spec-validator + $ pip install prance + $ prance validate --backend=openapi-spec-validator path/to/spec.yml - ```javascript + *A note on flex usage:* While flex is the fastest validation backend, unfortunately it is no longer - 'use strict'; + maintained and there are issues with its dependencies. For one thing, it depends on a version of `PyYAML` + that contains security flaws. For another, it depends explicitly on older versions of `click`. - // First, we need to define a provider for the api client, we'll call it 'myAPI' - angular.module('data').provider('myAPI', + If you use the flex subpackage, therefore, you do so at your own risk. - ['window', function(window){ - var schema = window.API_SCHEMA, - auth; - // Override the base path to enable pointing to different backends - this.basePath = function(basePath){ - schema.apis.forEach(function(api){ - api.apiDeclaration.basePath = basePath; - }); - }; + *Compatibility* - // Allows for setting the auth token during .config() phase of app start up. - this.auth = function(authToken){ - auth = authToken; - }; - // Instantiates the swagger-angular-client - this.$get = ['$rootScope', 'swaggerClient', function($rootScope, swaggerClient){ - var api = swaggerClient(schema); - api.authorization(auth); + See `COMPATIBILITY.rst `__ - // Handle any future api token changes - $rootScope.$on('api token changed', function($event, authToken){ - api.authorization(authToken); - }); + for a list of known issues. - return api; - }]; - }]) - // Now we'll configure myAPI during app start up by setting the auth token. + Partial Reference Resolution - // You would decide where this token comes from. Maybe it's ok to embed directly + ---------------------------- - // in the code. Maybe it comes from a cookie. Maybe you don't even need auth. - // This all depends on your auth scheme. + It's possible to instruct the parser to only resolve some kinds of references. - .config(['myAPIProvider', function(myAPIProvider){ - myAPIProvider.auth(THE_TOKEN); - }]) + This allows e.g. resolving references from external URLs, whilst keeping local + references (i.e. to local files, or file internal) intact. - // Finally, we can start using myAPI in the application - .run(['myAPI', function(myAPI){ - // This would be an application-specific call. In this example, we make an - // http request to a api endpoint to notify the metrics resource that the - // application has loaded. - myAPI.metrics.appLoaded({ - time: Date.now() - }); - }]); + .. code:: python + from prance import ResolvingParser + from prance.util.resolver import RESOLVE_HTTP - ``` -richhollis/swagger-docs: > - # Swagger::Docs + parser = ResolvingParser('/path/to/spec', resolve_types = RESOLVE_HTTP) - Generates swagger-ui json files for rails apps with APIs. You add the swagger DSL to your controller classes and then run one rake task to generate the json files. + Multiple types can be specified by OR-ing constants together: - [![Gem Version](https://badge.fury.io/rb/swagger-docs.svg)][gem] + .. code:: python - [![Dependency Status](https://gemnasium.com/richhollis/swagger-docs.svg?travis)][gemnasium] + from prance import ResolvingParser + from prance.util.resolver import RESOLVE_HTTP, RESOLVE_FILES + parser = ResolvingParser('/path/to/spec', resolve_types = RESOLVE_HTTP | RESOLVE_FILES) - [gem]: https://rubygems.org/gems/swagger-docs - [travis]: http://travis-ci.org/richhollis/swagger-docs + Extensions - [gemnasium]: https://gemnasium.com/richhollis/swagger-docs + ---------- - [coveralls]: https://coveralls.io/r/richhollis/swagger-docs + Prance includes the ability to reference outside swagger definitions - ## Swagger Version Specification Support + in outside Python packages. Such a package must already be importable + (i.e. installed), and be accessible via the - This project supports elements of the v1.2 swagger specification. It *does not* support the v2 specification. If you are looking for support for the newer specification the please see the [swagger-blocks](https://github.com/fotinakis/swagger-blocks/) project. I don't currently have any plans to add support for v2.0 at this time due to time constraints, but I'm open to accepting a PR on this. Contact me if you are interested in helping with that effort - thanks! + `ResourceManager API `__ + (some more info `here `__). - ## Example usage + For example, you might create a package ``common_swag`` with the file - Here is an extract of the DSL from a user controller API class: + ``base.yaml`` containing the definition - ```ruby + .. code:: yaml - swagger_controller :users, "User Management" + definitions: + Severity: + type: string + enum: + - INFO + - WARN + - ERROR + - FATAL + In the ``setup.py`` for ``common_swag`` you would add lines such as - swagger_api :index do - summary "Fetches all User items" - notes "This lists all the active users" - param :query, :page, :integer, :optional, "Page number" - response :unauthorized - response :not_acceptable - response :requested_range_not_satisfiable - end - ``` + .. code:: python + packages=find_packages('src'), + package_dir={'': 'src'}, + package_data={ + '': '*.yaml' + } - ## Installation + Then, having installed ``common_swag`` into some application, you could + now write - Add this line to your application's Gemfile: - gem 'swagger-docs' + .. code:: yaml - And then execute: + definitions: + Message: + type: object + properties: + severity: + $ref: 'python://common_swag/base.yaml#/definitions/Severity' + code: + type: string + summary: + type: string + description: + type: string + required: + - severity + - summary - $ bundle + Contributing - Or install it yourself as: + ============ - $ gem install swagger-docs - ## Usage + See `CONTRIBUTING.md `__ for details. - ### Create Initializer + Professional support is available through `finkhaeuser consulting `__. - Create an initializer in config/initializers (e.g. swagger_docs.rb) and define your APIs: + License + ======= - ```ruby - Swagger::Docs::Config.register_apis({ - "1.0" => { - # the extension used for the API - :api_extension_type => :json, - # the output location where your .json files are written to - :api_file_path => "public/api/v1/", - # the URL base path to your API - :base_path => "http://api.somedomain.com", - # if you want to delete all .json files at each generation - :clean_directory => false, - # Ability to setup base controller for each api version. Api::V1::SomeController for example. - :parent_controller => Api::V1::SomeController, - # add custom attributes to api-docs - :attributes => { - :info => { - "title" => "Swagger Sample App", - "description" => "This is a sample description.", - "termsOfServiceUrl" => "http://helloreverb.com/terms/", - "contact" => "apiteam@wordnik.com", - "license" => "Apache 2.0", - "licenseUrl" => "http://www.apache.org/licenses/LICENSE-2.0.html" - } - } - } - }) + Licensed under MITNFA (MIT +no-false-attribs) License. See the - ``` + `LICENSE.txt `__ file for details. - #### Configuration options + "Prancing unicorn" logo image Copyright (c) Jens Finkhaeuser. + Made by `Moreven B `__. Use of the logo is permitted under - The following table shows all the current configuration options and their defaults. The default will be used if you don't supply your own value. + the `Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International license `__. - + .. |Posix Build Status| image:: https://travis-ci.org/jfinkhaeuser/prance.svg?branch=master + :target: https://travis-ci.org/jfinkhaeuser/prance + .. |Windows Build Status| image:: https://ci.appveyor.com/api/projects/status/ic7lo8r95mkee7di/branch/master?svg=true + :target: https://ci.appveyor.com/project/jfinkhaeuser/prance + .. |Docs| image:: https://img.shields.io/badge/docs-passing-brightgreen.svg + :target: https://jfinkhaeuser.github.io/prance/ + .. |License| image:: https://img.shields.io/pypi/l/prance.svg + :target: https://pypi.python.org/pypi/prance/ + .. |PyPI| image:: https://img.shields.io/pypi/v/prance.svg + :target: https://pypi.python.org/pypi/prance/ + .. |Package Format| image:: https://img.shields.io/pypi/format/prance.svg + :target: https://pypi.python.org/pypi/prance/ + .. |Python Versions| image:: https://img.shields.io/pypi/pyversions/prance.svg + :target: https://pypi.python.org/pypi/prance/ + .. |Package Status| image:: https://img.shields.io/pypi/status/prance.svg + :target: https://pypi.python.org/pypi/prance/ + .. |FOSSA Status| image:: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fjfinkhaeuser%2Fprance.svg?type=shield + :target: https://app.fossa.io/projects/git%2Bgithub.com%2Fjfinkhaeuser%2Fprance?ref=badge_shield + .. |Liberapay| image:: http://img.shields.io/liberapay/receives/jfinkhaeuser.svg?logo=liberapay + :target: https://liberapay.com/jfinkhaeuser/donate + .. |Logo| image:: https://raw.githubusercontent.com/jfinkhaeuser/prance/master/docs/images/prance_logo_256.png - +swimlane/qswag: "{\"message\":\"API rate limit exceeded for 74.249.13.182. (But + here's the good news: Authenticated requests get a higher rate limit. Check + out the documentation for more details.) If you reach out to GitHub Support + for help, please include the request ID B483:A0544:3AFA9B:6EE334:67198DFA and + timestamp 2024-10-23 23:59:54 + UTC.\",\"documentation_url\":\"https://docs.github.com/rest/overview/rate-lim\ + its-for-the-rest-api\",\"status\":\"403\"}" +frankiesardo/pedestal-swagger: > + # route-swagger - - + [![Build status](https://circleci.com/gh/frankiesardo/route-swagger.svg?style=shield)](https://circleci.com/gh/frankiesardo/route-swagger) - - + Generate Swagger documentation from pedestal (or tripod) routes - - + - [Demo](https://pedestal-swagger.herokuapp.com) - + ## For old pedestal-swagger users - - + This project now focuses solely on route transformation and schema validation and thus is pedestal-agnostic. - - + Route-swagger is a much lower level library. Everything the old pedestal-swagger did is still possible (look at the example repo) but requires a bit more boilerplate. The major breaking difference is that now route-swagger uses ring specific keys for describing the schema rather than swagger ones, e.g. - + ```clj - + {:parameters {:body-params .. + :form-params .. + :query-params .. + :path-params .. + :headers ..} + :responses {500 {:body .. :headers ..}}} + ``` - - + Instead of `body`, `formData`, `query`, `schema`, etc. That should make it much more user friendly for clojure users. - - + For a nicer integration with pedestal, extra features and easier migration path from the old pedestal-swagger check out [pedestal-api](https://github.com/oliyh/pedestal-api). - + ## Download - - + [![Clojars Project](http://clojars.org/frankiesardo/route-swagger/latest-version.svg)](http://clojars.org/frankiesardo/route-swagger) - - + ## Usage - + Have a look at the project under the example folder for a working pedestal app - - + ## License - - + Copyright © 2015 Frankie Sardo - + Distributed under the Eclipse Public License either version 1.0 or (at - + your option) any later version. +gengo/grpc-gateway: > + # grpc-gateway - - + [![release](https://img.shields.io/github/release/grpc-ecosystem/grpc-gateway.svg?style=flat-square)](https://github.com/grpc-ecosystem/grpc-gateway/releases) [![CircleCI](https://img.shields.io/circleci/project/github/grpc-ecosystem/grpc-gateway/master.svg?style=flat-square)](https://circleci.com/gh/grpc-ecosystem/grpc-gateway) [![fuzzit](https://app.fuzzit.dev/badge?org_id=grpc-gateway)](https://app.fuzzit.dev/orgs/grpc-gateway/dashboard) [![coverage](https://img.shields.io/codecov/c/github/grpc-ecosystem/grpc-gateway/master.svg?style=flat-square)](https://codecov.io/gh/grpc-ecosystem/grpc-gateway) [![license](https://img.shields.io/github/license/grpc-ecosystem/grpc-gateway.svg?style=flat-square)](LICENSE.txt) - + The grpc-gateway is a plugin of the Google protocol buffers compiler - + [protoc](https://github.com/protocolbuffers/protobuf). - + It reads protobuf service definitions and generates a reverse-proxy server which - + 'translates a RESTful HTTP API into gRPC. This server is generated according to the - + [`google.api.http`](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto#L46) - + annotations in your service definitions. - + This helps you provide your APIs in both gRPC and RESTful style at the same time. - - + ![architecture introduction diagram](https://docs.google.com/drawings/d/12hp4CPqrNPFhattL_cIoJptFvlAqm5wLQ0ggqI5mkCg/pub?w=749&h=370) - - + ## Check out our [documentation](https://grpc-ecosystem.github.io/grpc-gateway/)! - + ## Background - + gRPC is great -- it generates API clients and server stubs in many programming - + languages, it is fast, easy-to-use, bandwidth-efficient and its design is - + combat-proven by Google. However, you might still want to provide a traditional - + RESTful JSON API as well. Reasons can range from maintaining + backwards-compatibility, supporting languages or clients not well supported by - + gRPC, to simply maintaining the aesthetics and tooling involved with a RESTful -
OptionDescriptionDefault
api_extension_typeThe extension, if necessary, used for your API - e.g. :json or :xml nil
api_file_pathThe output file path where generated swagger-docs files are written to. public/
base_pathThe URI base path for your API - e.g. api.somedomain.com/
base_api_controller / base_api_controllersThe base controller class your project uses; it or its subclasses will be where you call swagger_controller and swagger_api. An array of base controller classes may be provided.ActionController::Base
clean_directoryWhen generating swagger-docs files this option specifies if the api_file_path should be cleaned first. This means that all files will be deleted in the output directory first before any files are generated.false
formattingSpecifies which formatting method to apply to the JSON that is written. Available options: :none, :pretty:pretty
camelize_model_propertiesCamelizes property names of models. For example, a property name called first_name would be converted to firstName.true
parent_controllerAssign a different controller to use for the configuration
+ JSON architecture. + This project aims to provide that HTTP+JSON interface to your gRPC service. - ### Documenting a controller + A small amount of configuration in your service to attach HTTP semantics is all + that's needed to generate a reverse-proxy with this library. - ```ruby - class Api::V1::UsersController < ApplicationController + ## Installation - swagger_controller :users, "User Management" - swagger_api :index do - summary "Fetches all User items" - notes "This lists all the active users" - param :query, :page, :integer, :optional, "Page number" - param :path, :nested_id, :integer, :optional, "Team Id" - response :unauthorized - response :not_acceptable, "The request you made is not acceptable" - response :requested_range_not_satisfiable - end + The grpc-gateway requires a local installation of the Google protocol buffers - swagger_api :show do - summary "Fetches a single User item" - param :path, :id, :integer, :optional, "User Id" - response :ok, "Success", :User - response :unauthorized - response :not_acceptable - response :not_found - end + compiler `protoc` v3.0.0 or above. Please install this via your local package - swagger_api :create do - summary "Creates a new User" - param :form, :first_name, :string, :required, "First name" - param :form, :last_name, :string, :required, "Last name" - param :form, :email, :string, :required, "Email address" - param_list :form, :role, :string, :required, "Role", [ "admin", "superadmin", "user" ] - response :unauthorized - response :not_acceptable - end + manager or by downloading one of the releases from the official repository: - swagger_api :update do - summary "Updates an existing User" - param :path, :id, :integer, :required, "User Id" - param :form, :first_name, :string, :optional, "First name" - param :form, :last_name, :string, :optional, "Last name" - param :form, :email, :string, :optional, "Email address" - param :form, :tag, :Tag, :required, "Tag object" - response :unauthorized - response :not_found - response :not_acceptable - end - swagger_api :destroy do - summary "Deletes an existing User item" - param :path, :id, :integer, :optional, "User Id" - response :unauthorized - response :not_found - end + https://github.com/protocolbuffers/protobuf/releases - # Support for Swagger complex types: - # https://github.com/wordnik/swagger-core/wiki/Datatypes#wiki-complex-types - swagger_model :Tag do - description "A Tag object." - property :id, :integer, :required, "User Id" - property :name, :string, :optional, "Name" - property_list :type, :string, :optional, "Tag Type", ["info", "warning", "error"] - end - end - ``` + The following instructions assume you are using + [Go Modules](https://github.com/golang/go/wiki/Modules) for dependency - #### Support for Enums (PR #108) + management. Use a + [tool dependency](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module) - ``` + to track the versions of the following executable packages: - property_list :type, :string, :optional, "Type", ["info", "warning", "error"] - ``` + ```go + // +build tools - #### Custom resource paths`(PR #126) + package tools - ```ruby - class Api::V1::UsersController < ApplicationController + import ( + _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway" + _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger" + _ "github.com/golang/protobuf/protoc-gen-go" + ) - swagger_controller :users, "User Management", resource_path: "/some/where" ``` - ### DRYing up common documentation + Run `go mod tidy` to resolve the versions. Install by running - Suppose you have a header or a parameter that must be present on several controllers and methods. Instead of duplicating it on all the controllers you can do this on your API base controller: + ```sh + $ go install \ + github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway \ + github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger \ + github.com/golang/protobuf/protoc-gen-go + ``` - ```ruby - class Api::BaseController < ActionController::Base - class << self - Swagger::Docs::Generator::set_real_methods + This will place three binaries in your `$GOBIN`; - def inherited(subclass) - super - subclass.class_eval do - setup_basic_api_documentation - end - end - private - def setup_basic_api_documentation - [:index, :show, :create, :update, :delete].each do |api_action| - swagger_api api_action do - param :header, 'Authentication-Token', :string, :required, 'Authentication token' - end - end - end - end - end + * `protoc-gen-grpc-gateway` - ``` + * `protoc-gen-swagger` + * `protoc-gen-go` - And then use it as a superclass to all you API controllers. All the subclassed controllers will have the same documentation applied to them. + Make sure that your `$GOBIN` is in your `$PATH`. - #### Alternate method + ## Usage - Using a block for the swagger_api definition: + 1. Define your [gRPC](https://grpc.io/docs/) service using protocol buffers - ```ruby + `your_service.proto`: + ```protobuf + syntax = "proto3"; + package example; + message StringMessage { + string value = 1; + } - class Api::V1::UserController < Api::V1::BaseController + service YourService { + rpc Echo(StringMessage) returns (StringMessage) {} + } + ``` - swagger_controller :user, "Users" + 2. Add a [`google.api.http`](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto#L46) - def self.add_common_params(api) - api.param :form, "user[first_name]", :string, :optional, "Notes" - api.param :form, "user[last_name]", :string, :optional, "Name" - api.param :form, "user[email]", :string, :optional, "Email" - end + annotation to your .proto file - swagger_api :create do |api| - summary "Create a new User item" - Api::V1::UserController::add_common_params(api) - response :unauthorized - response :not_acceptable - response :unprocessable_entity - end - - swagger_api :update do |api| - summary "Update an existing User item" - Api::V1::UserController::add_common_params(api) - response :unauthorized - response :not_acceptable - response :unprocessable_entity - end - end + `your_service.proto`: + ```diff + syntax = "proto3"; + package example; + + + +import "google/api/annotations.proto"; + + + message StringMessage { + string value = 1; + } - ``` + service YourService { + - rpc Echo(StringMessage) returns (StringMessage) {} + + rpc Echo(StringMessage) returns (StringMessage) { + + option (google.api.http) = { + + post: "/v1/example/echo" + + body: "*" + + }; + + } + } + ``` + See [a_bit_of_everything.proto](examples/internal/proto/examplepb/a_bit_of_everything.proto) + for examples of more annotations you can add to customize gateway behavior + and generated Swagger output. - ### DSL Methods + If you do not want to modify the proto file for use with grpc-gateway you can + alternatively use an external + [gRPC Service Configuration](https://cloud.google.com/endpoints/docs/grpc/grpc-service-config) file. + [Check our documentation](https://grpc-ecosystem.github.io/grpc-gateway/docs/grpcapiconfiguration.html) + for more information. + 3. Generate gRPC stub - + The following generates gRPC code for Golang based on `path/to/your_service.proto`: + ```sh + protoc -I/usr/local/include -I. \ + -I$GOPATH/src \ + -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ + --go_out=plugins=grpc:. \ + path/to/your_service.proto + ``` - + It will generate a stub file `path/to/your_service.pb.go`. - + 4. Implement your service in gRPC as usual - + 1. (Optional) Generate gRPC stub in the [other programming languages](https://grpc.io/docs/). - + For example, the following generates gRPC code for Ruby based on `path/to/your_service.proto`: + ```sh + protoc -I/usr/local/include -I. \ + -I$GOPATH/src \ + -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ + --ruby_out=. \ + path/to/your_service.proto - + protoc -I/usr/local/include -I. \ + -I$GOPATH/src \ + -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ + --plugin=protoc-gen-grpc=grpc_ruby_plugin \ + --grpc-ruby_out=. \ + path/to/your_service.proto + ``` + 2. Add the googleapis-common-protos gem (or your language equivalent) as a dependency to your project. + 3. Implement your gRPC service stubs - + 5. Generate reverse-proxy using `protoc-gen-grpc-gateway` - + ```sh + protoc -I/usr/local/include -I. \ + -I$GOPATH/src \ + -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ + --grpc-gateway_out=logtostderr=true:. \ + path/to/your_service.proto + ``` + It will generate a reverse proxy `path/to/your_service.pb.gw.go`. - + 6. Write an entrypoint for the HTTP reverse-proxy server - + ```go + package main + + import ( + "context" // Use "golang.org/x/net/context" for Golang version <= 1.6 + "flag" + "net/http" + + "github.com/golang/glog" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "google.golang.org/grpc" + + gw "path/to/your_service_package" // Update + ) + + var ( + // command-line options: + // gRPC server endpoint + grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:9090", "gRPC server endpoint") + ) + + func run() error { + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + // Register gRPC server endpoint + // Note: Make sure the gRPC server is running properly and accessible + mux := runtime.NewServeMux() + opts := []grpc.DialOption{grpc.WithInsecure()} + err := gw.RegisterYourServiceHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts) + if err != nil { + return err + } + + // Start HTTP server (and proxy calls to gRPC server endpoint) + return http.ListenAndServe(":8081", mux) + } + + func main() { + flag.Parse() + defer glog.Flush() + + if err := run(); err != nil { + glog.Fatal(err) + } + } + ``` - + 7. (Optional) Generate swagger definitions using `protoc-gen-swagger` - + ```sh + protoc -I/usr/local/include -I. \ + -I$GOPATH/src \ + -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ + --swagger_out=logtostderr=true:. \ + path/to/your_service.proto + ``` + ## Video intro - - + This GopherCon UK 2019 presentation from our maintainer - + [@JohanBrandhorst](https://github.com/johanbrandhorst) provides a good intro to - + using the grpc-gateway. It uses the following boilerplate repo as a base: + https://github.com/johanbrandhorst/grpc-gateway-boilerplate. - - + [![gRPC-Gateway presentation](https://img.youtube.com/vi/Pq1paKC-fXk/0.jpg)](https://www.youtube.com/watch?v=Pq1paKC-fXk) - - + ## Parameters and flags - + During code generation with `protoc`, flags to grpc-gateway tools must be passed - + through protoc using the `--_out=:` pattern, for - + example: - + ```sh - + --grpc-gateway_out=logtostderr=true,repeated_path_param_separator=ssv:. - + --swagger_out=logtostderr=true,repeated_path_param_separator=ssv:. - + ``` - + `protoc-gen-grpc-gateway` supports custom mapping from Protobuf `import` to - + Golang import paths. They are compatible to -
MethodDescription
summaryThe summary of the API
notes (optional)The associated notes for the API
paramStandard API Parameter
param_listStandard API Enum/List parameter.
responseTakes a symbol or status code and passes it to `Rack::Utils.status_code`. The current list of status codes can be seen here: https://github.com/rack/rack/blob/master/lib/rack/utils.rb. An optional message can be added.
+ [the parameters with same names in `protoc-gen-go`](https://github.com/golang/protobuf#parameters) + (except `source_relative`). - ### Run rake task to generate docs + In addition we also support the `request_context` parameter in order to use the - ``` + `http.Request`'s Context (only for Go 1.7 and above). This parameter can be - rake swagger:docs + useful to pass request scoped context between the gateway and the gRPC service. - ``` + `protoc-gen-grpc-gateway` also supports some more command line flags to control - Swagger-ui JSON files should now be present in your api_file_path (e.g. ./public/api/v1) + logging. You can give these flags together with parameters above. Run + `protoc-gen-grpc-gateway --help` for more details about the flags. - #### Additional logging for generation failures + Similarly, `protoc-gen-swagger` supports command-line flags to control Swagger - Errors aren't displayed by default. To see all error messages use the ```SD_LOG_LEVEL``` environment variable when running the rake task: + output (for example, `json_names_for_fields` to output JSON names for fields + instead of protobuf names). Run `protoc-gen-swagger --help` for more flag - ``` + details. Further Swagger customization is possible by annotating your `.proto` - SD_LOG_LEVEL=1 rake swagger:docs + files with options from - ``` + [openapiv2.proto](protoc-gen-swagger/options/openapiv2.proto) - see + [a_bit_of_everything.proto](examples/internal/proto/examplepb/a_bit_of_everything.proto) - Currently only constantize errors are shown. + for examples. - Errors are written to ```$stderr```. Error logging methods can be found in ```Config``` and can be overridden for custom behaviour. + ## More Examples + More examples are available under `examples` directory. - Thanks to **[@tomtt](https://github.com/tomtt/)** who originally suggested this idea in #81 + * `proto/examplepb/echo_service.proto`, `proto/examplepb/a_bit_of_everything.proto`, `proto/examplepb/unannotated_echo_service.proto`: service definition + * `proto/examplepb/echo_service.pb.go`, `proto/examplepb/a_bit_of_everything.pb.go`, `proto/examplepb/unannotated_echo_service.pb.go`: [generated] stub of the service + * `proto/examplepb/echo_service.pb.gw.go`, `proto/examplepb/a_bit_of_everything.pb.gw.go`, `proto/examplepb/uannotated_echo_service.pb.gw.go`: [generated] reverse proxy for the service + * `proto/examplepb/unannotated_echo_service.yaml`: gRPC API Configuration for ```unannotated_echo_service.proto``` + * `server/main.go`: service implementation + * `main.go`: entrypoint of the generated reverse proxy - ### Sample + To use the same port for custom HTTP handlers (e.g. serving `swagger.json`), - A sample Rails application where you can run the above rake command and view the output in swagger-ui can be found here: + gRPC-gateway, and a gRPC server, see + [this example by CoreOS](https://github.com/philips/grpc-gateway-example/blob/master/cmd/serve.go) - https://github.com/richhollis/swagger-docs-sample + (and its accompanying [blog post](https://coreos.com/blog/grpc-protobufs-swagger.html)). - ![Screen shot 1](https://github.com/richhollis/swagger-docs-sample/raw/master/swagger-docs-screenshot-2.png) + ## Features + ### Supported - ### Advanced Customization + * Generating JSON API handlers. - #### Inheriting from a custom Api controller + * Method parameters in request body. + * Method parameters in request path. - By default swagger-docs is applied to controllers inheriting from ApplicationController. + * Method parameters in query string. - If this is not the case for your application, use this snippet in your initializer + * Enum fields in path parameter (including repeated enum fields). - _before_ calling Swagger::Docs::Config#register_apis(...). + * Mapping streaming APIs to newline-delimited JSON streams. + * Mapping HTTP headers with `Grpc-Metadata-` prefix to gRPC metadata (prefixed with `grpcgateway-`) - ```ruby + * Optionally emitting API definitions for - class Swagger::Docs::Config - def self.base_api_controller; Api::ApiController end - end + [OpenAPI (Swagger) v2](https://swagger.io/docs/specification/2-0/basic-structure/). - ``` + * Setting [gRPC timeouts](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests) + through inbound HTTP `Grpc-Timeout` header. - #### Custom route discovery for supporting Rails Engines + * Partial support for [gRPC API Configuration](https://cloud.google.com/endpoints/docs/grpc/grpc-service-config) + files as an alternative to annotation. - By default, swagger-docs finds controllers by traversing routes in `Rails.application`. + * Automatically translating PATCH requests into Field Mask gRPC requests. See - To override this, you can customize the `base_application` config in an initializer: + [the docs](https://grpc-ecosystem.github.io/grpc-gateway/docs/patch.html) + for more information. - ```ruby - class Swagger::Docs::Config - def self.base_application; Api::Engine end - end + ### No plan to support - ``` + But patch is welcome. + * Method parameters in HTTP headers. - If you want swagger to find controllers in `Rails.application` and/or multiple + * Handling trailer metadata. - engines you can override `base_application` to return an array. + * Encoding request/response body in XML. + * True bi-directional streaming. - ```ruby - class Swagger::Docs::Config - def self.base_application; [Rails.application, Api::Engine, SomeOther::Engine] end - end + # Mapping gRPC to HTTP - ``` + * [How gRPC error codes map to HTTP status codes in the response](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/runtime/errors.go#L15). - Or, if you prefer you can override `base_applications` for this purpose. The plural + * HTTP request source IP is added as `X-Forwarded-For` gRPC request header. - `base_applications` takes precedence over `base_application` and MUST return an + * HTTP request host is added as `X-Forwarded-Host` gRPC request header. - array. + * HTTP `Authorization` header is added as `authorization` gRPC request header. + * Remaining Permanent HTTP header keys (as specified by the IANA - ```ruby + [here](http://www.iana.org/assignments/message-headers/message-headers.xhtml) - class Swagger::Docs::Config - def self.base_applications; [Rails.application, Api::Engine, SomeOther::Engine] end - end + are prefixed with `grpcgateway-` and added with their values to gRPC request - ``` + header. + * HTTP headers that start with 'Grpc-Metadata-' are mapped to gRPC metadata - #### Transforming the `path` variable + (prefixed with `grpcgateway-`). + * While configurable, the default {un,}marshaling uses - Swagger allows a distinction between the API documentation server and the hosted API + [jsonpb](https://godoc.org/github.com/golang/protobuf/jsonpb) with - server through the `path` variable (see [Swagger: No server Integrations](https://github.com/wordnik/swagger-core/wiki/No-server-Integrations)). To override the default swagger-docs behavior, you can provide a `transform_path` + `OrigName: true`. - class method in your initializer: + # Contribution - ```ruby + See [CONTRIBUTING.md](http://github.com/grpc-ecosystem/grpc-gateway/blob/master/CONTRIBUTING.md). - class Swagger::Docs::Config - def self.transform_path(path, api_version) - "http://example.com/api-docs/#{api_version}/#{path}" - end - end - ``` + # License + grpc-gateway is licensed under the BSD 3-Clause License. - The transformation will be applied to all API `path` values in the generated `api-docs.json` file. + See [LICENSE.txt](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt) for more details. +BigstickCarpet/swagger-express-middleware: > + Swagger Express Middleware + ============================ - #### Precompile + ### Swagger 2.0 middleware and mocks for Express.js - It is best-practice *not* to keep documentation in version control. An easy way + [![Cross-Platform Compatibility](https://apitools.dev/img/badges/os-badges.svg)](https://github.com/APIDevTools/swagger-express-middleware/blob/master/.github/workflows/CI-CD.yaml) - to integrate swagger-docs into a conventional deployment setup (e.g. capistrano, + [![Build Status](https://github.com/APIDevTools/swagger-express-middleware/workflows/CI-CD/badge.svg?branch=master)](https://github.com/APIDevTools/swagger-express-middleware/blob/master/.github/workflows/CI-CD.yaml) - chef, or opsworks) is to piggyback on the 'assets:precompile' rake task. And don't forget - to add your api documentation directory to .gitignore in this case. + [![Coverage Status](https://coveralls.io/repos/github/APIDevTools/swagger-express-middleware/badge.svg?branch=master)](https://coveralls.io/github/APIDevTools/swagger-express-middleware) + [![Tested on APIs.guru](https://api.apis.guru/badges/tested_on.svg)](https://apis.guru/browse-apis/) - ```ruby + [![Dependencies](https://david-dm.org/APIDevTools/swagger-express-middleware.svg)](https://david-dm.org/APIDevTools/swagger-express-middleware) - #Rakefile or lib/task/precompile_overrides.rake - namespace :assets do - task :precompile do - Rake::Task['assets:precompile'].invoke - Rake::Task['swagger:docs'].invoke - end - end + [![npm](https://img.shields.io/npm/v/@apidevtools/swagger-express-middleware.svg)](https://www.npmjs.com/package/@apidevtools/swagger-express-middleware) - ``` + [![License](https://img.shields.io/npm/l/@apidevtools/swagger-express-middleware.svg)](LICENSE) + [![Buy us a tree](https://img.shields.io/badge/Treeware-%F0%9F%8C%B3-lightgreen)](https://plant.treeware.earth/APIDevTools/swagger-express-middleware) - ### Output files - api-docs.json output: + Features + -------------------------- - ```json + - **Supports Swagger 2.0 specs in JSON or YAML**
- { - "apiVersion": "1.0", - "swaggerVersion": "1.2", - "basePath": "/api/v1", - "apis": [ - { - "path": "/users.{format}", - "description": "User Management" - } - ] - } + Swagger Express Middleware uses [Swagger-Parser](https://github.com/APIDevTools/swagger-parser) to parse, validate, and dereference Swagger files. You can even split your spec into multiple different files using `$ref` pointers. - ``` + - **Thoroughly tested**
- users.json output: + Over 1,000 unit tests and integration tests with 100% code coverage. Tested on [**over 1,000 real-world APIs**](https://apis.guru/browse-apis/) from Google, Instagram, Spotify, etc. All tests are run on Mac, Linux, and Windows using all LTS versions of Node. - ```json + - [**Mock middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/mock.html)
- { - "apiVersion": "1.0", - "swaggerVersion": "1.2", - "basePath": "http://api.somedomain.com/api/v1/", - "resourcePath": "/users", - "apis": [ - { - "path": "/users", - "operations": [ - { - "summary": "Fetches all User items", - "parameters": [ - { - "paramType": "query", - "name": "page", - "type": "integer", - "description": "Page number", - "required": false - } - ], - "responseMessages": [ - { - "code": 401, - "message": "Unauthorized" - }, - { - "code": 406, - "message": "The request you made is not acceptable" - }, - { - "code": 416, - "message": "Requested Range Not Satisfiable" - } - ], - "method": "get", - "nickname": "Api::V1::Users#index" - } - ] - }, - { - "path": "nested/{nested_id}/sample", - "operations": [ - { - "summary": "Fetches all User items", - "parameters": [ - { - "paramType": "query", - "name": "page", - "type": "integer", - "description": "Page number", - "required": false - }, - { - "paramType": "path", - "name": "nested_id", - "type": "integer", - "description": "Team Id", - "required": false - } - ], - "responseMessages": [ - { - "code": 401, - "message": "Unauthorized" - }, - { - "code": 406, - "message": "The request you made is not acceptable" - }, - { - "code": 416, - "message": "Requested Range Not Satisfiable" - } - ], - "method": "get", - "nickname": "Api::V1::Users#index" - } - ] - }, - { - "path": "/users", - "operations": [ - { - "summary": "Creates a new User", - "parameters": [ - { - "paramType": "form", - "name": "first_name", - "type": "string", - "description": "First name", - "required": true - }, - { - "paramType": "form", - "name": "last_name", - "type": "string", - "description": "Last name", - "required": true - }, - { - "paramType": "form", - "name": "email", - "type": "string", - "description": "Email address", - "required": true - } - ], - "responseMessages": [ - { - "code": 401, - "message": "Unauthorized" - }, - { - "code": 406, - "message": "Not Acceptable" - } - ], - "method": "post", - "nickname": "Api::V1::Users#create" - } - ] - }, - { - "path": "/users/{id}", - "operations": [ - { - "summary": "Fetches a single User item", - "parameters": [ - { - "paramType": "path", - "name": "id", - "type": "integer", - "description": "User Id", - "required": false - } - ], - "responseMessages": [ - { - "code": 401, - "message": "Unauthorized" - }, - { - "code": 404, - "message": "Not Found" - }, - { - "code": 406, - "message": "Not Acceptable" - } - ], - "method": "get", - "nickname": "Api::V1::Users#show" - } - ] - }, - { - "path": "/users/{id}", - "operations": [ - { - "summary": "Updates an existing User", - "parameters": [ - { - "paramType": "path", - "name": "id", - "type": "integer", - "description": "User Id", - "required": true - }, - { - "paramType": "form", - "name": "first_name", - "type": "string", - "description": "First name", - "required": false - }, - { - "paramType": "form", - "name": "last_name", - "type": "string", - "description": "Last name", - "required": false - }, - { - "paramType": "form", - "name": "email", - "type": "string", - "description": "Email address", - "required": false - }, - { - "paramType": "form", - "name": "tag", - "type": "Tag", - "description": "Tag object", - "required": true - } - ], - "responseMessages": [ - { - "code": 401, - "message": "Unauthorized" - }, - { - "code": 404, - "message": "Not Found" - }, - { - "code": 406, - "message": "Not Acceptable" - } - ], - "method": "put", - "nickname": "Api::V1::Users#update" - } - ] - }, - { - "path": "/users/{id}", - "operations": [ - { - "summary": "Deletes an existing User item", - "parameters": [ - { - "paramType": "path", - "name": "id", - "type": "integer", - "description": "User Id", - "required": false - } - ], - "responseMessages": [ - { - "code": 401, - "message": "Unauthorized" - }, - { - "code": 404, - "message": "Not Found" - } - ], - "method": "delete", - "nickname": "Api::V1::Users#destroy" - } - ] - } - ], - "models": { - "Tag": { - "id": "Tag", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "integer", - "description": "User Id" - }, - "name": { - "type": "string", - "description": "Name", - "foo": "test" - } - }, - "description": "A Tag object." - } - } - } + **Fully-functional mock** implementations for every operation in your API, including data persistence, all with **zero code!** This is a great way to test-drive your API as you write it, or for quick demos and POCs. You can even extend the mock middleware with your own logic and data to fill in any gaps. - ``` + - [**Metadata middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/metadata.html)
- ## Thanks to our contributors + Annotates each request with all the relevant information from the Swagger definition. The path, the operation, the parameters, the security requirements - they're all easily accessible at `req.swagger`. - Thanks to jdar, fotinakis, stevschmid, ldnunes, aaronrenner and all of our contributors for making swagger-docs even better. + - [**Parse Request middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/parseRequest.html)
+ Parses incoming requests and converts everything into the correct data types, according to your Swagger API definition. - ## Related Projects + - [**Validate Request middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/validateRequest.html)
- **[@fotinakis](https://github.com/fotinakis/)** has created Swagger::Blocks - a DSL for pure Ruby code blocks: [swagger-blocks](https://github.com/fotinakis/swagger-blocks/) + Ensures that every request complies with your Swagger API definition, or returns the appropriate HTTP error codes if needed. Of course, you can catch any validation errors and handle them however you want. - A [cors rack middleware for testing swagger apis](https://gist.github.com/richhollis/b98a8b0599860145ad86) designed to be used in Rails development environments. + - [**CORS middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/CORS.html)
+ Adds the appropriate CORS headers to each request and automatically responds to CORS preflight requests, all in compliance with your Swagger API definition. - ## More About Me + - [**Files middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/files.html)
+ Serves the Swagger API file(s) in JSON or YAML format so they can be used with front-end tools like [Swagger UI](http://www.swagger.io), [Swagger Editor](http://editor.swagger.io), and [Postman](http://getpostman.com). - [Rich Hollis](http://richhollis.co.uk) - ## Contributing + Installation and Use - When raising a Pull Request please ensure that you have provided good test coverage for the request you are making. + -------------------------- + Install using [npm](https://docs.npmjs.com/about-npm/). - 1. Fork it - 2. Create your feature branch (`git checkout -b my-new-feature`) + ```bash - 3. Commit your changes (`git commit -am 'Add some feature'`) + npm install @apidevtools/swagger-express-middleware - 4. Push to the branch (`git push origin my-new-feature`) + ``` - 5. Create new Pull Request -EiffelWebFramework/swagger: | - Swagger - ======= + Then use it in your [Node.js](http://nodejs.org/) script like this: - This is a Swagger protocol implementation in Eiffel. - Note: This is a work in progress, and the API could change in a future. + ```javascript - ## Authors + const express = require('express'); - + [@oligot](https://github.com/oligot) - + [@weilers](https://github.com/weilers) - + B. Marchal -SmartBear/swagger4j: > - ## swagger4j + const createMiddleware = require('@apidevtools/swagger-express-middleware'); - A simple java library for reading and writing [Swagger 1.X definitions](https://swagger.io). Supports both JSON and XML formats. The current version is + let app = express(); - reasonably in line with the latest swagger core release except that it doesn't support any of the JSON Schema/Data Model constructs yet. Apache 2.0 licensed. + createMiddleware('PetStore.yaml', app, function(err, middleware) { + // Add all the Swagger Express Middleware, or just the ones you need. + // NOTE: Some of these accept optional options (omitted here for brevity) + app.use( + middleware.metadata(), + middleware.CORS(), + middleware.files(), + middleware.parseRequest(), + middleware.validateRequest(), + middleware.mock() + ); - If you're interested in reading Swagger 2.0 definitions you're better off using the official [swagger-parser](https://github.com/swagger-api/swagger-parser) + app.listen(8000, function() { + console.log('The PetStore sample is now running at http://localhost:8000'); + }); + }); + ``` - ### Getting started - Clone this repo from GitHub and build it yourself with maven (with "mvn install"). + Samples & Walkthroughs - The latest version is also available in the SmartBear maven repository at soapui.org, add this to your pom with + -------------------------- + Swagger Express Middleware comes two samples that use the [Swagger Pet Store API](https://github.com/APIDevTools/swagger-express-middleware/blob/master/samples/PetStore.yaml). - ```xml - - - soapUI Repository - http://www.soapui.org/repository/maven2 - - + #### Sample 1 - ``` + This sample demonstrates the most simplistic usage of Swagger Express Middleware. It simply creates a new Express Application and adds all of the Swagger middleware without changing any options, and without adding any custom middleware. - and add the corresponding dependency: + * [Source Code](https://github.com/APIDevTools/swagger-express-middleware/blob/master/samples/sample1.js) + * [Walkthrough](https://apitools.dev/swagger-express-middleware/docs/walkthroughs/running.html) - ```xml - - com.smartbear - swagger4j - 1.0.0 - - ``` + #### Sample 2 + This sample demonstrates a few more advanced features of Swagger Express Middleware, such as setting a few options, initializing the mock data store, and adding custom middleware logic. - swagger4j has a runtime dependency - on jsonp ([https://java.net/projects/jsonp/](https://java.net/projects/jsonp/)) which you can add to your maven pom with. + * [Source Code](https://github.com/APIDevTools/swagger-express-middleware/blob/master/samples/sample2.js) + * [Walkthrough](https://apitools.dev/swagger-express-middleware/docs/walkthroughs/walkthrough2.html) - ```xml - - org.glassfish - javax.json - 1.0-b06 - - - ``` - - - Once added to your classpath you can start reading swagger definitions, for example - - - ```java - - ResourceListing resourceListing = Swagger.readSwagger( "http://petstore.swagger.wordnik.com/api/api-docs.json" ) - - for( ResourceListingApi apiRef : resourceListing.getApis() ) - - { - ApiDeclaration apiDeclaration = apiRef.getDeclaration(); - for( Api api : apiDeclaration.getApis()) - { - ... - } - } - - ``` - - - and of course you can write them as well - - - ```java - - SwaggerFactory factory = Swagger.createSwaggerFactory(); - - - ApiDeclaration apiDeclaration = factory.createApiDeclaration( "http://api.mycompany.com/apis", "/user" ); - - Api api = apiDeclaration.addApi( "{id}" ); - - Operation op = api.addOperation( "getuserbyid", Operation.Method.GET ); - - op.addParameter( "id", Parameter.ParamType.path ); - - - ResourceListing rl = factory.createResourceListing( "http://api.mycompany.com/apis" ); - - rl.setApiVersion( "1.0" ); - - rl.addApi( apiDeclaration, "user-doc.{format}" ); - - - Swagger.writerSwagger( rl, "api-docs" ); - - ``` - The API is closely modeled after the Swagger specification, if you are familiar with that it should be a breeze to use. - - If you aren't familiar with Swagger and its spec head right over to the swagger website at + Contributing - [https://github.com/wordnik/swagger-core/wiki](https://github.com/wordnik/swagger-core/wiki) to learn all about it. + -------------------------- + I welcome any contributions, enhancements, and bug-fixes. [File an issue](https://github.com/APIDevTools/swagger-express-middleware/issues) on GitHub and [submit a pull request](https://github.com/APIDevTools/swagger-express-middleware/pulls). - Javadoc is available in the zip at sourceforge. + #### Building/Testing - ### Library Design + To build/test the project locally on your computer: - Swagger4j uses a standard Factory/Builder approach with interfaces defining the entire Swagger object model and a + 1. **Clone this repo**
- default implementation implementing them. If you have any suggestions on how to improve the actual API please don't + `git clone https://github.com/APIDevTools/swagger-express-middleware.git` - hesitate to get in touch by adding tickets here at GitHub for bugs, issues, feature requests - Thank you! + 2. **Install dependencies**
- Please note the following: + `npm install` - - the whole DataModel/DataType part of Swagger is not yet supported - - paths to APIs referred to in a ResourceListing are resolved by adding the path of the api to the basePath defined + 3. **Run the tests**
- in the resourceListing. If the basePath is relative - it is resolved relatively to the host/root of the ResourceListing + `npm test` - URI. + 4. **Run the sample app**
- ### Usages + `npm start` - * Version 0.2+ of the SoapUI-Swagger-Plugin use swagger4j to parse and generate Swagger definitions. - ### Future improvements + License + -------------------------- - * None planned at this point! + Swagger Express Middleware is 100% free and open-source, under the [MIT license](LICENSE). Use it however you want. - ### Release History + This package is [Treeware](http://treeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https://plant.treeware.earth/APIDevTools/swagger-express-middleware) to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats. - * 20130527 - Initial beta1 release - * 20131119 - beta2 release, adds support for Swagger 1.2 and 1.0 - * 20140505 - beta3 bugfixes + Big Thanks To - * 20140512 - beta4 more bugfixes + -------------------------- - * 20151029 - 1.0.0 release - more bugfixes -ROAMSYS/swaggerapi: > - # Swagger Java Client + Thanks to these awesome companies for their support of Open Source developers ❤ - * [Configuration](#configuration) + [![Travis CI](https://jstools.dev/img/badges/travis-ci.svg)](https://travis-ci.com) - * [Register the Swagger API components](#register-the-swagger-api-components) - * [Start Up listener](#start-up-listener) - * [Servlet for API calls](#servlet-for-api-calls) - * [Example API declaration](#example-api-declaration) - * [API class annotation](#api-class-annotation) - * [API method annotations](#api-method-annotations) - * [Method parameters](#method-parameters) - * [License](#license) + [![SauceLabs](https://jstools.dev/img/badges/sauce-labs.svg)](https://saucelabs.com) + [![Coveralls](https://jstools.dev/img/badges/coveralls.svg)](https://coveralls.io) +RobWin/swagger2markup-gradle-plugin: > + = Swagger2Markup Gradle Plugin - ## Configuration + :author: Robert Winkler + :hardbreaks: - Create a class that extends the **SwaggerAPIListener** class. Here you can do all your configuration using the instance of SwaggerAPIConfig. Use the **registerModel** method to add your API services. - ````java + image:https://travis-ci.org/Swagger2Markup/swagger2markup-gradle-plugin.svg?branch=master["Build Status", link="https://travis-ci.org/Swagger2Markup/swagger2markup-gradle-plugin"] image:https://coveralls.io/repos/Swagger2Markup/swagger2markup-gradle-plugin/badge.svg["Coverage Status", link="https://coveralls.io/r/Swagger2Markup/swagger2markup-gradle-plugin"] image:https://api.bintray.com/packages/swagger2markup/Maven/swagger2markup-gradle-plugin/images/download.svg[link="https://bintray.com/swagger2markup/Maven/swagger2markup-gradle-plugin/_latestVersion"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"] image:https://img.shields.io/badge/Twitter-rbrtwnklr-blue.svg["Twitter", link="https://twitter.com/rbrtwnklr"] image:https://badges.gitter.im/Join%20Chat.svg[link="https://gitter.im/Swagger2Markup/swagger2markup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"] - public class SwaggerListener extends SwaggerAPIListener { - - @Override - public void initialize(final SwaggerAPIConfig config) { - config.allowCrossOriginAccess(); - config.setAPIVersion("0.1.0"); - config.setBasePath("http://example.roamsys.lan:8080/api/"); - config.setSwaggerVersion("1.1"); - config.setDefaultContentType(SwaggerAPIConfig.CONTENT_TYPE_JSON_UTF8); - config.registerModel(new TestModel()); - } - } - ```` + == Reference documentation - ## Register the Swagger API components + The documentation can be found at https://github.com/Swagger2Markup/swagger2markup#reference-documentation[Reference documentation] - ### Start Up listener - Register the start up listener class you've created in your **web.xml**. This will initiate the Swagger API services at the start up of your application. + == License - ````xml - - ... - - ... - com.roamsys.example.gwt.server.swagger.SwaggerListener - - + Copyright 2015 Robert Winkler - ```` + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - ### Servlet for API calls + http://www.apache.org/licenses/LICENSE-2.0 - Edit your **web.xml** and add the Swagger API servlet. Thats all. + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +raphael/goa: "{\"message\":\"API rate limit exceeded for 74.249.13.182. (But + here's the good news: Authenticated requests get a higher rate limit. Check + out the documentation for more details.) If you reach out to GitHub Support + for help, please include the request ID B4D9:1DF100:350F17:63B45C:67198DF1 and + timestamp 2024-10-23 23:59:45 + UTC.\",\"documentation_url\":\"https://docs.github.com/rest/overview/rate-lim\ + its-for-the-rest-api\",\"status\":\"403\"}" +BigstickCarpet/swagger-parser#swagger-parser: '{"id":25453221,"node_id":"MDEwOlJlcG9zaXRvcnkyNTQ1MzIyMQ==","name":"swagger-parser","full_name":"APIDevTools/swagger-parser","private":false,"owner":{"login":"APIDevTools","id":43750074,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQzNzUwMDc0","avatar_url":"https://avatars0.githubusercontent.com/u/43750074?v=4","gravatar_id":"","url":"https://api.github.com/users/APIDevTools","html_url":"https://github.com/APIDevTools","followers_url":"https://api.github.com/users/APIDevTools/followers","following_url":"https://api.github.com/users/APIDevTools/following{/other_user}","gists_url":"https://api.github.com/users/APIDevTools/gists{/gist_id}","starred_url":"https://api.github.com/users/APIDevTools/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/APIDevTools/subscriptions","organizations_url":"https://api.github.com/users/APIDevTools/orgs","repos_url":"https://api.github.com/users/APIDevTools/repos","events_url":"https://api.github.com/users/APIDevTools/events{/privacy}","received_events_url":"https://api.github.com/users/APIDevTools/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/APIDevTools/swagger-parser","description":"Swagger + 2.0 and OpenAPI 3.0 + parser/validator","fork":false,"url":"https://api.github.com/repos/APIDevTools/swagger-parser","forks_url":"https://api.github.com/repos/APIDevTools/swagger-parser/forks","keys_url":"https://api.github.com/repos/APIDevTools/swagger-parser/keys{/key_id}","collaborators_url":"https://api.github.com/repos/APIDevTools/swagger-parser/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/APIDevTools/swagger-parser/teams","hooks_url":"https://api.github.com/repos/APIDevTools/swagger-parser/hooks","issue_events_url":"https://api.github.com/repos/APIDevTools/swagger-parser/issues/events{/number}","events_url":"https://api.github.com/repos/APIDevTools/swagger-parser/events","assignees_url":"https://api.github.com/repos/APIDevTools/swagger-parser/assignees{/user}","branches_url":"https://api.github.com/repos/APIDevTools/swagger-parser/branches{/branch}","tags_url":"https://api.github.com/repos/APIDevTools/swagger-parser/tags","blobs_url":"https://api.github.com/repos/APIDevTools/swagger-parser/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/APIDevTools/swagger-parser/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/APIDevTools/swagger-parser/git/refs{/sha}","trees_url":"https://api.github.com/repos/APIDevTools/swagger-parser/git/trees{/sha}","statuses_url":"https://api.github.com/repos/APIDevTools/swagger-parser/statuses/{sha}","languages_url":"https://api.github.com/repos/APIDevTools/swagger-parser/languages","stargazers_url":"https://api.github.com/repos/APIDevTools/swagger-parser/stargazers","contributors_url":"https://api.github.com/repos/APIDevTools/swagger-parser/contributors","subscribers_url":"https://api.github.com/repos/APIDevTools/swagger-parser/subscribers","subscription_url":"https://api.github.com/repos/APIDevTools/swagger-parser/subscription","commits_url":"https://api.github.com/repos/APIDevTools/swagger-parser/commits{/sha}","git_commits_url":"https://api.github.com/repos/APIDevTools/swagger-parser/git/commits{/sha}","comments_url":"https://api.github.com/repos/APIDevTools/swagger-parser/comments{/number}","issue_comment_url":"https://api.github.com/repos/APIDevTools/swagger-parser/issues/comments{/number}","contents_url":"https://api.github.com/repos/APIDevTools/swagger-parser/contents/{+path}","compare_url":"https://api.github.com/repos/APIDevTools/swagger-parser/compare/{base}...{head}","merges_url":"https://api.github.com/repos/APIDevTools/swagger-parser/merges","archive_url":"https://api.github.com/repos/APIDevTools/swagger-parser/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/APIDevTools/swagger-parser/downloads","issues_url":"https://api.github.com/repos/APIDevTools/swagger-parser/issues{/number}","pulls_url":"https://api.github.com/repos/APIDevTools/swagger-parser/pulls{/number}","milestones_url":"https://api.github.com/repos/APIDevTools/swagger-parser/milestones{/number}","notifications_url":"https://api.github.com/repos/APIDevTools/swagger-parser/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/APIDevTools/swagger-parser/labels{/name}","releases_url":"https://api.github.com/repos/APIDevTools/swagger-parser/releases{/id}","deployments_url":"https://api.github.com/repos/APIDevTools/swagger-parser/deployments","created_at":"2014-10-20T06:14:51Z","updated_at":"2020-04-06T17:57:45Z","pushed_at":"2020-04-01T13:01:11Z","git_url":"git://github.com/APIDevTools/swagger-parser.git","ssh_url":"git@github.com:APIDevTools/swagger-parser.git","clone_url":"https://github.com/APIDevTools/swagger-parser.git","svn_url":"https://github.com/APIDevTools/swagger-parser","homepage":"https://apitools.dev/swagger-parser","size":32415,"stargazers_count":584,"watchers_count":584,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":93,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":41,"license":{"key":"mit","name":"MIT + License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":93,"open_issues":41,"watchers":584,"default_branch":"master","permissions":{"admin":false,"push":false,"pull":true},"temp_clone_token":"","organization":{"login":"APIDevTools","id":43750074,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQzNzUwMDc0","avatar_url":"https://avatars0.githubusercontent.com/u/43750074?v=4","gravatar_id":"","url":"https://api.github.com/users/APIDevTools","html_url":"https://github.com/APIDevTools","followers_url":"https://api.github.com/users/APIDevTools/followers","following_url":"https://api.github.com/users/APIDevTools/following{/other_user}","gists_url":"https://api.github.com/users/APIDevTools/gists{/gist_id}","starred_url":"https://api.github.com/users/APIDevTools/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/APIDevTools/subscriptions","organizations_url":"https://api.github.com/users/APIDevTools/orgs","repos_url":"https://api.github.com/users/APIDevTools/repos","events_url":"https://api.github.com/users/APIDevTools/events{/privacy}","received_events_url":"https://api.github.com/users/APIDevTools/received_events","type":"Organization","site_admin":false},"network_count":93,"subscribers_count":17}' +kogosoftwarellc/express-openapi: > + # @open-api [![Build + Status][travis-image]][travis-url] [![Coveralls + Status][coveralls-image]][coveralls-url] [![Gitter + chat][gitter-image]][gitter-url] [![Greenkeeper + badge](https://badges.greenkeeper.io/kogosoftwarellc/open-api.svg)](https://greenkeeper.io/) - ````xml + > A Monorepo of various packages to power OpenAPI in node. - - ... - - SwaggerAPI - com.roamsys.swagger.SwaggerAPIServlet - - - SwaggerAPI - /api/* - - - ```` + ## Quick Start Express - ## Example API declaration + * See [express-openapi](https://github.com/kogosoftwarellc/open-api/tree/master/packages/express-openapi)   [![express-openapi Downloads][express-openapi-downloads-image]][express-openapi-npm-url] - ````java - @SwaggerModel (path = "/metadata") + ## Quick Start Koa - public class MetadataAPI implements SwaggerAPIModel { + * See [koa-openapi](https://github.com/kogosoftwarellc/open-api/tree/master/packages/koa-openapi)   [![koa-openapi Downloads][koa-openapi-downloads-image]][koa-openapi-npm-url] - @SwaggerApi ( - notes = "Returns a list of all documents", - method = HTTPMethod.GET, - path = "/all", - summary = "Get document list") - public void all(final SwaggerAPIContext context) throws IOException { - context.getResponse().getWriter().println("[ { \"name\" : \"document 1\", \"hash\" : \"abc\"}, { \"name\": \"another document\", \"hash\" : \"rrr\"} ]"); - } - @SwaggerApi ( - notes = "Returns detailed information a specific document", - method = HTTPMethod.GET, - path = "/details/{hash}", - summary = "Get document details") - public void allForTypeAndFormat(final SwaggerAPIContext context, - @SwaggerParameter ( - name = "hash", - description = "The document hash", - required = true, - paramType = ParamType.PATH, - dataType = DataType.STRING - ) final String hash) { - if (hash.equals("abc")) { - context.getResponse().getWriter().println("{ \"name\" : \"document 1\", \"hash\" : \"abc\", , \"size\" : 1232, , \"extension\" : \"odt\"}"); - } else if (hash.equals("rrr")) { - context.getResponse().getWriter().println("{ \"name\" : \"another document\", \"hash\" : \"rrr\", , \"size\" : 3532, , \"extension\" : \"zip\"}"); - } - } - } + ## Packages - ```` + * [express-openapi](https://github.com/kogosoftwarellc/open-api/tree/master/packages/express-openapi) - ### API class annotation + * [fetch-openapi](https://github.com/kogosoftwarellc/open-api/tree/master/packages/fetch-openapi) + * [fs-routes](https://github.com/kogosoftwarellc/open-api/tree/master/packages/fs-routes) - Each class defining an API has to be annotated with @SwaggerModel(path = "pathToAPIs"). All APIs defined in the class will have that path as prefix. + * [openapi-default-setter](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-default-setter) - The following example defines two APIs. Both APIs will be available thru the base path of your application followed by */metadata*. + * [openapi-framework](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-framework) + * [openapi-jsonschema-parameters](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-jsonschema-parameters) - ### API method annotations + * [openapi-request-coercer](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-request-coercer) + * [openapi-request-validator](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-request-validator) - To make an method available as public API annotate it with @SwaggerApi and provide the usual Swagger specifications: + * [openapi-response-validator](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-response-validator) + * [openapi-schema-validator](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-schema-validator) - * **notes** - A description for the API + * [openapi-types](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-types) - * **method** - The HTTP method GET, PUT, POST, DELETE - * **path** - The URL pattern containing placeholders for parameters + ## Development - * **summary** - A short description or name for the API + _Note: One of the goals of this monorepo is to support independent package versions. The author has used other popular options out there (like lerna), and has found independent versioning to behave strangely with them. Another goal with the current approach is to reduce boilerplate code as much as possible (something tools like lerna don't help with). The inspiration for the current approach came from [boennemann/alle](https://github.com/boennemann/alle). The author isn't - ### Method parameters + married to the current approach, so if you have ideas on how to simplify the development of this monorepo by all means please [open an issue](https://github.com/kogosoftwarellc/open-api/issues/new)._ - The parameters used in the URL must annotated with the @SwaggerParameter annotation, which uses the following properties: + ### Typical Workflow for Contributors - * **name** - The name of the parameter, should be the same as the method argument + Let's say you're working on a package under [./packages](https://github.com/kogosoftwarellc/open-api/tree/master/packages). Here's what you do: - * **description** - A short description for the parameter - * **required** - Set this to *true* for mandatory parameters, optional parameters should be placed at the end of the URL, if paramType is PATH + 1. `cd open-api` - * **paramType** - The type/kind of the parameter - * *PATH* - For parameters placed in a REST-full URL seperated by slashes - * *QUERY* - For parameters in a query string append to the URL - * *BODY* - For parameters in a the body (the data) of a PUT or POST request - * *HEADER* - For parameters in the request header - * *FORM* - For parameters in a request body encoded with *multipart/form-data* - * **dataType** - The data type of the parameter - * *STRING* - * *INTEGER* - * *LONG* - * *BOOLEAN* - * *DATE* - * *DATETIME* + 1. `./bin/test packages/` - ## Documentation support + 1. Make your changes. + 1. _Do not bump the version in package.json._ A maintainer will handle that once your PR is merged. + 1. Once you're satisfied with your changes: + 1. Create a new branch `git checkout -b my-branch` (in case you haven't done so already). + 1. `./bin/commit packages/ 'commit message describing your change. can be multi line here. just close with a single quote like so:'` + 1. Push your change to your fork + 1. Open a PR. + ### bin - The support for Swagger UI has been changed since Release 5: - * Former versions support the Swagger UI version 1.x (aka resource.json). + Several scripts have been created to aid in the development of this monorepo (see [./bin](./bin)). They assume that your `$PWD` is the root of the repository. Here is a brief summary of common actions: - * The current version now supports Swagger UI version 2.0 which is also known as *OpenAPI* framework. + * Testing + * (Note: `./bin/test` will run `npm i` in the package _prior_ to running the tests) + * Test a single package - `./bin/test packages/` (starts the test in watch mode) + * Test all packages - `./bin/test` + * Commit changes to a package - `./bin/commit packages/ 'Commit message'` (the commit message will be prepended with the package name e.g. `: Commit message` - The following URL may be used for getting the OpenAPI specification based on the annotation information defined on class and method level: - `https:////swagger.json` + #### dev-tools + Scripts in this directory wrap common tools, like `nyc`, `tsc`, and `mocha`. They reduce boilerplate and are called from npm scripts. - The API key has to be specified as URL parameter 'api_key' or as header field 'X-Api-Key'. + ## LICENSE - ## License + ``` The MIT License (MIT) - Copyright (c) 2014 Roamsys S.A. + Copyright (c) 2018 Kogo Software LLC Permission is hereby granted, free of charge, to any person obtaining a copy @@ -13898,9 +13335,9 @@ ROAMSYS/swaggerapi: > furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in all + The above copyright notice and this permission notice shall be included in - copies or substantial portions of the Software. + all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR @@ -13913,94239 +13350,7625 @@ ROAMSYS/swaggerapi: > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - - SOFTWARE. -ryankennedy/swagger-jaxrs-doclet: > - **[Carma-Public/swagger-jaxrs-doclet](https://github.com/Carma-Public/swagger-jaxrs-doclet - "Carma-Public/swagger-jaxrs-doclet") has been doing more recent development on - a fork of this project. Please consider checking that fork out first.** + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. - # Swagger Doclet [![Build Status](https://travis-ci.org/ryankennedy/swagger-jaxrs-doclet.png)](https://travis-ci.org/ryankennedy/swagger-jaxrs-doclet) + ``` - A JavaDoc Doclet that can be used to generate a Swagger resource listing suitable for feeding to + [express-openapi-downloads-image]: http://img.shields.io/npm/dm/express-openapi.svg - swagger-ui. + [express-openapi-npm-url]: https://npmjs.org/package/express-openapi + [koa-openapi-downloads-image]: http://img.shields.io/npm/dm/koa-openapi.svg - ## Usage + [koa-openapi-npm-url]: https://npmjs.org/package/koa-openapi - To use the Swagger Doclet in your Maven project, add the following to your POM file. + [travis-url]: https://travis-ci.org/kogosoftwarellc/open-api + [travis-image]: https://api.travis-ci.org/kogosoftwarellc/open-api.svg?branch=master - ```xml - + [coveralls-url]: https://coveralls.io/r/kogosoftwarellc/open-api - - 4.0.0 + [coveralls-image]: https://coveralls.io/repos/github/kogosoftwarellc/open-api/badge.svg?branch=master - - - - - - … - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - - generate-service-docs - generate-resources - - com.hypnoticocelot.jaxrs.doclet.ServiceDoclet - - com.hypnoticocelot - jaxrs-doclet - 0.0.4-SNAPSHOT - - ${project.build.outputDirectory} - false - -apiVersion 1 -docBasePath /apidocs -apiBasePath / - - - javadoc - - - - - - - - ``` + [gitter-url]: https://gitter.im/kogosoftwarellc/open-api + [gitter-image]: https://badges.gitter.im/kogosoftwarellc/open-api.png +inaka/cowboy-swagger: > + - ## Example + # cowboy-swagger - An example project using Dropwizard is included in `jaxrs-doclet-sample-dropwizard`. To get it running, run the following commands. + [Swagger](http://swagger.io/) integration for [Cowboy](https://github.com/ninenines/cowboy) (built on [trails](https://github.com/inaka/cowboy-trails)). - ``` + ## Contact Us - $ cd jaxrs-doclet-sample-dropwizard + If you find any **bugs** or have a **problem** while using this library, please - $ mvn package + [open an issue](https://github.com/inaka/elvis/issues/new) in this repo - $ java -jar target/jaxrs-doclet-sample-dropwizard-0.0.4-SNAPSHOT.jar server sample.yml + (or a pull request :)). - ``` + ## Requirements - The example server should be running on port 8080: + Cowboy Swagger requires Erlang 18+ after 0.1.0 version - ``` + ## Why Cowboy Swagger? - $ curl localhost:8080/apidocs/service.json + Simple, because there isn't a tool in Erlang to document Cowboy RESTful APIs easy and fast, - { - "apiVersion" : "1", - "basePath" : "/apidocs/", - "apis" : [ { - "path" : "/Auth.{format}", - "description" : "" - }, { - "path" : "/HttpServletRequest.{format}", - "description" : "" - }, { - "path" : "/ModelResource_modelid.{format}", - "description" : "" - }, { - "path" : "/Recursive.{format}", - "description" : "" - }, { - "path" : "/Response.{format}", - "description" : "" - }, { - "path" : "/greetings_name.{format}", - "description" : "" - } ], - "swaggerVersion" : "1.1" - } + and to improve development productivity. - $ - ``` + With `cowboy_swagger` is possible to integrate Swagger to your Erlang projects that use Cowboy as a web server. + It is extremely easy to use, and with just a few steps you'll have a nice Web documentation for your RESTful APIs. - ## Override Swagger UI + To learn a bit more about Swagger, please check this [blog post](http://inaka.net/blog/2015/06/23/erlang-swagger-2015/). - To override the swagger ui included with the doclet, create your own swagger-ui.zip file and add a swaggerUiZipPath to the additionalparam attribute in the pom file. + ## How to Use it? - ``` + This is the best part. It is extremely easy. - -apiVersion 1 -docBasePath /apidocs -apiBasePath / -swaggerUiZipPath ../../../src/main/resources/swagger-ui.zip - ``` -signalfx/swagger-node-client: > - # Swagger Node Client + ### 1. Document each Cowboy Handler + Because `cowboy_swagger` runs on top of `trails`, the first thing that you have to do - Create client APIs for [Swagger API Specifications](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md). + is document all about your handler within the trails metadata. Keep in mind that + all fields defined within each method into the metadata must be compliant with the - Given a schema object, this tool returns an api object which can be used to interact with the API server described by the schema. The schema can be generated using [fetch-swagger-schema](https://github.com/signalfx/fetch-swagger-schema)). + [Swagger specification](http://swagger.io/specification). - ## Usage + For example, suppose that you have `example_echo_handler`, so it must implement the `trails/0` + callback from `trails_handler` behaviour: - `npm install swagger-node-client` to install, then `var swaggerNodeClient = require('swagger-node-client')` and pass in your schema object (generated using [fetch-swagger-schema](https://github.com/signalfx/fetch-swagger-schema)). + ```erlang - ## Examples + trails() -> + Metadata = + #{get => + #{tags => ["echo"], + description => "Gets echo var from the server", + produces => ["text/plain"] + }, + put => + #{tags => ["echo"], + description => "Sets echo var in the server", + produces => ["text/plain"], + parameters => [ + #{name => <<"echo">>, + description => <<"Echo message">>, + in => <<"path">>, + required => false, + type => <<"string">>} + ] + } + }, + [trails:trail("/message/[:echo]", example_echo_handler, [], Metadata)]. + ``` - First, a simple example. Let's say you saved a schema json file, then loaded it + To get a better idea of how your handler should look like, please check [here](./example/src/example_echo_handler.erl). - into your app as the `schema` variable. Now you can call operations on the API - by using swaggerNodeClient: + ### 2. Include cowboy_swagger in your app - ```javascript + First, you need to include `cowboy_swagger_handler` module in your list of trails to be compiled. - // Assuming the variable schema exists - var swaggerNodeClient = require('swagger-node-client'); + ```erlang - var api = swaggerNodeClient(schema); + % Include cowboy_swagger_handler in the trails list + Trails = trails:trails([example_echo_handler, + example_description_handler, + cowboy_swagger_handler]), + % store them - // for apiKey authorization use: api.auth('my-token') + trails:store(Trails), - // for basicAuth use: api.auth('username', 'password') + % and then compile them - // authorization may be set for any level (api, api.resource, or api.operation) + Dispatch = trails:single_host_compile(Trails), + ``` - api.pet.getPetById(id).then(function(pet){ - console.log(pet); - }); - ``` + The snippet of code above is usually placed when you start `cowboy`. Check it [here](./example/src/example.erl#L31). + Then add `cowboy_swagger` to the list of apps to be loaded in your `*.app.src` file. - Here's a more advanced case in which we're leveraging promises to implement a - 'getOrCreate' method, which doesn't actually exist within the api: + ```erlang - ```javascript + {application, example, + [ + {description, "Cowboy Swagger Basic Example."}, + {vsn, "0.1"}, + {applications, + [kernel, + stdlib, + jsx, + cowboy, + trails, + cowboy_swagger + ]}, + {modules, []}, + {mod, {example, []}}, + {registered, []}, + {start_phases, [{start_trails_http, []}]} + ] + }. - var swaggerNodeClient = require('swagger-node-client'); + ``` - var api = swaggerNodeClient(schema); + And that's it, you got it. Now start your application and then you will have access to the API docs - function getOrCreate(id, name){ - return api.pet.getPetById(id).catch(function(response){ - // If pet doesn't exist, create a new one. - if(response.status === 404){ - var pet = {id: id, name: name}; - return api.pet.addPet(pet).then(function(){ - return pet; - }); - } + under the path `/api-docs`. Supposing that you're running the app on `localhost:8080`, - // Unknown error - console.error(response.error.toString()); - }); - } + that will be [http://localhost:8080/api-docs](http://localhost:8080/api-docs). - getOrCreate(23, 'bob').then(function(pet){ - console.log('Got pet:', pet); - }, function(error){ - console.error(error.toString()); - }); + ## Configuration - ``` + Additionally, `cowboy_swagger` can be configured/customized from a `*.config` file: - ## API + ### app.config - #### `api = swaggerNodeClient(schema)` - * *schemaObject* - A json object describing the schema (generated by [fetch-swagger-schema](https://github.com/signalfx/fetch-swagger-schema)). + ```erlang - * *api* - An object which can be used as the api for the given schema. The first-level objects are the resources within the schema and the second-level functions are the operations which can be performed on those resources. + [ + %% Other apps ... + %% cowboy_swagger config + {cowboy_swagger, + [ + %% `static_files`: Static content directory. This is where Swagger-UI + %% is located. Default: `priv/swagger`. + %% Remember that Swagger-UI is embedded into `cowboy-swagger` project, + %% within `priv/swagger` folder. BUT you have to reference that path, + %% and depending on how you're using `cowboy-swagger` it will be different. + %% For example, assuming that you want to run your app which has + %% `cowboy-swagger` as dependency from the console, `static_files` will be: + {static_files, "./deps/cowboy_swagger/priv/swagger"}, - #### `api.` + %% `global_spec`: Global fields for Swagger specification. + %% If these fields are not set, `cowboy_swagger` will set default values. + {global_spec, + #{swagger => "2.0", + info => #{title => "Example API"}, + basePath => "/api-docs" + } + } + ] + } + ]. - A map of all the resources as defined in the schema to their operation handler (e.g. `api.pet`). + ``` - #### `responsePromise = api..(data, options)` + ### Definitions - This is the actual operation function to initiate a request to the API endpoint (e.g., `api.pet.getPetById`). + [Definitions](http://swagger.io/specification/#definitionsObject) can be used for describing - The operation handler takes two parameters: + [parameters](http://swagger.io/specification/#parametersDefinitionsObject), - * *data* - A map of the operation data parameters. If the operation only has one parameter, the value may be used directly (i.e. `api.pet.getPetById(1, callback)` is the same as `api.pet.getPetById({petId: 1}, callback)`). + [responses](http://swagger.io/specification/#responsesDefinitionsObject) and - * *options* - A map of the options to use when calling the operation (see below for full list). + [security](http://swagger.io/specification/#securityDefinitionsObject) schemas. - The response promise is an ES6 promise. A HTTP response in the 200s range will result + For adding definitions to your app, you have 2 choices: - in a resolved promise and anything else will result in a rejected promises. A resolved - promise value is whatever the server responded with (JSON is automatically parsed). A + 1. Add a `definitions` key to your cowboy_swagger `global_spec` map. - rejected promise value is a map with a `status`, `data`, and `error` properties, where + 2. Add them by calling `cowboy_swagger:add_definition/2` and send the + definition's name and properties. - the status is the HTTP status, data is the response body from the server, and error + Let's say you want to describe a `POST` call to a `newspapers` endpoint that requires - is a JavaScript error (if any occurred). + `name` and `description` fields only, you can do it like this: - Here's an example: + **Option 1:** - ```javascript + ```erlang - // use of .then(successHandler, failHandler) + [ ... % other configurations - responsePromise.then(function(response){ - console.log('successful response:', response); - }, function(response){ - console.log('request failed due to error:', response.error); - }); + , { cowboy_swagger + , [ { global_spec + , #{ swagger => "2.0" + , info => #{title => "My app API"} + , definitions => #{ + "RequestBody" => + #{ "name" => + #{ "type" => "string" + , "description" => "Newspaper name" + } + , "description" => + #{ "type" => "string" + , "description" => "Newspaper description" + } + } + } + } + } + ] + } + ] ``` - ## Developing - - After installing [nodejs](http://nodejs.org) execute the following: + **Option 2:** - ```shell + For the second choice, you can do it for example in one or several `start_phases`, - git clone https://github.com/signalfx/swagger-node-client.git + directly in your handler or any other place you want. - cd swagger-node-client - npm install + ```erlang - npm run dev + -spec trails() -> trails:trails(). + trails() -> + DefinitionName = <<"RequestBody">>, + DefinitionProperties = + #{ <<"name">> => + #{ type => <<"string">> + , description => <<"Newspaper name">> + } + , <<"description">> => + #{ type => <<"string">> + , description => <<"Newspaper description">> + } + }, + % Add the definition + ok = cowboy_swagger:add_definition(DefinitionName, DefinitionProperties), + ... ``` - The build engine will test and build everything, start a server hosting the `example` folder on [localhost:3000](http://localhost:3000), and watch for any changes and rebuild when nescessary. - To generate minified files in `dist`: + Now in your handler's trails callback function you can use it: - ```shell - npm run dist + ```erlang + ... + RequestBody = + #{ name => <<"request body">> + , in => body + , description => <<"request body (as json)">> + , required => true + % Use the previously created `RequestBody' definition + , schema => cowboy_swagger:schema(<<"RequestBody">>) + }, + Metadata = + #{ get => + #{ tags => ["newspapers"] + , description => "Returns the list of newspapers" + , produces => ["application/json"] + } + , post => + # { tags => ["newspapers"] + , description => "Creates a new newspaper" + , consumes => ["application/json"] + , produces => ["application/json"] + , parameters => [RequestBody] % and then use that parameter here + } + }, + Path = "/newspapers", + Options = #{path => Path}, + [trails:trail(Path, newspapers_handler, Options, Metadata)]. ``` -springfox/springfox-grails-integration: > - = SpringFox Grails Integration - image:https://api.bintray.com/packages/springfox/maven-repo/springfox-grails-integration/images/download.svg["Download", link="https://bintray.com/springfox/maven-repo/springfox-grails-integration/_latestVersion"] + What this does for you is add a nice `response`, `parameter` or `security` - image:https://circleci.com/gh/springfox/springfox-grails-integration.svg?style=svg["CircleCI", link="https://circleci.com/gh/springfox/springfox-grails-integration"] + model in swagger-ui, so client developers will know exactly what parameters - image:https://codecov.io/gh/springfox/springfox-grails-integration/branch/master/graph/badge.svg["codecov",link="https://codecov.io/gh/springfox/springfox-grails-integration"] + the API expects for every endpoint. - image:https://api.codacy.com/project/badge/Grade/77fbd793eb06447d9f1bf47eb8cdad8b["Codacy code quality", link="https://www.codacy.com/app/dilip-krishnan-github/springfox-grails-integration?utm_source=github.com&utm_medium=referral&utm_content=springfox/springfox-grails-integration&utm_campaign=Badge_Grade"] - image:https://app.fossa.io/api/projects/git%2Bgithub.com%2Fspringfox%2Fspringfox-grails-integration.svg?type=shield["FOSSA Status", link="https://app.fossa.io/projects/git%2Bgithub.com%2Fspringfox%2Fspringfox-grails-integration?ref=badge_shield"] + ## Example + For more information about `cowboy_swagger` and how to use it, please check this [Example](./example). +gedaiu/swaggarize: > + # OpenApi - SpringFox Grails integration library that produces grails specific documentation. + I will not mantain this project in the future. Please have a loog at this fork: [https://github.com/gedaiu/OpenApi](https://github.com/gedaiu/OpenApi) +tjwebb/sails-swagger: > + # sails-swagger - == Development Environment + [![NPM version][npm-image]][npm-url] - === IDE setup + [![Build status][ci-image]][ci-url] + [![Dependency Status][daviddm-image]][daviddm-url] - ==== IntelliJ IDEA + [![Code Climate][codeclimate-image]][codeclimate-url] - - File >> open >> build.gradle - - Make sure to check the 'use the default gradle wrapper' option. + [swagger.io](http://swagger.io/) (v2.0) hook for Sails. The application's models, controllers, and routes are aggregated and transformed into a Swagger Document. Supports the Swagger 2.0 specification. - - First time build + ## Install - ```bash - ./gradlew cleanIdea idea + ```sh + $ npm install sails-swagger --save ``` - === Build + ## Configuration + ```js - - To get more output from any gradle commands/tasks append a `-i` (info) or `-d` (debug) e.g. + // config/swagger.js - ```bash + module.exports.swagger = { + /** + * require() the package.json file for your Sails app. + */ + pkg: require('../package'), + ui: { + url: 'http://swagger.balderdash.io' + } + }; - ./gradlew clean build -i + ``` - ``` + ## Usage - - To publish to local maven repository + After installing and configuring swagger, you can find the docs output on the [/swagger/doc](http://localhost:1337/swagger/doc) route. - ```bash - ./gradlew clean build publishToMavenLocal -i + You may also specify additional swagger endpoints by specifying the swagger spec in config/routes.js ``` + /** + * Route Mappings + * @file config/routes.js + * (sails.config.routes) + * + * Your routes map URLs to views and controllers. + */ - == Getting Started + module.exports.routes = { + /*************************************************************************** + * * + * Make the view located at `views/homepage.ejs` (or `views/homepage.jade`, * + * etc. depending on your default view engine) your home page. * + * * + * (Alternatively, remove this and add an `index.html` file in your * + * `assets` directory) * + * * + ***************************************************************************/ - :releaseVersion: 1.0.0 + '/': { + view: 'homepage' + }, - :snapshotVersion: 1.0.1-SNAPSHOT + /*************************************************************************** + * * + * Custom routes here... * + * * + * If a request to a URL doesn't match any of the custom routes above, it * + * is matched against Sails route blueprints. See `config/blueprints.js` * + * for configuration options and examples. * + * * + ***************************************************************************/ + 'get /groups/:id': { + controller: 'GroupController', + action: 'test', + skipAssets: 'true', + //swagger path object + swagger: { + methods: ['GET', 'POST'], + summary: ' Get Groups ', + description: 'Get Groups Description', + produces: [ + 'application/json' + ], + tags: [ + 'Groups' + ], + responses: { + '200': { + description: 'List of Groups', + schema: 'Group', // api/model/Group.js, + type: 'array' + } + }, + parameters: [] - :springfoxVersion: 2.7.0 + } + }, + 'put /groups/:id': { + controller: 'GroupController', + action: 'test', + skipAssets: 'true', + //swagger path object + swagger: { + methods: ['PUT', 'POST'], + summary: 'Update Groups ', + description: 'Update Groups Description', + produces: [ + 'application/json' + ], + tags: [ + 'Groups' + ], + responses: { + '200': { + description: 'Updated Group', + schema: 'Group' // api/model/Group.js + } + }, + parameters: [ + 'Group' // api/model/Group.js + ] - :springfoxRfc6570Version: 1.0.0 + } + } + }; - The SpringFox Grails integration library depends on http://springfox.github.io/springfox/docs/current/[Springfox] + ``` - image:https://api.bintray.com/packages/springfox/maven-repo/springfox/images/download.svg["Download", link="https://bintray.com/springfox/maven-repo/springfox/_latestVersion"] + ## License + MIT - == Dependencies - The Springfox libraries are hosted on https://bintray.com/springfox/maven-repo/springfox/view[bintray] and jcenter. + ## Maintained By - The artifacts can be viewed accessed at the following locations: + [](http://langa.io) - * Release: - ** https://jcenter.bintray.com/io/springfox/ - ** http://jcenter.bintray.com/io/springfox/ - * Snapshot - ** http://oss.jfrog.org/simple/oss-snapshot-local/io/springfox/ - ** http://oss.jfrog.org/oss-snapshot-local/io/springfox/ + [sails-version-image]: https://goo.gl/gTUV5x - SpringFox has multiple modules and the dependencies will vary depending on the desired API specification standard. + [sails-url]: http://sailsjs.org - Below outlines how to include the springfox-swagger2 module which produces Swagger 2.0 API documentation. + [npm-image]: https://img.shields.io/npm/v/sails-swagger.svg?style=flat + [npm-url]: https://npmjs.org/package/sails-swagger - TIP: Refer the main documentation on how to http://springfox.github.io/springfox/docs/current/#swagger-ui[include springfox bundled swagger-ui] dependencies + [ci-image]: https://img.shields.io/travis/langateam/sails-swagger/master.svg?style=flat + [ci-url]: https://travis-ci.org/langateam/sails-swagger - NOTE: Please refer the main documentation on how to http://springfox.github.io/springfox/docs/current/#dependencies[include the springfox-swagger2 dependencies] - - which are required for this integration library to work. + [daviddm-image]: http://img.shields.io/david/langateam/sails-swagger.svg?style=flat + [daviddm-url]: https://david-dm.org/langateam/sails-swagger - === Release + [codeclimate-image]: https://img.shields.io/codeclimate/github/langateam/sails-swagger.svg?style=flat - [source,groovy] + [codeclimate-url]: https://codeclimate.com/github/langateam/sails-swagger +sarnowski/swagger1st: > + ## swagger1st: A Swagger-First Clojure Ring handler - [subs="verbatim,attributes"] - ---- + ![Maven Central](https://img.shields.io/maven-central/v/org.zalando/swagger1st.svg) - repositories { - jcenter() - } + [![Build Status](https://travis-ci.org/zalando-stups/swagger1st.svg?branch=master)](https://travis-ci.org/zalando-stups/swagger1st) + [![codecov](https://codecov.io/gh/zalando-stups/swagger1st/branch/master/graph/badge.svg)](https://codecov.io/gh/zalando-stups/swagger1st) - dependencies { - compile "io.springfox.grails:springfox-grails:{releaseVersion}" //<1> - } - ---- + swagger1st is a Clojure [Ring](https://github.com/ring-clojure/ring) handler that parses, validates and routes requests + based on your [Swagger](http://swagger.io/)/OpenAPI definition. It takes the opposite approach of [ring-swagger](https://github.com/metosin/ring-swagger)—which enables you to generate your Swagger spec from your Clojure code—by allowing you to use your Swagger spec to generate Clojure code. - === Snapshot + Instead of defining routes and validation rules in your code, you can use swagger1st along with [Swagger/OpenAPI's great tool set](http://editor.swagger.io/) to specify your API according to the [Swagger/Open API 2.0 Specification](https://github.com/swagger-api/swagger-spec). This enables you to specify your API in an API-First, technology-independent format. The resulting definition is the ultimate format for publishing, sharing and reviewing your API. - [source,groovy] - [subs="verbatim,attributes"] + #### Compatibility Overview - ---- + swagger1st aims to implement all of the Swagger/OpenAPI spec's features, so that you only have to write your business logic. [This document](https://github.com/zalando-stups/swagger1st/blob/master/comp-2.0.md) shows which aspects of the spec it currently supports. - repositories { - maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' } - } + swagger1st will use the Swagger definition of your API as a configuration file for processing incoming requests—ensuring that your implementation and specification always remain in sync. During runtime, you can inspect and easily test - dependencies { - compile "io.springfox.grails:springfox-grails:{snapshotVersion}" //<1> - } + your API with the built-in [Swagger UI](http://petstore.swagger.io/). You can also extend the interpretation of - ---- + your definition according to your own needs. - == Configuration + Imagine a simple API definition like this: - In your Application (GrailsAutoConfiguration) startup entry-point follow the steps below + ```yaml + swagger: '2.0' - [source,groovy] - [subs="verbatim,attributes"] + info: + title: Example API + version: '0.1' - ---- + paths: + /helloworld: + get: + summary: Returns a greeting. + operationId: example.api/generate-greeting + parameters: + - name: firstname + in: query + type: string + pattern: "^[A-Z][a-z]+" + responses: + 200: + description: say hello + ``` - // 1. Enable SpringFox on your project + By default, this definition is connected to your business logic via the `operationId`, which might be defined like so: - @EnableSwagger2 - // 2. Import the springfox grails integration configuration + ```clojure - @Import([springfox.documentation.grails.SpringfoxGrailsIntegrationConfiguration]) + (ns example.api + (:require [ring.util.response :as r])) - class Application extends GrailsAutoConfiguration { - static void main(String[] args) { - GrailsApp.run(Application, args) - } + (defn generate-greeting [request] + (let [firstname (-> request :parameters :query :firstname)] + (-> (r/response (str "Hello " firstname "!")) + (r/content-type "plain/text")))) + ``` - // 3. **Optionally** define a custom docket or omit this step to use the default - // For grails it is preferrable to use use the following settings. - @Bean - Docket api() { - new Docket(DocumentationType.SWAGGER_2) - .ignoredParameterTypes(MetaClass) - .select() - .paths(not(ant("/error"))) - .build() - } - // 4. **Optionally** in the absense of asset pipeline configure the swagger-ui webjar to serve the scaffolded - swagger UI - @Bean - static WebMvcConfigurerAdapter webConfigurer() { - new WebMvcConfigurerAdapter() { - @Override - void addResourceHandlers(ResourceHandlerRegistry registry) { - if (!registry.hasMappingForPattern("/webjars/**")) { - registry - .addResourceHandler("/webjars/**") - .addResourceLocations("classpath:/META-INF/resources/webjars/") - } - if (!registry.hasMappingForPattern("/swagger-ui.html")) { - registry - .addResourceHandler("/swagger-ui.html") - .addResourceLocations("classpath:/META-INF/resources/swagger-ui.html") - } - } - } - } - } + This is all you need to do to define and implement your API. Only fully validated requests get to your function, - ---- + so you can rely on swagger1st to properly check all input parameters according to your definition. The function itself + is a normal Clojure function without any dependencies to swagger1st - simple as that. - == Swagger UI integration + ### Quickstart - IMPORTANT: In order to use the bundled swagger UI as explained in ___step 4___ above. The following library needs to be - included in the `build.gradle` + The following provides instructions for simple, complex and manual setups. For all three approaches you'll need to install [Leiningen](http://leiningen.org/) as the build tool. - [source,groovy] + #### Simple Setup - [subs="verbatim,attributes"] + If you're bootstrapping a completely new project, or just want to try out swagger1st, you can use this Leiningen template: - ---- - repositories { - jcenter() - } + ``` + $ lein new swagger1st myproject - dependencies { - compile "compile "io.springfox:springfox-swagger-ui:{springfoxVersion}" //<1> - } + $ cd myproject - ---- + $ lein ring server-headless + ``` - NOTE: The latest released version is image:https://api.bintray.com/packages/springfox/maven-repo/springfox/images/download.svg["Springfox Version", - link="https://bintray.com/springfox/maven-repo/springfox/_latestVersion"] + This will run a local web server on port 3000, so you can interact with the API at . Also, you might want to have a look at for a graphical interface to explore and experiment with your API (using [Swagger UI](http://petstore.swagger.io/)). - == Extensibility + ### Complex Setup - The library comes with intelligent defaults imeplemented by `DefaultGrailsAlternateTypeRuleConvention`. However the - defaults can be tweaked using one of these extensibility mechanisms. The following classes can be implemented and + To see how you can handle dependency injection with swagger1st, generate a project setup that includes Stuart Sierra's - registered as a bean to augment default behavior. + [component](https://github.com/stuartsierra/component) framework: - - AlternateTypeRuleConvention - for adding custom conventions for replacing grails types + ``` - - GrailsPropertySelector - for overriding the selection of grails properties by the default convention + $ lein new swagger1st myproject +component - - GrailsPropertyTransformer - for overriding the transformer of the grails property + $ cd myproject - - GeneratedClassNamingStrategy - for naming the generated class mixins + $ lein run -m myproject.core + ``` - == Demo application + As with the simple setup above, this will launch a local web server on port 3000. - The demo application is available in https://github.com/springfox/springfox-grails-demo[this repository]. You can + ### Manual Setup - see a live demo running or https://immense-escarpment-17128.herokuapp.com/swagger-ui.html[heroku here]. + The following steps describe how to manually set up swagger1st in a Clojure project. This is especially useful if you want to integrate it into an existing project or cannot use the provided template for other reasons. - == Troubleshooting + Use the following dependency in your [Leiningen](http://leiningen.org/) project: - If you get an exception when you try to run your app, this might be because of the chosen profile for your application. + [org.zalando/swagger1st ""] - If you use the `rest-api` profile, everything should be fine, but if you've chosen the `web` profile, it is likely that + This creates a Ring-compliant handler: - you have to add something like this. - grails.serverURL: http://localhost:8080 + ```clojure - - to your `application.yml` for the plugin to render absolute links. + (ns example + (:require [io.sarnowski.swagger1st.core :as s1st] + [io.sarnowski.swagger1st.util.security :as s1stsec])) + (def app + (-> (s1st/context :yaml-cp "my-swagger-api.yaml") + (s1st/discoverer) + (s1st/mapper) + (s1st/parser) + (s1st/protector {"oauth2" (s1stsec/allow-all)}) + (s1st/executor))) + ``` + ### Commands for Development - ## License - image:https://app.fossa.io/api/projects/git%2Bgithub.com%2Fspringfox%2Fspringfox-grails-integration.svg?type=large["FOSSA Status", link="https://app.fossa.io/projects/git%2Bgithub.com%2Fspringfox%2Fspringfox-grails-integration?ref=badge_large"] -rantav/flask-restful-swagger: > - # flask-restful-swagger + ```shell + # get the source - [![flask_restful_swagger-automation](https://github.com/rantav/flask-restful-swagger/workflows/flask_restful_swagger%20Python2.7/badge.svg)](https://github.com/rantav/flask-restful-swagger/actions)
+ $ git clone https://github.com/zalando-stups/swagger1st.git - [![flask_restful_swagger-automation](https://github.com/rantav/flask-restful-swagger/workflows/flask_restful_swagger%20Python3.7/badge.svg)](https://github.com/rantav/flask-restful-swagger/actions)
+ $ cd swagger1st + # run the tests - ## What is flask-restful-swagger? + $ lein test - flask-restful-swagger is a wrapper for [flask-restful](http://flask-restful.readthedocs.org/en/latest/) which enables [swagger](https://developers.helloreverb.com/swagger/) support. + # run all tests, including performance benchmarks - In essence, you just need to wrap the Api instance and add a few python decorators to get full swagger support. + $ lein test :all - ## Installation: + # build an own artifact for local development - Install: + $ lein install - ``` + # release a new version - pip install flask-restful-swagger + $ lein release :minor ``` - (This installs flask-restful as well) - + For interactive development, you can start a REPL by typing `lein repl`. - ## See Some Quick Examples: + ### Projects Using Swagger1st in Production - ```bash - PYTHONPATH=. python examples/basic.py + - [Friboo](https://github.com/zalando/friboo), a utility library for writing microservices in Clojure, with support for Swagger and OAuth. It uses swagger1st at its base for RESTful HTTP endpoints and also integrates with the [component](https://github.com/stuartsierra/component) framework. - PYTHONPATH=. python examples/blueprints.py + - [STUPS.io](https://stups.io/) components [Kio](https://github.com/zalando-stups/kio), [PierOne](https://github.com/zalando-stups/pierone) (a complete Docker registry based on S3), [Essentials](https://github.com/zalando-stups/essentials), [TWINTIP](https://github.com/zalando-stups/twintip-storage) and [mint](https://github.com/zalando-stups/mint-storage) - PYTHONPATH=. python examples/inheritance.py - ``` + ### The Ring Handler in Detail - Browse to: [http://localhost:5000/api/spec.html](http://localhost:5000/api/spec.html) + * `s1st/context` (required) + * Creates a new context from a given definition. This context will be used by the next steps to prepare the + execution of requests. + * `s1st/discoverer` (optional) + * The discoverer enables certain HTTP endpoints, that makes it easy to work with your API. In particular, this + enables the Swagger UI under the path `/ui/` and exposes the Swagger definition under `/swagger.json`. + * `s1st/mapper` (required) + * The mapper denormalizes the given definition (e.g. resolves all `$ref`s) and figures out, which request definition + maps to the actual incoming request. After this function, your `request` map contains the `:swagger` key, which + contains a `:request` key containing the denormalized definition of the request and a `:key` key which can be used + to uniquely identify a request. + * `s1st/parser` (required) + * The parser parses the incoming request according to the definition and validates all inputs. + * `s1st/protector` (optional) + * The protector can enforce all security definitions for you. As the security check implementations vary depending + on your environment, this is only a framework to hook into the system and define callbacks for the actual checks. + * `s1st/executor` (required) + * The executor executes your defined function in the end. At this point, the whole definition was validated and only + valid requests make it up until here. You can also specify an own function resolver function in order to hook into + your own framework. + ### License - ## Contributing, and Making Improvements: + Copyright (c) 2015, Tobias Sarnowski - - [Contribution Guide](./CONTRIBUTING.md) + Copyright (c) 2016, Zalando SE - - [Code of Conduct](./CODE_OF_CONDUCT.md) - - [Development Environment](./development/DEVELOPMENT.md) + Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, + provided that the above copyright notice and this permission notice appear in all copies. - ## How To: + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - In your program, where you'd usually just use flask-restful, add just a little bit of sauce and get a swagger spec out. + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF - ```python + THIS SOFTWARE. +lucybot/api-spec-converter: > + # api-spec-converter - from flask import Flask + [![Share on Twitter][twitter-image]][twitter-link] - from flask_restful import Api - from flask_restful_swagger import swagger + [![Chat on gitter][gitter-image]][gitter-link] + [![NPM version][npm-image]][npm-link] - app = Flask(__name__) + [![Build status][travis-image]][travis-link] - ################################### + [![Dependency status][deps-image]][deps-link] - # Wrap the Api with swagger.docs. It is a thin wrapper around the Api class that adds some swagger smarts + [![devDependency status][devdeps-image]][devdeps-link] - api = swagger.docs(Api(app), apiVersion='0.1') - ################################### + Convert between API description formats such as [Swagger](http://swagger.io/) and [RAML](http://raml.org/) + **Currently only supports conversion to OpenAPI(fka Swagger) 2.0 format, and from OpenAPI 2.0 to OpenAPI 3.0.x** - # You may decorate your operation with @swagger.operation - class Todo(Resource): - "Describing elephants" - @swagger.operation( - notes='some really good notes', - responseClass=ModelClass.__name__, - nickname='upload', - parameters=[ - { - "name": "body", - "description": "blueprint object that needs to be added. YAML.", - "required": True, - "allowMultiple": False, - "dataType": ModelClass2.__name__, - "paramType": "body" - } - ], - responseMessages=[ - { - "code": 201, - "message": "Created. The URL of the created blueprint should be in the Location header" - }, - { - "code": 405, - "message": "Invalid input" - } - ] - ) - def get(self, todo_id): + You can also use the online version at https://lucybot-inc.github.io/api-spec-converter/. - - # Operations not decorated with @swagger.operation do not get added to the swagger docs + ## Installation - class Todo(Resource): - def options(self, todo_id): - """ - I'm not visible in the swagger docs - """ - pass + ### Command Line - # Then you add_resource as you usually would + > Problems? See [issue #132](https://github.com/LucyBot-Inc/api-spec-converter/issues/132) + ```bash - api.add_resource(TodoList, '/todos') + npm install -g api-spec-converter - api.add_resource(Todo, '/todos/') + ``` - # You define models like this: + ### NodeJS/Browser - @swagger.model + ```bash - class TodoItem: - "A description ..." - pass + npm install --save api-spec-converter - # Swagger json: - "models": { - "TodoItemWithArgs": { - "description": "A description...", - "id": "TodoItem", - }, + ``` - # If you declare an __init__ method with meaningful arguments then those args could be used to deduce the swagger model fields. - @swagger.model + ## Usage - class TodoItemWithArgs: - "A description ..." - def __init__(self, arg1, arg2, arg3='123'): - pass - # Swagger json: - "models": { - "TodoItemWithArgs": { - "description": "A description...", - "id": "TodoItem", - "properties": { - "arg1": { - "type": "string" - }, - "arg2": { - "type": "string" - }, - "arg3": { - "default": "123", - "type": "string" - } - }, - "required": [ - "arg1", - "arg2" - ] - }, + ### Command Line + ```bash - # Additionally, if the model class has a `resource_fields` class member then flask-restful-swagger is able to deduce the swagger spec by this list of fields. + $ api-spec-converter -h + Usage: api-spec-converter [options] - @swagger.model + Convert API descriptions between popular formats. - class TodoItemWithResourceFields: - resource_fields = { - 'a_string': fields.String - } + Supported formats: + * swagger_1 + * swagger_2 + * openapi_3 + * api_blueprint + * io_docs + * google + * raml + * wadl - # Swagger json: - "models": { - "TodoItemWithResourceFields": { - "id": "TodoItemWithResourceFields", - "properties": { - "a_string": { - "type": "string" - }, - } - } + Options: - # And in order to close the loop with flask-restify you'd also need to tell flask-restify to @marshal_with the same list of fields when defining your methods. + -h, --help output usage information + -V, --version output the version number + -f, --from Specifies format to convert + -t, --to Specifies output format + -s, --syntax [syntax] Specifies output data syntax: json or yaml. Defaults to json + -o, --order [sortOrder] Specifies top fields ordering: openapi or alpha. Defaults to openapi + -c, --check Check if result is valid spec + -d, --dummy Fill missing required fields with dummy data + ``` - # Example: + Example: - @marshal_with(TodoItemWithResourceFields.resource_fields) + ```bash - def get() - return ... + $ api-spec-converter --from=swagger_1 --to=swagger_2 --syntax=yaml --order=alpha https://raw.githubusercontent.com/LucyBot-Inc/api-spec-converter/master/test/input/swagger_1/petstore/pet.json > swagger.json ``` - # Using @marshal_with - - Let us recap usage of @marshal_with. + ### NodeJS - flask-restful has a decorator `@marshal_with`. With the following setup it's possible to define the swagger model types with the same logic as `@marshal_with`. + ### Options - You have to: + * `from` - source format (see formats below) + * `to` - desired format (see formats below) - ```python + * `source` - Filename, URL, or JS object for the source - # Define your model with resource_fields + ### Simple example: - @swagger.model + ```js - class TodoItemWithResourceFields: - resource_fields = { - 'a_string': fields.String, - 'a_second_string': fields.String(attribute='a_second_string_field_name') - } + var Converter = require('api-spec-converter'); - # And use @marshal_with(YourClass.resource_fields): - @marshal_with(TodoItemWithResourceFields.resource_fields) + Converter.convert({ + from: 'swagger_1', + to: 'swagger_2', + source: 'https://api.gettyimages.com/swagger/api-docs', + }, function(err, converted) { + console.log(converted.stringify()); + // For yaml and/or OpenApi field order output replace above line + // with an options object like below + // var options = {syntax: 'yaml', order: 'openapi'} + // console.log(converted.stringify(options)); + }) - def get() - return ... ``` + ### Callback vs Promises + + This library has full support for both callback and promises. + All async functions return promises but also will execute callback if provided. - # Running and testing + ```js - Now run your flask app + var Converter = require('api-spec-converter'); - ``` + Converter.convert({ + from: 'swagger_1', + to: 'swagger_2', + source: 'https://api.gettyimages.com/swagger/api-docs', + }) - python example.py + .then(function(converted) { + console.log(converted.stringify()); + }); ``` + ### Advanced features: - And visit: + ```js + var Converter = require('api-spec-converter'); - ``` + Converter.convert({ + from: 'swagger_1', + to: 'swagger_2', + source: 'https://api.gettyimages.com/swagger/api-docs', + }) + .then(function(converted) { + // [Optional] Fill missing fields with dummy values + converted.fillMissing(); - curl http://localhost:5000/api/spec.json + // [Optional] Validate converted spec + return converted.validate() + .then(function (result) { + if (result.errors) + return console.error(JSON.stringify(errors, null, 2)); + if (result.warnings) + return console.error(JSON.stringify(warnings, null, 2)); + fs.writeFileSync('swagger2.json', converted.stringify()); + }); + }); ``` - # Passing more metadata to swagger + ### Browser + + ```js - When creating the `swagger.docs` object you may pass additional arguments, such as the following: + + APISpecConverter.convert(...) ``` - api_spec_url - where to serve the swagger spec from. Default is /api/spec. This will make the json - available at /api/spec as well as /api/spec.json and will also present a nice interactive + ## Supported Formats - HTML interface at /api/spec.html + * [Swagger 1.x](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/1.2.md) (swagger_1) - apiVersion - passed directly to swagger as the apiVersion attribute. Default: 0.0 + * [OpenAPI(fka Swagger) 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) (swagger_2) + * [OpenAPI 3.0.x](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md) (openapi_3) - basePath - passed directly to swagger as the basePath attribute. Default: 'http://localhost:5000' (do not include a slash at the end) + * [I/O Docs](https://github.com/mashery/iodocs) (io_docs) + * [API Blueprint](https://github.com/apiaryio/api-blueprint/blob/master/API%20Blueprint%20Specification.md) (api_blueprint) - resourcePath - same as before. default: '/' + * [Google API Discovery](https://developers.google.com/discovery/v1/reference/apis) (google) + * [RAML](http://raml.org/spec.html) (raml) - produces - same as before, passed directly to swagger. The default is ["application/json"] + * [WADL](http://www.w3.org/Submission/wadl/) (wadl) - swaggerVersion - passed directly to swagger. Default: 1.2 + ## Conversion Table - description - description of this API endpoint. Defaults to 'Auto generated API docs by flask-restful-swagger' - ``` + |from: |swagger_1|swagger_2|openapi_3|io_docs|api_blueprint|google|raml|wadl| + -------------------|:-------:|:-------:|:-----:|:-----:|:-----------:|:----:|:--:|:--:| - # Accessing the result json spec and an Interactive HTML interface + |to swagger_1 | n/a | | | | | | | | - Assuming you provided `swagger.docs` with a parameter `api_spec_url='/api/spec'` (or left out in which case the default is '/api/spec') you may access the resulting json at /api/spec.json. + |to swagger_2 | :white_check_mark: | n/a | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | - You may also access /api/spec.html where you'd find an interactive HTML page that lets you play with the API to some extent. + |to openapi_3 | :eight_spoked_asterisk: | :white_check_mark: | n/a | :eight_spoked_asterisk: | :eight_spoked_asterisk: | :eight_spoked_asterisk: | :eight_spoked_asterisk: | :eight_spoked_asterisk: | + |to io_docs | | | | n/a | | | | | - Here's how this HTML page would look like: + |to api_blueprint | | | | | n/a | | | | + |to google | | | | | | n/a | | | - ![An example /api/spec.html page](http://cl.ly/image/312Q2u091u24/Screen%20Shot%202013-12-17%20at%2012.26.02%20PM.png) + |to raml | | | | | | | n/a| | + |to wadl | | | | | | | | n/a| - # Accessing individual endpoints (.help.json) - flask-restful-swagger adds some useful help pages (well, json documents) to each of your resources. This isn't part of the swagger spec, but could be useful anyhow. + #### Key - With each endpoint you register, there's also an automatically registered help endpoint which ends with a .help.json extension. + * :white_check_mark: - direct conversion - So for example when registering the resource `api.add_resource(TodoList, '/todos')` you may access the actual api through the url `/todos` and you may also access the help page at `/todos.help.json`. This help page spits out the relevant json content only for this endpoint (as opposed to `/api/spec.json` which spits out the entire swagger document, which could be daunting) + * :eight_spoked_asterisk: - conversion via swagger_2 - Example: + ## Contributing + Contributions are welcome and encouraged. - ``` - ### python: + ### Testing + Please add a test case if you're adding features or fixing bugs. To run the tests: - > api.add_resource(TodoList, '/todos') + ```bash - ### Shell: + WRITE_GOLDEN=true npm test + ``` - $ curl localhost:5000/todos.help.json - { - "description": null, - "operations": [ - { - "method": "GET", - "nickname": "nickname", - "parameters": [], - "summary": null - }, - { - "method": "POST", - "nickname": "create", - "notes": "Creates a new TODO item", - "parameters": [ - { - "allowMultiple": false, - "dataType": "TodoItem", - "description": "A TODO item", - "name": "body", - "paramType": "body", - "required": true - } - ], - "responseClass": "TodoItem", - "responseMessages": [ - { - "code": 201, - "message": "Created. The URL of the created blueprint should be in the Location header" - }, - { - "code": 405, - "message": "Invalid input" - } - ], - "summary": null - } - ], - "path": "/todos" - } + ### Releases ``` - When registering an endpoint with path parameters (e.g. `/todos/`) then the .help url is may be found at the swagger path, e.g. `/todos/{id}.help.json` where {id} is just that - a literal string "{id}" + npm run browserify + + git commit -a -m "Build browser distribution" + npm version minor # or major/patch - Example: + npm publish + git push --follow-tags ``` - ### Python: - > api.add_resource(Todo, '/todos/') + [twitter-image]: https://img.shields.io/twitter/url/http/lucybot.github.io/api-spec-converter.svg?style=social + [twitter-link]: https://twitter.com/intent/tweet?text=Convert+between+API+description+formats+such+as+Swagger+and+RAML:&url=http%3A%2F%2Flucybot.github.io%2Fapi-spec-converter - ### Shell: - # You might need to quote and escape to prevent the shell from messing around + [gitter-image]: https://img.shields.io/gitter/room/lucybot/api-spec-converter.svg - curl 'localhost:5000/todos/\{todo_id\}.help.json' + [gitter-link]: https://gitter.im/lucybot/api-spec-converter - { - "description": "My TODO API", - "operations": [ - { - "method": "DELETE", - "nickname": "nickname", - "parameters": [ - { - "dataType": "string", - "name": "todo_id" - } - ], - "summary": null - }, - { - "method": "GET", - "nickname": "get", - "notes": "get a todo item by ID", - "parameters": [ - { - "allowMultiple": false, - "dataType": "string", - "description": "The ID of the TODO item", - "name": "todo_id_x", - "paramType": "path", - "required": true - } - ], - "responseClass": "TodoItemWithResourceFields", - "summary": "Get a todo task" - }, - { - "method": "PUT", - "nickname": "nickname", - "parameters": [ - { - "dataType": "string", - "name": "todo_id" - } - ], - "summary": null - } - ], - "path": "/todos/{todo_id}" - } + [npm-image]: https://img.shields.io/npm/v/api-spec-converter.svg - ``` + [npm-link]: https://npmjs.org/package/api-spec-converter + [travis-image]: https://img.shields.io/travis/LucyBot-Inc/api-spec-converter.svg + [travis-link]: https://travis-ci.org/LucyBot-Inc/api-spec-converter - # Accessing individual endpoints as HTML (.help.html) + [deps-image]: https://img.shields.io/david/lucybot/api-spec-converter.svg - Similarly to the `.help.json` URLs we have `.help.html` pages which are static HTML pages to document your APIs. + [deps-link]: https://david-dm.org/lucybot/api-spec-converter - Here's a screenshot to illustrate: + [devdeps-image]: https://img.shields.io/david/dev/lucybot/api-spec-converter.svg - ![An example .help.html page](http://cl.ly/image/160E3G2F2B3u/Screen%20Shot%202013-12-10%20at%209.49.37%20PM.png) + [devdeps-link]: https://david-dm.org/lucybot/api-spec-converter#info=devDependencies +zalando/play-swagger: > + ## The Play-Swagger plugin is now renamed + [api-first-hand](https://github.com/zalando/api-first-hand). This version is + no longer under active development. + ## Api-First-Hand is actively mantained and offers full functionality of Play-Swagger with an exception of Play 2.4 support. Please navigate to [api-first-hand](https://github.com/zalando/api-first-hand) if you'd like to check out Play-Swagger or create an issue. + -- + -- - __This project is part of the [Cloudify Cosmo project](https://github.com/CloudifySource/)__ -emicklei/go-restful: > - go-restful + -- - ========== + -- - package for building REST-style Web Services using Google Go - [![Build Status](https://travis-ci.org/emicklei/go-restful.png)](https://travis-ci.org/emicklei/go-restful) + # Play-Swagger - [![Go Report Card](https://goreportcard.com/badge/github.com/emicklei/go-restful)](https://goreportcard.com/report/github.com/emicklei/go-restful) - [![GoDoc](https://godoc.org/github.com/emicklei/go-restful?status.svg)](https://pkg.go.dev/github.com/emicklei/go-restful) + [![Build Status](https://travis-ci.org/zalando/play-swagger.svg)](https://travis-ci.org/zalando/play-swagger) - [![codecov](https://codecov.io/gh/emicklei/go-restful/branch/master/graph/badge.svg)](https://codecov.io/gh/emicklei/go-restful) + [![codecov](https://codecov.io/gh/zalando/play-swagger/branch/master/graph/badge.svg)](https://codecov.io/gh/zalando/play-swagger) + [![Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/zalando/play-swagger?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - - [Code examples use v3](https://github.com/emicklei/go-restful/tree/v3/examples) + ## Compatibility - REST asks developers to use HTTP methods explicitly and in a way that's consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping: + - Play 2.4 - - GET = Retrieve a representation of a resource + - Swagger (OpenAPI) 2.0 - - POST = Create if you are sending content to the server to create a subordinate of the specified resource collection, using some server-side algorithm. - - PUT = Create if you are sending the full content of the specified resource (URI). + ## Status - - PUT = Update if you are updating the full content of the specified resource. - - DELETE = Delete if you are requesting the server to delete the resource + This plugin should be enabled using the [play-swagger-service](http://www.typesafe.com/activator/template/play-swagger-service) activator template - - PATCH = Update partial content of a resource + as the version in this repository is under active development. The status of this software is beta, - - OPTIONS = Get information about the communication options for the request URI - - ### Usage + an end-to-end functional release intended to demonstrate the possibility to generate following from a Swagger specification: - #### Without Go Modules + - Play route files + - Generators of random test data - All versions up to `v2.*.*` (on the master) are not supporting Go modules. + - Wrappers for Play route files to convert semantics from http-related to domain-related (controller_base) + - Skeletons for the domain-driven controller implementation - ``` + - Model classes and validation rules - import ( - restful "github.com/emicklei/go-restful" - ) + - Unit tests for invalid and valid parameter sets - ``` + - Security extractors (if needed) + - Skeletons for custom deserializers (if needed) - #### Using Go Modules + We benefit from community feedback. All comments are welcome! - As of version `v3.0.0` (on the v3 branch), this package supports Go modules. + # Play-Swagger Tutorial - ``` - import ( - restful "github.com/emicklei/go-restful/v3" - ) + This tutorial is based on the [play-swagger-service](http://www.typesafe.com/activator/template/play-swagger-service) activator template. - ``` + ```bash - ### Example + $ activator new playground play-swagger-service + ``` - ```Go - ws := new(restful.WebService) + The template project contains following: - ws. - Path("/users"). - Consumes(restful.MIME_XML, restful.MIME_JSON). - Produces(restful.MIME_JSON, restful.MIME_XML) - ws.Route(ws.GET("/{user-id}").To(u.findUser). - Doc("get a user"). - Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")). - Writes(User{})) - ... - - func (u UserResource) findUser(request *restful.Request, response *restful.Response) { - id := request.PathParameter("user-id") - ... - } + - `tutorial` folder with HTML tutorial - ``` - - [Full API of a UserResource](https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go) - - ### Features + - `public/swagger` folder containing static files needed for swagger UI + - `project` folder containing pre-configured `plugins.sbt` file with a definition of all required resolvers and plugins - - Routes for request → function mapping with path parameter (e.g. {id} but also prefix_{var} and {var}_suffix) support + - `conf` folder with following customized contents: + * `routes` file with route configuration for Swagger UI, example specification and commented out links to other examples + * `example.yaml`, a demo Swagger specification. The specification has a dummy implementation in `app` folder. + * `examples` folder containing other different Swagger specification examples. Each specification in this folder represents some aspect of the Play-Swagger plugin in more details. + For the specification to be picked up by the plugin it must be moved into the `conf` folder. It is allowed to have multiple Swagger specifications in the `conf` folder at the same time. + - `app` directory with following template implementations: + * `controllers/Swagger.scala` - a backend side of the Swagger UI + * `generated_controllers/example.yaml.scala` - a dummy implementation of the example controller. Will be (re)generated if deleted + * `security/example.yaml.scala` - a marshaller for OAuth2 tokens. Will not be regenerated until + a) deleted or renamed + b) explicitly requested by issuing a `apiFirstSecurity` command - - Configurable router: - - (default) Fast routing algorithm that allows static elements, [google custom method](https://cloud.google.com/apis/design/custom_methods), regular expressions and dynamic parameters in the URL path (e.g. /resource/name:customVerb, /meetings/{id} or /static/{subpath:*}) - - Routing algorithm after [JSR311](http://jsr311.java.net/nonav/releases/1.1/spec/spec.html) that is implemented using (but does **not** accept) regular expressions - - Request API for reading structs from JSON/XML and accessing parameters (path,query,header) - - Response API for writing structs to JSON/XML and setting headers + ## Welcome to Play-Swagger - - Customizable encoding using EntityReaderWriter registration - - Filters for intercepting the request → response flow on Service or Route level + Congratulations, you just created a new Play-Swagger application! - - Request-scoped variables using attributes - - Containers for WebServices on different HTTP endpoints + The [Play Framework](http://www.playframework.com/) with the [Play-Swagger](https://github.com/zalando/play-Swagger/) - - Content encoding (gzip,deflate) of request and response payloads + plugin make it easy to build RESTful web services from a Swagger API specification as the single source of truth. - - Automatic responses on OPTIONS (using a filter) + Play is based on a lightweight, stateless, web-friendly architecture. Built on [Akka](http://akka.io), - - Automatic CORS request handling (using a filter) + Play provides predictable and minimal resource consumption for highly-scalable applications. - - API declaration for Swagger UI ([go-restful-openapi](https://github.com/emicklei/go-restful-openapi), see [go-restful-swagger12](https://github.com/emicklei/go-restful-swagger12)) + The Play-Swagger plugin takes Swagger API definitions and treats them as the single source of truth of your REST services. - - Panic recovery to produce HTTP 500, customizable using RecoverHandler(...) - - Route errors produce HTTP 404/405/406/415 errors, customizable using ServiceErrorHandler(...) + Play-Swagger supports round-trip regeneration and compilation of: - - Configurable (trace) logging - - Customizable gzip/deflate readers and writers using CompressorProvider registration + - Play routes definitions (managed). - - Inject your own http.Handler using the `HttpMiddlewareHandlerToFilter` function + - Swagger domain model definitions and parameters onto Scala case classes (managed). + - Swagger domain model constraints onto Play validations (managed). - ## How to customize + - Generators for random test data generation of parameter values (managed). - There are several hooks to customize the behavior of the go-restful package. + - Unit tests for validating your service at the API boundary (managed). + - Swagger path definitions onto skeletons for Play controller implementations (unmanaged). - - Router algorithm - - Panic recovery + In the list above, "(managed)" means that the code is managed by sbt. The code is not controlled - - JSON decoder + and altered by you, the programmer of the REST service. The plugin takes your Swagger API definition as the single - - Trace logging + source of truth and regenerates these code parts in a consistent manner. - - Compression + You'll instead be focusing on implementing the service business logic in an (unmanaged) Play controller class - - Encoders for other serializers + that is generated once. Subsequent regenerations keep the code that you have added, either by commenting out the - - Use [jsoniter](https://github.com/json-iterator/go) by building this package using a build tag, e.g. `go build -tags=jsoniter .` + parts that are no longer valid, or by adding parts that are needed because you have made a change to the API. - - Use the variable `MergePathStrategy` to change the behaviour of composing the Route path given a root path and a local route path - - versions >= 3.10.1 has set the value to `PathJoinStrategy` that fixes a reported [security issue](https://github.com/advisories/GHSA-r48q-9g5r-8q2h) but may cause your services not to work correctly anymore. - - versions <= 3.9 had the behaviour that can be restored in newer versions by setting the value to `TrimSlashStrategy`. - - you can set value to a custom implementation (must implement MergePathStrategyFunc) - ## Resources + Manual generation and compilation of: - - [Example programs](./examples) + - Security extractors - - [Example posted on blog](http://ernestmicklei.com/2012/11/go-restful-first-working-example/) + - Unmarshallers for custom content types - - [Design explained on blog](http://ernestmicklei.com/2012/11/go-restful-api-design/) - - [sourcegraph](https://sourcegraph.com/github.com/emicklei/go-restful) + is supported in the case if - - [showcase: Zazkia - tcp proxy for testing resiliency](https://github.com/emicklei/zazkia) - - [showcase: Mora - MongoDB REST Api server](https://github.com/emicklei/mora) + a) No security extractor or unmarshaller with the same name already exists + b) The developer issues `apiFirstSecurity` or `apiFirstMarshallers` sbt command - Type ```git shortlog -s``` for a full list of contributors. + ## Run Your Application - © 2012 - 2022, http://ernestmicklei.com. MIT License. Contributions are welcome. -springfox/springfox-grails-demo: >- - # springfox-grails-demo + Before we go any further, let's run the application. - This is minimalistic repo, which assumes prior knowledge of grails 3.x. + - Open a shell and `cd` into your service project directory. - Sample application to demonstrate the capabilities of integrating with grails + - Start `sbt` and `run` the service. + - View the running application at [http://localhost:9000](http://localhost:9000). - Details on how to configure the grails app are available in the [library repository](https://github.com/springfox/springfox-grails-integration). You can see this demo running [live here](https://immense-escarpment-17128.herokuapp.com/swagger-ui.html). + The service template comes with the Swagger UI frontend included, + run statically from the within Play, which provides a sandbox for your service. - To run the application + The template is configured with a template Swagger API definition called `example.yaml` + and located in the `conf` directory of the Play application. - ```bash - ./grailsw run-app + The `example.yaml` definition provides an example [API description](https://github.com/zalando/play-swagger-service/blob/master/conf/example.yaml) - ``` + This definition contains three end points: - the swagger-ui page should be available at `http://localhost:8080/swagger-ui.html` -gong023/swagger-assert: > - # Swagger-assert + - the `/token` path, which accept the `GET` and `POST` methods - enable to assert swagger 1.2 doc keys and API response. For Swagger 2 take a look to [SwaggerAssertions](https://github.com/Maks3w/SwaggerAssertions) + - the `/todos/{user_id}`, which accepts the `GET` method. - [![Build Status](https://travis-ci.org/gong023/swagger-assert.svg)](https://travis-ci.org/gong023/swagger-assert) + The `GET /token` API plays a role of an authentication server and is used by the Swagger UI for OAuth token requests. - [![Coverage Status](https://coveralls.io/repos/gong023/swagger-assert/badge.png?branch=master)](https://coveralls.io/r/gong023/swagger-assert?branch=master) + The `POST /token` API represents an authorization server and is used by the security part of the + generated code to validate OAuth tokens. + + The `GET /todos/{user_id}` takes a path parameter `user_id` and returns a TODO list for given user. - ## Installation + For the client to be allowed to access this endpoint, it must provide an OAuth token with the scope `admin:org`. - composer + The token can be requested using the Swagger UI. - ```javascript - "require-dev": { - "gong023/swagger-assert": "dev-master" - } - ``` - requires PHP5.4+ + Try it out for yourself: - ## Usage + Click the [default](http://localhost:9000/) button to expand the API definition in the Swagger UI. - ### Sample API - Sample API is below. Swagger-assert enables you to assert that `/plain` response has swagger keys `id`,`name`. + # Play Routes Integration - ```php + As a Play application developer, you are used to defining your endpoints in the `conf/routes` file. - /** - * @SWG\Resource( - * resourcePath="plain", - * @SWG\Api( - * path="/plain", - * description="plain api structure", - * @SWG\Operation( - * method="GET",type="SimpleMember",nickname="plain" - * ) - * ) - * ) - * - * @SWG\Model( - * id="SimpleMember", - * @SWG\Property(name="id", type="integer", required=true, description="user id"), - * @SWG\Property(name="name", type="string", required=true, description="user name") - * ) - */ - $app->get('/plain', function () use ($app) { - $response = [ - 'id' => 0, - 'name' => 'kohsaka' - ]; + Not so with the Play-Swagger plugin! Swagger API specifications already define endpoints as `path` definitions, - return $app->json($response); - }); + as seen in the example above. So why do the work twice, right? Instead, the Play-Swagger plugin requires you to + + link your API definition in the routes file ones—making all Swagger API-defined endpoints available as children + + of one single path context location, and generating Play route definitions from them (as shown below): - ``` + ``` - ### Ready + -> /example example.yaml.Routes - At first, call `SwaggerAssert::analyze` at the start of the test. Argument is directory path where annotation file exists. + ``` - ```php + Note that the `conf/routes` file provided by this activator template also contains a couple of additional `GET` - // testing bootstrap.php + mappings required for the the Swagger UI sandbox. - \SwaggerAssert\SwaggerAssert::analyze($targetDir); - ``` + There are a couple of commented out links to other examples. If you activate some specification by moving it from + the `examples` folder into the `conf` folder, you'll need to uncomment an appropriate line in the `routes` file in - ### Assert keys + order for play to be able to find it. - Second, call `SwaggerAssert::responseHasSwaggerKeys` in test class. - - First argument: array of API response - - Second argument: string of http method - - Third argument: url of API endpoint - When testing the sample API by PHPUnit, code is as follows. + ## Swagger Domain Definitions - ```php + Scala domain model definitions are generated for all data types defined as Swagger parameters in an API specification. - use SwaggerAssert\SwaggerAssert; + Swagger parameters can be of path, query, header, form or body types, and consist of either primitive data types or + more complex types composed from objects and arrays with primitives as leaves. - class PlainApiTest extends \PHPUnit_Framework_TestCase - { - public function testResponseHasSwaggerKeys() - { - $response = $this->request('get', '/plain'); - $result = SwaggerAssert::responseHasSwaggerKeys(array $response, 'get', '/plain', $onlyRequired = true); + Both primitive types and complex types are mapped to scala. - $this->assertTrue($result); - } - } - ``` + As an example, let's look at the Swagger API specification file [`simple.petstore.api.yaml`](https://github.com/zalando/play-swagger-service/blob/master/conf/examples/simple.petstore.api.yaml), - `SwaggerAssert::responseHasSwaggerKeys` compares API response keys and keys in swagger doc and return true when they match. + which defines the API of a simple pet store. It contains a model definition for a pet. - If they differs, output below error message. + ```yaml + definitions: + pet: + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string ``` - SwaggerAssert\Exception\CompareException: Failed asserting that API response and swagger document are equal. - --- Response + This definition consists of an object `pet` containing the required properties `id` and `name` + + and the optional property `tag`. The Swagger primitive types of these properties are a 64-bit `integer` - +++ Swagger + and (twice) a `string`, successively. The Play-Swagger plugin will map this definition on to a generated Scala model. - @@ @@ - Array ( - - 0 => 'id' - - 1 => 'name' + ```scala - + 0 => 'name' - ) - ``` + package simple.petstore.api - The fourth argument is optional. If you give false, `responseHasSwaggerKeys` contains required=false keys to assert. Default value is true. + package object yaml { - if you need more sample, please take a look at [swagger-assert-sandbox](https://github.com/gong023/swagger-assert-sandbox). + type PetTag = Option[String] + case class Pet(id: Long, name: String, tag: PetTag) + } - ## Motivation + ``` - Swagger doc and API response sometimes differ. If they differ, the swagger doc causes confusion in development. - So create library to assert API response and swagger doc. + This generated model contains a type definition `PetTag`, which declares a type alias for the optional `tag` property, + and a `Pet` case class with the properties as named in the Swagger API definition and mapped on the subsequent - ## Bugs & Contributions + Scala primitive or declared types. The case class and type alias are generated in an package object `yaml`, - Please report bugs by opening an issue. + this package object itself is contained in the package `simple.petstore.api` so that full object name corresponds + to the API filename. - Contributions are welcome. -worldline/swagger-jack: > - # Swagger for Express - [![Build Status](https://travis-ci.org/feugy/swagger-jack.png)](https://travis-ci.org/feugy/swagger-jack) + Note that models are generated within a Play application as _managed_ code in the target folder. + Generated model code is not intended to be altered. We should instead look upon the Swagger definition as the single + source of truth, and as the source code that defines our model. - [Swagger](http://developers.helloreverb.com/swagger/) is a specification and complete framework implementation for describing, producing, consuming, and visualizing RESTful web services. + The Swagger specification file of our API is, in that sense, part of the codebase. + Even though the generated `Pet` case class is managed by the plugin, and not us, it can (of course) - It provides: + be used in our application codebase after being imported. - * _specification_: to write descriptors of your API + ```scala - * _tools_: based on this descriptors: friendly GUI for documentation, client libraries... + import simple.petstore.api.yaml._ - **Swagger-Jack** is a nodeJS modules that implements the swagger specification and offers you three middlewares to: + val pet = Pet(0L, "Tucker", Some("Greyhound")) + ``` - 1. _generate_ your routes from a swagger descriptor, binding them to your own controller functions - 2. _validate_ all the API inputs (query parameter, headers, bodies...) + ## Specification Cross-References - 3. report _errors_ in a consistent way + A `$ref` element of the specification is allowed to contain a name of file as it's part. Because of this, it is possible to split + a single specification into multiple files as shown in [`cross_spec_references.yaml`](https://github.com/zalando/play-swagger-service/blob/master/conf/examples/cross_spec_references.yaml) - ## How can I use it ? + example. It is also possible to reference a definition in one specification from another specification. + In this case for each reference an independent copy of the class definition will be created for each referencing specification. - First, get the module, by referencing it inside your package.json: + The definition is then placed into the appropriate package for each specification. - ```js - "dependencies": { - "express": "3.1.0", - "swagger-jack": "1.0.0" - } - ``` + Thus, even if multiple classes with the same name and structure might be generated, they all will coexist in their + own separate namespaces and won't be interchangeable. - Then, when creating your Express application, import and configure the two middlewares: - ```js - var express = require('express'), - swagger = require('swagger-jack'); + ## Primitive Types - var app = express(); - - app.use(express.bodyParser()) - .use(express.methodOverride()) - .use(swagger.generator(app, { - // general descriptor part - apiVersion: '2.0', - basePath: 'http://my-hostname.com/api' - }, [{ - // descriptor of a given resource - api: { - resourcePath: '/user' - apis: [{ - path: '/user/' - operations: [{ - httpMethod: 'POST', - nickname: 'create' - }, { - httpMethod: 'GET', - nickname: 'list' - - }] - }] - }, - // controller for this resource - controller: - create: function(req, res, next) { - // create a new user... - }, - list: function(req, res, next) { - // list existing users... - } - }]) - .use(swagger.validator(app)) - .use(swagger.errorHandler()) - - app.get "/api/unvalidated", function(req, res, next) { - // not documented not validated - } - app.listen(8080); - ``` + Swagger version 2.0 allows for primitive data types based on the types defined by + [JSON-Schema](http://json-schema.org/latest/json-schema-core.html#anchor8). - ### Generator middleware + When generated as Scala, the following mapping applies: - Generator takes the following parameters: + | Common Name | Swagger Type | Swagger Format | Scala Type | - 1. your express application, + |-------------|--------------|----------------|---------------------------------------------| - 1. a general descriptor object (which is totally not constraint: put whatever you need in it), + | integer | integer | int32 | scala.Int | - 1. an array of "resources", + | long | integer | int64 | scala.Long | - 1. optionnal `options` (see below) + | float | number | float | scala.Float | + | double | number | double | scala.Double | - A "resource" is composed by a *resource* descriptor, and the corresponding code (what we called *controller*). + | big int | integer | | scala.math.BigInt | + | big decimal | number | | scala.math.BigDecimal | - The middleware will automatically add to your express application the routes found inside the *resource* descriptor, and bound them to the provided *controller* (it uses the `nickname` attribute from the descriptor to bound the right controller's method). + | boolean | boolean | | scala.Boolean | + | string | string | | scala.String | - In the previous example, two routes are created: + | byte | string | byte | de.zalando.play.controllers.Base64String | + | binary | string | binary | de.zalando.play.controllers.BinaryString | - 1. `POST /api/user/` to create a user (controller method `create()`) + | date | string | date | org.joda.time.LocalDate | - 1. `GET /api/user/` to list existing users (controller method `list()`) + | datetime | string | date-time | org.joda.time.DateTime | + | password | string | password | scala.String | - As explained in the swagger specification, the descriptor `basePath` attribute is used as url prefix for every resources and their operations. + | file | file | | java.io.File | - You should not repeat it in resources paths and apis path. + Additionally, if a validation of type "enum" is defined for some primitive type, a trait and a set of case objects forming an ADT - The `resourcePath` in resource object is intended to be repeated in every api path. + will be generated for this enum. - If you just want to document some existing routes, just provide a resource descriptor, and no associated controller. + ## Complex Types - Of course, no validation will be provided. + Complex types are made up of primitive objects, or nested objects. - You can still register routes and middleware within your application, like you've used to. - But they will not be documented nor validated. + ### Objects - The following options are available: + Complex object types are defined in Swagger model definitions as either objects or arrays. - - descPath `String`: path of generated swagger descriptor. Must contain leading slash. Default to `/api-docs.json`, with `basePath` used as prefix. + Objects are, again, based on the [JSON-Schema](http://json-schema.org/latest/json-schema-core.html#anchor8) specification + and defined as Swagger [Schema Objects](https://github.com/Swagger-api/Swagger-spec/blob/master/versions/2.0.md#schema-object) + for parameter definitions of `type: "object"`. - ### Validator middleware + For example, given a Swagger API definition file `api.yaml` containing a model that defines a `person` as an object + with the properties `name` and `age` of the primitive types `string` and `integer` subsequently, - Validator will analyze the declared parameters of your descriptor, and validate the input. + this object will be mapped on a Scala case class, and generated in a Scala package object (namespace) with the same name - It will handle parameter casting, range validation and declared model compliance (thank to the excellent [json-gate](https://github.com/oferei/json-gate)). + as the extension of the file the specification is read from and in a package with the same name as the + Swagger definition file in which the model is defined—that is, `api` - All casted values (except body parameters) are available inside the controller methods with the `req.input` associative array. - No matter if parameter is from path, query or header: it will be present inside `req.input`. + ```yaml + definitions: + person: + type: object + required: + - name + - age + properties: + name: + type: string + age: + type: integer + format: int32 + ``` - You can still use the Express original function (`req.params`, `req.param()`, `req.headers`...), but beware: values are just strings. + Is generated into: - Bodies are also validated, but parsing is done by express's bodyParser middleware: it takes in account json and multipart bodies. For other bodies kind, validator will read itself the body, and perfoms casting. + ```scala + package api - **Caution** You *must* use `express.bodyParser()` *before* `swagger.validator`. + package object yaml { + case class Person(name: String, age: Int) + } + ``` - **Caution** You *can't* read the body by yourself (with *data*/*end* request events) for routes declared with `swagger.validator`. + ### Nested Objects - If you do not need validation, no problem: just remove the validator middleware. + Nested objects are generated adjourned but referenced hierarchically. E.g. - ### Error middleware + ```yaml + definitions: + parent: + type: object + required: + - child + properties: + child: + type: object + required: + - name + properties: + name: + type: string + ``` - Validation errors (and your custom business errors) are handled by the error middleware. - It uses the express's error mecanism: invoke the next() method with an argument. + Is generated into: - Weither it's a string or an object, it will be serialized into a json response with an http status (500 by default). + ```scala + package api - For example: + package object yaml { + case class Parent(child: ParentChild) + case class ParentChild(name: String) + } - ```js - use(swagger.generator(app, { - // general descriptor ... - }, [{ - api: // resource descriptor... - controller: { - create: function(req, res, next) { - if (// error check...) { - var err = new Error('forbidden !'); - err.status = 403; - return next(err); - } - // process ... - } - } - }])) ``` - Input validation errors are reported the same way. + ### Optionality - You may not use the error middleware and provide your own. + Swagger, by default, defines object properties to be optional, which can be overridden by providing a list of `required` + object properties as already used in the examples above. Optional properties are mapped upon Scala's `Option` type, + for which a type alias is generated for each property that is optional. E.g. - ### Power-tip ! + ```yaml - Use js-yaml to store your descriptor in a separate file, and split your code into other controller modules: + definitions: + product: + required: + - name + properties: + name: + type: string + tag: + type: string + ``` - ```js - var express = require('express'), - swagger = require('swagger-jack'), - yaml = require('js-yaml'); - - var app = express(); - - app.use(express.bodyParser()) - .use(express.methodOverride()) - .use(swagger.generator(app, - require('/api/general.yml'), - [{ - api: require('/api/users.yml'), - controller: require('/controller/users') - },{ - api: require('/api/commands.yml'), - controller: require('/controller/commands') - }]) - .use(swagger.validator(app)) - .use(swagger.errorHandler()) - - app.listen(8080); - ``` + Which is generated as: + ```scala - ### Really hacky power-tip + package api + package object yaml { + type ProductTag = Option[String] + case class Product(name: String, tag: ProductTag) + } - For very specific cases, it's possible to use the validation function without request. + ``` - For example: + As objects can be nested, so can object property optionality. To facilitate for nested optionality, we generate a nested scala `Option` type alias. E.g. - ```js - // init your application as usual - var app = express(); - var validator; // don't init yet ! the generator was not invoked - app.use(express.bodyParser()) - .use(express.methodOverride()) - .use(swagger.generator(app, - ... - , [{ - api: require('./fixtures/validatedApi.yml'), - controller: require('./controller') - ]) - // keep the validator middleware. - .use(validator = swagger.validator(app)) - .use(swagger.errorHandler()) - ... + ```yaml - // manually validate a "fake" url - var casted = {}; - var url = '/api/queryparams'; - // method, Express path, url, query, headers, body, casted, callback - validator.validate('GET', url, url, {param1:"-2", param2:"5.5"}, {}, {}, casted, function(err) { - if (err) { - // handle validation errors - } else { - // you can use casted values safely. - } - }); + definitions: + Basic: + properties: + optional: + type: object + properties: + nested: + type: string ``` - You still need to use an Express application and to declare generator and validator middlewares. + Which is generated as: - Documentation for the `validate()` function can be found [in the source code](https://github.com/feugy/swagger-jack/blob/master/src/validator.coffee#L216) + ```scala + package api + package object yaml { + type BasicOptional = Option[BasicOptionalOpt] + type BasicOptionalNested = Option[String] - ## TODO How does it works ? + case class BasicOptionalOpt(nested: BasicOptionalNested) + case class Basic(optional: BasicOptional) + } + ``` - To be Done + ### Parameter optionality - ## What about [swagger-node-express](https://github.com/wordnik/swagger-node-express) ? + As object properties can be optional, so can be query, header, body or form parameters. - Reverb folks (the ones who made Swagger) provide an express module to enhance your Express application by returning the swagger descriptor. + In the case if they are not required, they are mapped to the Scala's `Option` type. - It provides a quick way to describe your code in Json and register your express routes. + Path parameters are _must_ be declared as required. - To me it's very handy for a start, but has three problems: + In the case, if a parameter is _not_ required, it is allowed to have a default value. - 1. your descriptor is inside your code, and splitted into parts, which makes it not easy to read - 2. you do not use any more the marvellous express functions, but the one provided by swagger-node-epxress - 3. it does not use the descriptor to automatize input validation, and you still have to cast and check your parameters + ### Extension + Objects can extend other objects via employment of Swagger's `allOff` property. In the example below, the `ExtendedErrorModel` inherits _all of_ the properties of the `ErrorModel` which it refers to—that is, the properties `message` and `code`—and _extends_ this model with the property `rootCause`. Swagger object extension is mapped by duplicating inherited properties in the object that extends. E.g. - ## Changelog + ```yaml - ### 1.6.3 + definitions: + ErrorModel: + type: object + required: + - message + - code + properties: + message: + type: string + code: + type: integer + ExtendedErrorModel: + allOf: + - $ref: '#/definitions/ErrorModel' + - type: object + required: + - rootCause + properties: + rootCause: + type: string + ``` - - fix "Bug in method 'convertModel', for detecting circular reference" ([details](https://github.com/feugy/swagger-jack/issues/25)) + Which is generated as: - ### 1.6.2 + ```scala - - fix mising leading / on generated descriptor, when using non empty basePath ([details](https://github.com/feugy/swagger-jack/issues/19)) + package api + package object yaml { + import scala.math.BigInt + case class ErrorModel(message: String, code: BigInt) + case class ExtendedErrorModel(message: String, code: BigInt, rootCause: String) + } - ### 1.6.1 + ``` - - do not prepend basePath to api's path with swagger root descriptor ([details](https://github.com/feugy/swagger-jack/issues/19)) - - enforce validator on api declared with basePath + ### Polymorphism - ### 1.6.0 + Polymorphic object definitions are possible through employment of the Swagger `discriminator` property. + In the example definition below, an abstract `Pet` defines what concrete `Cat` and `Dog`s have in common. - - fix basePath handling, be more strict on operation path validation ([details](https://github.com/feugy/swagger-jack/issues/10)) + Swagger object models define data, so a discriminator property is required to distinguish concrete cat and dog - - allow validation utilities to be used without Express's request object ([details](https://github.com/feugy/swagger-jack/issues/11)) + instances as they are serialised to and from the API. In this sense, the discriminator property works + in the same way as a discriminator column works in ORM frameworks when mapping a class hierarchy onto a single table. - ### 1.5.0 + It simply contains a value that maps onto one of the concrete types—for example, `petType: "Cat"` or `petType: "Dog"`. - - more strict check for mandatory data inside descriptors + ```yaml - - test missing models that are referenced in apis + definitions: + Pet: + discriminator: petType + properties: + name: + type: string + petType: + type: string + required: + - name + - petType + Cat: + allOf: + - $ref: '#/definitions/Pet' + - properties: + huntingSkill: + type: string + default: lazy + enum: + - clueless + - lazy + - adventurous + - aggressive + required: + - huntingSkill + Dog: + allOf: + - $ref: '#/definitions/Pet' + - properties: + packSize: + type: integer + format: int32 + required: + - packSize + ``` - ### 1.4.2 + Which is generated as: - - only expose relevant models inside the swagger descriptor for a given resource ([details](https://github.com/feugy/swagger-jack/pull/9)) + ```scala - - be less restrictive on model content ([details](https://github.com/feugy/swagger-jack/pull/8)) + package api - ### 1.4.1 + package object yaml { + trait IPet { + def name: String + def petType: String + } - - check model id unicity to avoid erasure + case class Cat(name: String, petType: String, huntingSkill: CatHuntingSkill) extends IPet + case class Dog(name: String, petType: String, packSize: Int) extends IPet + case class Pet(name: String, petType: String) extends IPet - - allow apis to contain unwired resources. Allow to document handy-managed routes + sealed trait CatHuntingSkill { def value: String } + case object Clueless extends CatHuntingSkill { val value = "clueless" } + case object Lazy extends CatHuntingSkill { val value = "lazy" } + case object Adventurous extends CatHuntingSkill { val value = "adventurous" } + case object Aggressive extends CatHuntingSkill { val value = "aggressive" } + implicit def stringToCatHuntingSkill(in: String): CatHuntingSkill = in match { + case "clueless" => Clueless + case "lazy" => Lazy + case "adventurous" => Adventurous + case "aggressive" => Aggressive + } + } - ### 1.4.0 + ``` - - use CakeFile for better build/test portability + Please note how the enumeration of cat's `huntingSkill`'s get's translated into the ADT with a sealed trait `CatHuntingSkill` - - enhance documentation + and four case objects implementing that trait. - - allow swagger descriptor path customization ([details](https://github.com/feugy/swagger-jack/issues/6)) + ### Additional Properties - ### 1.3.1 + Swagger's model language allows objects' additional properties to be loosely defined employing the `additionalProperties` annotation - - fix when req.body is undefined ([details](https://github.com/feugy/swagger-jack/pull/4)) + in order to model dictionaries. These dictionaries are mapped to Scala's `Map` type, for which a type alias is + generated following the same (by now) well-known pattern as for optional properties, with the map's key parameter type being a Scala `String`. - ### 1.3.0 + A Swagger additional property definition takes as its type property the element type of the dictionary, - - allow anonymous complex bodies to have multiple occurences + which can be of primitive or complex type and which is mapped on Scala as the map's value parameter type. + Swagger allows for one `additionalProperties` annotation per object definition, so we can generate this Scala parameter - ### 1.2.0 + with the static name `additionalProperties`. - - allow body parameter to be facultative + In the following example we define a Swagger model object definition `KeyedArray` that uses the `additionalProperties` - - fix packaging issues with coffee. Only contributors need to install it globally (as well as mocha) + annotation to provide the object with a set of key value mappings from string to array. E.g. - ### 1.1.0 + ```yaml + definitions: + KeyedArrays: + type: object + additionalProperties: + type: array + items: + type: integer + ``` - - be more strict regarding multipart management + Which is generated as: - ### 1.0.1 + ```scala - - add some test on multipart/related body parsing + package api - - enhance documentation - - use [Travis CI](https://travis-ci.org/feugy/swagger-jack) + package object yaml { + import de.zalando.play.controllers.ArrayWrapper + import scala.math.BigInt + import scala.collection.immutable.Map + type KeyedArraysAdditionalPropertiesCatchAll = ArrayWrapper[BigInt] + type KeyedArraysAdditionalProperties = Map[String, KeyedArraysAdditionalPropertiesCatchAll] + case class KeyedArrays(additionalProperties: KeyedArraysAdditionalProperties) + } - ## License (MIT) + ``` - Swagger is shipped with an MIT Licence. + ## Arrays - Copyright (c) 2013 Atos Worldline + Swagger's `array` is used to define properties that hold sets or lists of model values—possibly of a primitive type, + but complex element types are also allowed. Depending on the place where the array definition appears, Swagger array can be mapped to one of two Scala types, parametrised for the element type that it contains: - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + - if an array only defined inline as a part of the response definition, it is translated to a `Seq` type + - otherwise (array appears in the parameter definition or in the `definitions` part of the specification) it is - The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + defined as a `de.zalando.play.controllers.ArrayWrapper` - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + For example, in the snippet below, an `Activity` object definition is referred to as an item element in the + `messages` property of `type: array` of the containing object definition `Example`. + A Scala type alias will be generated for the array type (just as we've seen before with optional properties), - -------- + after which the array-containing property can be generated within the case class as being of this alias type. - ### Addendum: what's with that name ? + E.g. in the Swagger definition and code - We looked for a fun and yet eloquent name. But swagger.js was already used. + ```yaml - [Jack Swagger](http://www.wwe.com/superstars/jackswagger) is an american catch superstar, and we never heard about him before, but it perfectly fits your naming goals :) -Luracast/Restler: > - ![Restler](public/examples/resources/restler.svg) Luracast - Restler + definitions: + Activity: + type: object + required: + - actions + properties: + actions: + type: string + Example: + type: object + required: + - messages + properties: + messages: + type: array + items: + $ref: '#/definitions/Activity' + ``` - ================================================================== - [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Luracast/Restler) + Which is generated as: - [![Latest Stable Version](https://poser.pugx.org/luracast/restler/v/stable.png)](https://packagist.org/packages/luracast/restler) - [![Total Downloads](https://poser.pugx.org/luracast/restler/downloads.png)](https://packagist.org/packages/luracast/restler) + ```scala - [![Latest Unstable Version](https://poser.pugx.org/luracast/restler/v/unstable.png)](https://packagist.org/packages/luracast/restler) + package api - [![License](https://poser.pugx.org/luracast/restler/license.png)](https://packagist.org/packages/luracast/restler) + package object yaml { - ### Version 5 + import de.zalando.play.controllers.ArrayWrapper + type ExampleMessages = ArrayWrapper[Activity] - > upgraded from version 3 RC6 for latest PHP support + case class Activity(actions: String) + case class Example(messages: ExampleMessages) + } - Restler is a simple and effective multi-format Web API Server written in PHP. + ``` - Just deal with your business logic in php, restler will take care of the REST! + If the description of the same array is inlined as a part of the response definition like that: - ### Restler - *Better APIs by Design* + ```yaml + paths: + /api: + get: + responses: + 200: + schema: + type: object + required: + - messages + properties: + messages: + type: array + items: + $ref: '#/definitions/Activity' + description: array payload + definitions: + Activity: + type: object + required: + - actions + properties: + actions: + type: string + ``` - * [Developer Home](https://luracast.com/products/restler/) - * [Documentation](https://restler5.luracast.com/) with live examples + than the `Seq` scala type will be used: - * Updates on [Facebook](https://www.facebook.com/Luracast) and [Twitter](https://twitter.com/Luracast) + ```scala - * [Features](#features) + package api - * [Installation](#installation) + package object yaml { + type ApiGetResponses200Messages = Seq[Activity] + case class Activity(actions: String) + case class ApiGetResponses200(messages: ApiGetResponses200Messages) + } - * [Quick Start Guide](#quick-start-guide) + ``` - * [Change Log](#change-log) - Features + ### Nested Arrays - -------- + Array definition types can be nested and are possibly optional. - * No Learning Curve + The following (contrived) snippet depicts the generated Scala code when both definition types are - * Light weight + employed in a somewhat non-useful manner. The intent of this example is to show that the case - * Flexible + class definitions are rather concisely generated, even though a stack of type aliases is needed - * Highly Customizable + to make sure that we still refer in Scala code to an aptly named Swagger definition—especially - * Many Examples that can be tried on your localhost to get started + in conjunction with the object properties being optional. Next to its benefits, - * Supports HTTP request methods HEAD, GET, POST, PUT, DELETE, OPTIONS and PATCH via header or request parameter (method) + type safety against `null` pointers does have an associated cost as well. - * Supports both RESTful and Pragmatic REST API Design - * Clients can use X-HTTP-Method-Override header, supports Cross Origin Resource Sharing and JSONP - - * Two-way format(media type) conversion both send and receive - * Pluggable content Formatter framework and api - * Comes with JSON, XML, Yaml, Amf, and Plist(both XML and Binary) format support - * Pluggable Authentication schemes - * OAuth 2 Server - * Pluggable Filters to effectively manage API usage - * API Rate Limiting Filter - * Routing - * Manual Routing (Annotation) - * Using `@url GET my/custom/url/{param}` PHPDoc comments - * Auto Routing (Reflection) - * URL to Method mapping - * URL part to Method parameter mapping - * Query parameters to Method parameter mapping - * Request body to Method parameter mapping - * Cache built-in - * Client Side Caching support - * Proxy Caching support - * API Features - * Always supports URLEncoded format for simplified input (POST vars) - * Automatic parameter validation and type conversion - * API versioning support by URL and/or vendor specific MIME - * API documentation and discovery using [Restler API Explorer](https://github.com/Luracast/Restler-API-Explorer) - * Throttling and Performance tuning - * Management - * Behavior Driven API testing using [Behat](http://behat.org/) and [Guzzle](https://github.com/guzzle/guzzle) - * Command line Project Management using [Respect/Foundation](https://github.com/Respect/Foundation) - * Dependency Management using [Composer](http://getcomposer.org/) - * Source code distributed under LGPL - - Git Repository and the Branches - - ------------------------------- - - - 1. Most stable and recent version is at the `master` branch, previous versions are in the version branches such - as `v4`, `v3`, `v2`, and `v1`. - - 2. Version branch with the current version such as `v5` is used for building up the next release. It's documentation may - not be updated frequently and thus reserved for the daring ones. - - 3. Feature branches such as `features/html` and `features/router` are purely for experimentation purpose to try out a - feature. They may be merged when ready. - - Test Drive - - ---------- - - - Install this repository to try out the examples. - - - > Make sure PHP 5.4 or above is available on your server. We recommended using the latest version for better performance. - - - ### 1. Install Composer - - - Restler uses [Composer](http://getcomposer.org/) to manage its dependencies. First, download a copy of `composer.phar`. - - It can be kept in your project folder or ideally in `usr/local/bin` to use it globally for all your projects. If you are - - on Windows, you can use the composer - - [windows installer](https://getcomposer.org/Composer-Setup.exe) instead. - - - ### 2. Install Restler - - - #### Option 1. Using composer create-project - - - You may install Restler by running the create project command in your terminal. Replace {projectName} with your actual - - project name. It will create a folder with that name and install Restler. - - - ```console - - php composer.phar create-project luracast/restler {projectName} - - ``` - - - > **Note:-** - - > - - > 1. If you do not want the additional formats and BDD tools you can include - > `--no-dev` to enforce exclusion of dev packages. - > - - > 2. If you want to try the bleading edge v3 branch or any of the feature - > branches include `3.x-dev` or `dev-features/html` in the above command - - #### Option 2. Downloading from GitHub - - - After installing Composer, download the [latest version]() of the Restler framework and extract its contents into a - - directory on your server. Next, in the root of your Restler project, run the `php composer.phar install` - - (or `composer install`) command to install all the framework's dependencies. This process requires Git to be installed - - on the server to successfully complete the installation. - - - If you want to update the Restler framework, you may issue the - - `php composer.phar update` command. - - - > **Note:-** If you are not allowed to install composer and git on your server, you - - > can install and run them on your development machine. The resulting files and - - > folders can be uploaded and used on the server. - - - ### 3. Configure - - - Ideally public folder should be mapped as your web root, It is optional, but recommended avoiding exposing unneeded - - files and folders. - - - ### 4. Try it out - - - Try the live examples in your localhost. - - > You may launch the PHP's built-in server with `composer serve` command. - - - ### 5. Run some test - - - Update the base_url specified in `behat.yml` and then try the following command - - - ```console - - - vendor/bin/behat - - - ``` - - > alternatively you can run `composer test` - - - This will test the examples against the behaviors expected, for example - - - ```gherkin - - - Feature: Testing CRUD Example - - Scenario: Creating new Author with JSON - Given that I want to make a new "Author" - And his "name" is "Chris" - And his "email" is "chris@world.com" - And the request is sent as JSON - When I request "/examples/_007_crud/authors" - Then the response status code should be 200 - And the response should be JSON - And the response has a "id" property - - ``` - - - All set, Happy RESTling! :) - - - Quick Start Guide - - ----------------- - - - We have two options to create your own restler api server - - 1. Most convenient option is using application templates such as [Restler Application](https://github.com/Luracast/Restler-Framework) - which has integrations with many packages to help us with the business logic as well. - If you choose this option, select a branch in that repository and proceed with - the instructions available there. - - 2. Create a project from scratch so that you have full control over every aspect of your application. - If you choose this option, follow along with the steps below. - - create a folder to hold your project and open it in the terminal. - - run `composer init` and follow along to create `composer.json` - - when it is asking for dependencies, type `restler/framework` and `^5` for the version constraint. - - alternatively, you can leave it blank and create the composer.json first and then run `composer require restler/framework:^5` - - - > we are using `restler/framework` instead of `luracast/restler` to reduce the space required for the package. - - > It is coming from https://github.com/Luracast/Restler-Framework it contains only the contents of src folder here. - - > Even when you are building from scratch, checking out the application templates will help with folder structure - - > decisions and finding other useful packages. - - - ### 1. Write API - - - Create your **API classes** with all needed public and protected methods - - - ### 2. Open the Gateway - - - Create the **gateway (public/index.php)** as follows - - - ```php - - addAPIClass('YourApiClassNameHere'); // repeat for more - - $r->handle(); //serve the response - - ``` - - - ### 3. Prettify URLs - - - **Enable URL Rewriting** - - - Make sure all the requests go to index.php by enabling URL Rewriting for your website - - - For example:- - - - If you are on Apache, you can use an .htaccess file such as - - - ```apache - - DirectoryIndex index.php - - - RewriteEngine On - RewriteRule ^$ index.php [QSA,L] - RewriteCond %{REQUEST_FILENAME} !-f - RewriteCond %{REQUEST_FILENAME} !-d - RewriteRule ^(.*)$ index.php [QSA,L] - - - - php_flag display_errors On - + ```yaml + definitions: + Activity: + type: object + properties: + actions: + type: string + Example: + type: object + properties: + messages: + type: array + items: + type: array + items: + $ref: '#/definitions/Activity' + nested: + type: array + items: + type: array + items: + type: array + items: + type: array + items: + type: string ``` - > **Note:-** This requires `AllowOverride` to be set to `All` instead of `None` - - > in the `httpd.conf` file, and might require some tweaking on some server - - > configurations. Refer to [mod_rewrite](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) - - > documentation for more info. - + Which is generated as: - If you are on Nginx, you have to make sure you set the `server_name` and pass the PHP scripts to fast cgi (PHP-FPM) - listening on 127.0.0.1:9000 + ```scala + package api - ``` - server { - listen 80; - server_name api.luracast.com; //change it to match your server name + package object yaml { - //... other stuff + import de.zalando.play.controllers.ArrayWrapper - location ~ \.php$ { - root /var/www/html; - fastcgi_pass 127.0.0.1:9000; - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name; - include fastcgi_params; - } + type ExampleMessagesOpt = ArrayWrapper[ExampleMessagesOptArr] + type ExampleMessages = Option[ExampleMessagesOpt] + type ExampleNested = Option[ExampleNestedOpt] + type ExampleMessagesOptArr = ArrayWrapper[Activity] + type ExampleNestedOptArrArrArr = ArrayWrapper[String] + type ExampleNestedOptArrArr = ArrayWrapper[ExampleNestedOptArrArrArr] + type ActivityActions = Option[String] + type ExampleNestedOptArr = ArrayWrapper[ExampleNestedOptArrArr] + type ExampleNestedOpt = ArrayWrapper[ExampleNestedOptArr] - //... other stuff + case class Activity(actions: ActivityActions) + case class Example(messages: ExampleMessages, nested: ExampleNested) } - ``` - - - > **Note:-** This requires PHP, PHP-FPM to be properly installed and configured. - - > Refer to [PHP FastCGI](http://wiki.nginx.org/PHPFcgiExample) example for more - - > info. - - - ### 4. Customise - - - **Fine tune to suit your needs** - - - ```php - - addAPIClass('YourApiClassNameHere'); // repeat for more - - $r->addAPIClass('Explorer'); //from restler framework for API Explorer - - $r->addFilterClass('RateLimit'); //Add Filters as needed - - $r->handle(); //serve the response ``` - Explore the api and try it out by openings `explorer/index.html` from the web root on your browser - - - Happy Exploring! :) - - - > **Note:-** Using eAccelerator can make restler to fail as it removes the - - > comments. More info can be found [here](http://wildlyinaccurate.com/eaccelerator-and-doctrine-2) - - - ### 5. Annotate - + ## Swagger Validations - Restler supports annotations in the form of PHPDoc comments for API fine tuning + Swagger API definitions allow for constraints to be put on parameter types. - They are documented in detail under [Annotations](ANNOTATIONS.md) + We have already seen the `required` constraint, used to mark a parameter or specific field within + a domain definition to be required upon input. Additional constraints, as defined by the - ### 6. Authorize + [Parameter Object](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#parameterObject), + can be added to your API definition. The Play-Swagger plugin will generate validations for these parameter - In order to protect your api, authenticate and allow valid users + constraints and make sure that your controller methods are only called if the input of your service + complies to those constraints. - ```php - addAPIClass('YourApiClassNameHere'); // repeat for more + ```yaml - $r->addAuthenticationClass('CustomAuth'); //Add Authentication classes as needed + ... - $r->handle(); //serve the response + parameters: + - name: token + in: formData + description: oauth2 token + type: string + format: byte + pattern: "[A-Za-z0-9]*" + minLength: 5 + maxLength: 100 + required: true + ... ``` - ### 7. Start Production - - - By default Restler runs in debug mode more fine tuned for API developer, by showing detailed error messages and - - prettifying the api result to human readbale form - - - By turning on production mode you will gain some performance boost as it will cache the routes (comment parsing happens - - only once instead of every api call), few other files and avoid giving out debug information - - - ```php - - *Note:-* When production mode is set to `true` it always uses the cache and does not detect - - > changes and new routes if any. Your continuous integration pipeline or your git hook should delete - - > this file during the deployment process. Alternatively you can pass second parameter to restler - - > constructor to refresh the cache when changes need to be applied. - - Change Log - - ---------- - - - ### Restler 5 + The `state` parameter is of type string, is not required and has no default value. + It is also only allowed to have a state of length between 1 and 110, otherwise it won't pass validation. - * Semantic versioning to move forward + For the demo purposes, let's change it's type to `integer` and make it required. - * Support for PHP 8 - * Corrects the source path to be outside the vendor directory + As the parameter is required now, the `default` value cannot be present. The `maxLength` and `maxLength` validations - * Adds php development server support with `composer serve` command. + are not allowed for integer parameters, therefore let's replace them with `minimum` and `maximum` values: + + ```yaml - * Ability to run the tests with `composer test` command after running the server - with `composer serve` in another window. + ... + get: + parameters: + - name: state + in: query + description: Any application state to be forwarded back to the frontend + type: integer + format: int32 + required: true + minimum: 2000 + maximum: 2100 + ... - ### Restler 3.0 RC6 + ``` - #### What's new + As we just changed the parameter type, refreshing Swagger UI will, in addition to generating validations - * Adds PassThrough class to serve files outside your web root, including secure downloads + for that parameter type, also force a regeneration of the model consistent with the validation. - * Adds Explorer class (v1 swagger 1.2 spec, and v2 swagger 2.0 spec) as a potential - replacement to Resources class (swagger 1.1 spec) - * Explorer comes bundled with the html, css, and assets. So that you need not manually download and configure it - * Explorer combines the parameters that are expected in the request body to create a unique model for swagger - * Since Restler Explorer comes bundled, you can map to it to your url of choice. - For example `$restler->addAPIClass("Luracast/Restler/Explorer", 'swagger')` maps it to `/swagger`. - * Explorer metadata can be easily customized with ExplorerInfo class + That's nice, but note that it will break the current implementation of the controller class, as the - #### Improvements + implementation of the `postAction` expects `state` to be of type `String`. - * Routes class improved to provide a findAll method to list all the routes for a specific version of the API excluding - the specified paths and http methods. - * The magic properties utilized by routes when found, ignoring actual properties. - This is useful for Dynamic Model classes such as Eloquent. - * Routes now allow `@required` and `@properties` to be arrays when the parameter is an object. - This helps us to pick and choose the properties for each api method differently. - Example `{@properties property1,property2,property3}` `{@required property1,property2}` makes an api to only look for - 3 properties and 2 of them are required. + ![Validation screenshot](/docs/validations-01.png) - * Optimized the Nav class. It now makes use of `Routes::findAll()`, along with Explorer class - * Restler class has setBaseUrls method to set acceptable base urls that can be set using `$_SERVER['HTTP_HOST']`. - Read [this article](http://shiflett.org/blog/2006/mar/server-name-versus-http-host) to understand why. This is useful - in the following cases when - * PHP has trouble detecting the port correctly - * multiple domains are pointing to the same server + Let's change the implementation. The second parameter `state` is no longer - * Restler class now allows overriding the status code by setting `$this->restler->responseCode` from the api method. - - * Improved Forms class to send the embedded properties to emmet template. For example - - - ``` - - /** - * {@id form1} - * - * @param string $name - * @param int $age - */ - - ``` - - Generates the following form - -
- # Swagger CLI Client - - - Generates a command-line interface for any - - [Swagger Specification](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md) so you can do things like: - - - ![Example usage](https://i.imgur.com/IVhxFlE.png) - - - ## Usage - - This intended to be embedded within a wrapper application which can provide it the schema object (which is generated using [fetch-swagger-schema](https://github.com/signalfx/fetch-swagger-schema)). For example, here's the petstore-cli file: - - - ```javascript - - #!/usr/bin/env node - - - var swaggerCli = require('../'), - schema = require('./petstore-schema.json'); - - swaggerCli(schema); - - ``` - - - To create a cli app for your schema, just require your schema instead of the petstore schema. - - - ## Auth lookup strategy - - By default the cli will first use the `--auth` param (if defined), then it'll use the `_AUTH` (e.g., PETSTORECLI_AUTH) env variable (if defined), and finally a yaml/json file called `.` (e.g. ~/.petstore-cli which may contain "`auth: MY_TOKEN`"). - - - ## Overriding the base path - - You can override your api base path via the same lookup strategy as auth keys, this is useful for testing and development. Pass in `--basePathOverride ` or defined a `_BASE_PATH` or a `basePath` key-value pair in the `.` config file. -concentricsky/django-tastypie-swagger: > - ![Concentric - Sky](https://concentricsky.com/media/uploads/images/csky_logo.jpg) - - - ## Django Tastypie Swagger - - - **django-tastypie-swagger** is a small adapter library to construct [Swagger](http://swagger.wordnik.com/) documentation from [Tastypie](https://django-tastypie.readthedocs.org) resources. - - - This package provides two things: - - - 1. An embedded instance of [Swagger UI](https://github.com/wordnik/swagger-ui) to point a URL to. - - 2. Automatic [Resource Listing](https://github.com/wordnik/swagger-core/wiki/Resource-Listing) and [API Declaration](https://github.com/wordnik/swagger-core/wiki/API-Declaration) generation that is consumed by #1 - - - - ### Table of Contents - - - [Version History](#version-history) - - - [Documentation](#documentation) - - - [Installation](#installation) - - - [Getting Started](#getting-started) - - - [Contributors](#contributors) - - - [License](#license) - - - [About Concentric Sky](#about-concentric-sky) - - - - ## Version History - - - - v0.1.3 Various bug fixes and documentation updates - - - v0.1.2 Fixes for Django 1.5 compatibility - - - v0.1.1 Public codebase was released - - - - ## Documentation - - - Detailed documentation is available on [Read The Docs](http://django-tastypie-swagger.readthedocs.org/en/latest/). - - - - ## Installation - - - Install package:: - - pip install django-tastypie-swagger - - Add to INSTALLED_APPS:: - - INSTALLED_APPS = [ - ... - - 'tastypie_swagger', - - ... - ] - - - ## Getting Started - - - Enable documentation for an api endpoint by adding a URL to your urlpatterns. - - - eg:: - - - urlpatterns = patterns('', - ... - - url(r'api/myapi/doc/', - include('tastypie_swagger.urls', namespace='myapi_tastypie_swagger'), - kwargs={"tastypie_api_module":"myapp.registration.my_api", "namespace":"myapi_tastypie_swagger"} - ), - - ... - ) - - - To declare more than one endpoint, repeat the above URL definition and change the namespace. - - - Swagger documentation will be served up at the URL(s) you configured. - - - - ## Contributors - - - Contributors to this project are listed in the CONTRIBUTORS.md file. If you contribute to this project, please add your name to the file. - - - - ## License - - - This project is licensed under the Apache License, Version 2.0. Details can be found in the LICENSE.md file. License for third-party code is available in 3RDPARTYLICENSES.md. - - - - ## About Concentric Sky - - - _For nearly a decade, Concentric Sky has been building technology solutions that impact people everywhere. We work in the mobile, enterprise and web application spaces. Our team, based in Eugene Oregon, loves to solve complex problems. Concentric Sky believes in contributing back to our community and one of the ways we do that is by open sourcing our code on GitHub. Contact Concentric Sky at hello@concentricsky.com._ -fliptoo/swagger-express: > - {swagger-express} - - ========= - - - [Swagger](https://developers.helloreverb.com/swagger/) is a specification and complete framework - - implementation for describing, producing, consuming, and visualizing RESTful web services. - - View [demo](http://petstore.swagger.wordnik.com/). - - - __{swagger-express}__ is a simple and clean solution to integrate swagger with express. - - - ## Installation - - $ npm install -g swagger-express - - ## Quick Start - - - Configure {swagger-express} as express middleware. - - - - `apiVersion` -> Your api version. - - - `swaggerVersion` -> Swagger version. - - - `swaggerUI` -> Where is your swagger-ui? - - - `swaggerURL` -> Path to use for swagger ui web interface. - - - `swaggerJSON` -> Path to use for swagger ui JSON. - - - `basePath` -> The basePath for swagger.js - - - `info` -> [Metadata][info] about the API - - - `apis` -> Define your api array. - - - `middleware` -> Function before response. - - - ``` - - var swagger = require('swagger-express'); - - - app.configure(function(){ - ... - app.use(swagger.init(app, { - apiVersion: '1.0', - swaggerVersion: '1.0', - swaggerURL: '/swagger', - swaggerJSON: '/api-docs.json', - swaggerUI: './public/swagger/', - basePath: 'http://localhost:3000', - info: { - title: 'swagger-express sample app', - description: 'Swagger + Express = {swagger-express}' - }, - apis: ['./api.js', './api.yml'], - middleware: function(req, res){} - })); - app.use(app.router); - ... - }); - - ``` - - - [info]: https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#513-info-object - - - ## Read from jsdoc - - - Example 'api.js' - - - ```js - - - /** - * @swagger - * resourcePath: /api - * description: All about API - */ - - /** - * @swagger - * path: /login - * operations: - * - httpMethod: POST - * summary: Login with username and password - * notes: Returns a user based on username - * responseClass: User - * nickname: login - * consumes: - * - text/html - * parameters: - * - name: username - * description: Your username - * paramType: query - * required: true - * dataType: string - * - name: password - * description: Your password - * paramType: query - * required: true - * dataType: string - */ - exports.login = function (req, res) { - var user = {}; - user.username = req.param('username'); - user.password = req.param('password'); - res.json(user); - } - - - /** - * @swagger - * models: - * User: - * id: User - * properties: - * username: - * type: String - * password: - * type: String - */ - ``` - - - ## Read from yaml file - - - Example 'api.yml' - - - ```yml - - resourcePath: /api - - description: All about API - - apis: - - - - path: /login - operations: - - - httpMethod: POST - summary: Login with username and password - notes: Returns a user based on username - responseClass: User - nickname: login - consumes: - - text/html - parameters: - - - name: username - dataType: string - paramType: query - required: true - description: Your username - - - name: password - dataType: string - paramType: query - required: true - description: Your password - - models: - User: - id: User - properties: - username: - type: String - password: - type: String - ``` - - - ## Read from jsdoc - - - Example 'api.coffee' - - - ```coffee - - - ### - * @swagger - * resourcePath: /api - * description: All about API - ### - - - ### - * @swagger - * path: /login - * operations: - * - httpMethod: POST - * summary: Login with username and password - * notes: Returns a user based on username - * responseClass: User - * nickname: login - * consumes: - * - text/html - * parameters: - * - name: username - * description: Your username - * paramType: query - * required: true - * dataType: string - * - name: password - * description: Your password - * paramType: query - * required: true - * dataType: string - ### - - - ### - * @swagger - * models: - * User: - * id: User - * properties: - * username: - * type: String - * password: - * type: String - ### - - ``` - - - - ## Examples - - - Clone the {swagger-express} repo, then install the dev dependencies: - - $ git clone git://github.com/fliptoo/swagger-express.git --depth 1 - $ cd swagger-express - $ npm install - - and run the example: - - $ cd example - $ node app.js - - - # Credits - - - - [Express](https://github.com/visionmedia/express) - - - [swagger-jack](https://github.com/feugy/swagger-jack) - - - ## License - - - (The MIT License) - - - Copyright (c) 2013 Fliptoo <fliptoo.studio@gmail.com> - - - Permission is hereby granted, free of charge, to any person obtaining - - a copy of this software and associated documentation files (the - - 'Software'), to deal in the Software without restriction, including - - without limitation the rights to use, copy, modify, merge, publish, - - distribute, sublicense, and/or sell copies of the Software, and to - - permit persons to whom the Software is furnished to do so, subject to - - the following conditions: - - - The above copyright notice and this permission notice shall be - - included in all copies or substantial portions of the Software. - - - THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -KevM/fubumvc-swagger: "FubuMVC Swagger\r - - ===============\r - - \r - - This project helps your [FubuMVC](https://github.com/DarthFubuMVC/fubumvc) - web application\r - - \ generate API documentation via [Swagger](http://swagger.wordnik.com/).\r - - \ \r - - [![swagger - demo](https://github.com/KevM/fubumvc-swagger/raw/gh-pages/images/hellofubusw\ - agger.png)](http://fubuswagger.apphb.com/)\r - - \r - - See our [Hello Swagger](http://fubuswagger.apphb.com/) live demo.\r - - \r - - ### How do I get it? ###\r - - \r - - We have a [nuget package](https://nuget.org/packages/FubuMVC.Swagger) - available.\r - - \r - - ```PM> Install-Package FubuMVC.Swagger```\r - - \r - - #### Building Swagger\r - - \r - - To build just run rake grabbing the albacore gem if you don't already have - it. \r - - \r - - ```rb\r - - gem install albacore\r - - rake\r - - ```\r - - \r - - ### How do I put this in my peanut butter?\r - - \r - - **Note:** This should all be simplified when I find the time to figure out - Fubu Bottles. \r - - \r - - Your API documented should support content negitiation and be grouped under - the route **/api**. Take a look at the - [HelloSwagger](https://github.com/KevM/fubumvc-swagger/tree/master/src/HelloS\ - wagger) for examples. \r - - \r - - #### Checklist\r - - \r - - Add a reference to this project. Why not [use - nuget](https://nuget.org/packages/FubuMVC.Swagger)!\r - - \r - - Add the following to your FubuRegistry:\r - - \r - - ```cs\r - - ApplyConvention();\r - - Services(s=> s.AddService());\r - - ```\r - - \r - - Copy the swagger-ui directory into your **/content** direcotry.\r - - \r - - Launch your web app and take a look at the **/api** to see if it is - working.\r - - \r - - ### What does this convention do?\r - - \r - - Three routes will be added to your application:\r - - \r - - ```html\r - - GET /api\r - - ```\r - - This route serves up the Swagger-UI page currently embedded into - FubuSwagger. _This part needs work._\r - - \r - - ```html\r - - GET /api/resources.json\r - - ```\r - - Swagger UI does some resource discovery and uses the output of this route to - find all of the API groups in your project. \r - - \r - - ```html\r - - GET /api/{GroupKey}.json\r - - ```\r - - Details of each API group present in your app. \r - - \r - - Pointing a Swagger UI web site at ```http://localhost:port/api/``` should - render pretty API documentation for your web application.\r - - \r - - ### Why do I not see documentation for my actions?\r - - \r - - Make sure the actions you wish to document are enabled for \"Conneg\"\r - - \r - - In this example I have two marker interfaces which are used to mark input - models on actions which will be APIs. \r - - \r - - ```cs\r - - graph.Behaviors\r - - \ .Where(x => x.InputType().CanBeCastTo() || - x.InputType().CanBeCastTo())\r - - \ .Each(x => x.MakeAsymmetricJson());\r - - ```\r - - \r - - This example will force the result of these actions to be JSON. Note: This - configuration is working around a bug in FubuMVC where normal browser usage - will return XML for Conneg enabled endpoints. :( \r - - \r - - Better yet take a look at the - [HelloSwagger](https://github.com/KevM/fubumvc-swagger/tree/master/src/HelloS\ - wagger) demo application and see how it is wired up and organized.\r - - \r - - ### How do I add more detail to my APIs\r - - \r - - You can use data annotations to mark up your input models and their - properties.\r - - \r - - ```cs\r - - [Description(\"Workflow object history\")]\r - - public class HistoryRequest : IApi \r - - {\r - - \ [Required, Description(\"Type of workflow object. Typically this is - 'case'.\")]\r - - \ [AllowableValues(\"case\", \"subcase\", \"solution\", \"\")]\r - - \ public string Type { get; set; }\r - - \ [Required, Description(\"Id of the workflow object.\")]\r - - \ public string Id { get; set; }\r - - \r - - \ [Description(\"Limit the amout of history returned the given number of - days. When this parameter is not specified. All history items will be - returned.\")]\r - - \tpublic int DaysOfHistory { get; set; }\r - - }\r - - ```" -ServiceStack/ServiceStack: > - Follow - [@ServiceStack](https://twitter.com/servicestack) or [view the - docs](https://docs.servicestack.net), use - [StackOverflow](http://stackoverflow.com/questions/ask) or the [Customer - Forums](https://forums.servicestack.net/) for support. - - - > View the [Release Notes](https://docs.servicestack.net/release-notes-history) for latest features or see [servicestack.net/features](https://servicestack.net/features) for an overview. - - - ### Simple, Fast, Versatile and full-featured Services Framework - - - ServiceStack is a simple, fast, versatile and highly-productive full-featured [Web](http://razor.servicestack.net) and - - [Web Services](https://docs.servicestack.net/web-services.html) Framework that's - - thoughtfully-architected to [reduce artificial complexity](https://docs.servicestack.net/why-not-odata.html#why-not-complexity) and promote - - [remote services best-practices](https://docs.servicestack.net/advantages-of-message-based-web-services.html) - - with a [message-based design](https://docs.servicestack.net/what-is-a-message-based-web-service.html) - - that allows for maximum re-use that can leverage an integrated - - [Service Gateway](https://docs.servicestack.net/service-gateway.html) - - for the creation of loosely-coupled - - [Modularized Service](https://docs.servicestack.net/modularizing-services.html) Architectures. - - ServiceStack Services are consumable via an array of built-in fast data formats (inc. - - [JSON](https://github.com/ServiceStack/ServiceStack.Text), - - XML, - - [CSV](https://docs.servicestack.net/csv-format.html), - - [JSV](https://docs.servicestack.net/json-jsv-and-xml.html), - - [ProtoBuf](https://docs.servicestack.net/protobuf-format.html), - - [Wire](https://docs.servicestack.net/wire-format.html) and - - [MsgPack](https://docs.servicestack.net/messagepack-format.html)) - - as well as XSD/WSDL for [SOAP endpoints](https://docs.servicestack.net/soap-support.html) and - - [Rabbit MQ](https://docs.servicestack.net/rabbit-mq.html), - - [Redis MQ](https://docs.servicestack.net/messaging-and-redis.html) and - - [Amazon SQS](https://github.com/ServiceStack/ServiceStack.Aws#sqsmqserver) MQ hosts. - - - Its design and simplicity focus offers an unparalleled suite of productivity features that can be declaratively enabled - - without code, from creating fully queryable Web API's with just a single Typed Request DTO with - - [Auto Query](https://docs.servicestack.net/autoquery.html) supporting - - [every major RDBMS](https://github.com/ServiceStack/ServiceStack.OrmLite#8-flavours-of-ormlite-is-on-nuget) - - to the built-in support for - - [Auto Batched Requests](https://docs.servicestack.net/auto-batched-requests.html) - - or effortlessly enabling rich [HTTP Caching](https://docs.servicestack.net/http-caching.html) and - - [Encrypted Messaging](https://docs.servicestack.net/encrypted-messaging.html) - - for all your existing services via [Plugins](https://docs.servicestack.net/plugins.html). - - - Your same Services also serve as the Controller in ServiceStack's [Smart Razor Views](http://razor.servicestack.net/) - - reducing the effort to serve both - - [Web and Single Page Apps](https://github.com/ServiceStackApps/LiveDemos) as well as - - [Rich Desktop and Mobile Clients](https://github.com/ServiceStackApps/HelloMobile) that are able to deliver instant interactive - - experiences using ServiceStack's real-time [Server Events](https://docs.servicestack.net/server-events.html). - - - ServiceStack Services also maximize productivity for consumers providing an - - [instant end-to-end typed API without code-gen](https://docs.servicestack.net/csharp-client.html) enabling - - the most productive development experience for developing .NET to .NET Web Services. - - - ### [Generate Instant Typed APIs from within all Major IDEs!](https://docs.servicestack.net/add-servicestack-reference.html) - - - ServiceStack now integrates with all Major IDE's used for creating the best native experiences on the most popular platforms - - to enable a highly productive dev workflow for consuming Web Services, making ServiceStack the ideal back-end choice for powering - - rich, native iPhone and iPad Apps on iOS with Swift, Mobile and Tablet Apps on the Android platform with Java, OSX Desktop Applications - - as well as targeting the most popular .NET PCL platforms including Xamarin.iOS, Xamarin.Android, Windows Store, WPF, WinForms and Silverlight: - - - - - - #### [VS.NET integration with ServiceStackVS](https://visualstudiogallery.msdn.microsoft.com/5bd40817-0986-444d-a77d-482e43a48da7) - - - Providing instant Native Typed API's for - - [C#](https://docs.servicestack.net/csharp-add-servicestack-reference.html), - - [TypeScript](https://docs.servicestack.net/typescript-add-servicestack-reference.html), - - [F#](https://docs.servicestack.net/fsharp-add-servicestack-reference.html) and - - [VB.NET](https://docs.servicestack.net/vbnet-add-servicestack-reference.html) - - directly in Visual Studio for the - - [most popular .NET platforms](https://github.com/ServiceStackApps/HelloMobile) including iOS and Android using - - [Xamarin.iOS](https://github.com/ServiceStackApps/HelloMobile#xamarinios-client) and - - [Xamarin.Android](https://github.com/ServiceStackApps/HelloMobile#xamarinandroid-client) on Windows. - - - #### [Xamarin Studio integration with ServiceStackXS](https://docs.servicestack.net/csharp-add-servicestack-reference.html#xamarin-studio) - - - Providing [C# Native Types](https://docs.servicestack.net/csharp-add-servicestack-reference.html) - - support for developing iOS and Android mobile Apps using - - [Xamarin.iOS](https://github.com/ServiceStackApps/HelloMobile#xamarinios-client) and - - [Xamarin.Android](https://github.com/ServiceStackApps/HelloMobile#xamarinandroid-client) with - - [Xamarin Studio](https://www.xamarin.com/studio) on OSX. The **ServiceStackXS** plugin also provides a rich web service - - development experience developing Client applications with - - [Mono Develop on Linux](https://docs.servicestack.net/csharp-add-servicestack-reference.html#xamarin-studio-for-linux) - - - #### [Xcode integration with ServiceStackXC Plugin](https://docs.servicestack.net/swift-add-servicestack-reference.html) - - - Providing [an instant Native Typed API in Swift](https://docs.servicestack.net/swift-add-servicestack-reference.html) - - including generic Service Clients enabling a highly-productive workflow and effortless consumption of Web Services from - - native iOS and OSX Applications - directly from within Xcode! - - - #### [Android Studio integration with ServiceStackIDEA](https://docs.servicestack.net/java-add-servicestack-reference.html) - - - Providing [an instant Native Typed API in Java](https://docs.servicestack.net/java-add-servicestack-reference.html) - - and [Kotlin](https://docs.servicestack.net/kotlin-add-servicestack-reference.html) - - including idiomatic Java Generic Service Clients supporting Sync and Async Requests by leveraging Android's AsyncTasks to enable the creation of services-rich and responsive native Java or Kotlin Mobile Apps on the Android platform - directly from within Android Studio! - - - #### [IntelliJ integration with ServiceStackIDEA](https://docs.servicestack.net/java-add-servicestack-reference.html#install-servicestack-idea-from-the-plugin-repository) - - - The ServiceStack IDEA plugin is installable directly from IntelliJ's Plugin repository and enables seamless integration with IntelliJ Java Maven projects for generating a Typed API to quickly and effortlessly consume remote ServiceStack Web Services from pure cross-platform Java or Kotlin Clients. - - - #### [Eclipse integration with ServiceStackEclipse](https://github.com/ServiceStack/ServiceStack.Java/tree/master/src/ServiceStackEclipse#eclipse-integration-with-servicestack) - - - The unmatched productivity offered by [Java Add ServiceStack Reference](https://docs.servicestack.net/java-add-servicestack-reference.html) is also available in the - - [ServiceStackEclipse IDE Plugin](https://github.com/ServiceStack/ServiceStack.Java/tree/master/src/ServiceStackEclipse#eclipse-integration-with-servicestack) that's installable - - from the [Eclipse MarketPlace](https://marketplace.eclipse.org/content/servicestackeclipse) to provide deep integration of Add ServiceStack Reference with Eclipse Java Maven Projects - - enabling Java Developers to effortlessly Add and Update the references of their evolving remote ServiceStack Web Services. - - - #### [servicestack-cli - Simple command-line utilities for ServiceStack](https://docs.servicestack.net/add-servicestack-reference.html#simple-command-line-utilities-for-servicestack) - - - In addition to our growing list of supported IDE's, the [servicestack-cli](https://github.com/ServiceStack/servicestack-cli) - - cross-platform command-line npm scripts makes it easy for build servers, automated tasks and command-line runners of your - - favorite text editors to easily Add and Update ServiceStack References! - - - ## Simple Customer Database REST Services Example - - - This example is also available as a [stand-alone integration test](https://github.com/ServiceStack/ServiceStack/blob/master/tests/ServiceStack.WebHost.Endpoints.Tests/CustomerRestExample.cs): - - - ```csharp - - //Web Service Host Configuration - - public class AppHost : AppSelfHostBase - - { - public AppHost() - : base("Customer REST Example", typeof(CustomerService).Assembly) {} - - public override void Configure(Container container) - { - //Register which RDBMS provider to use - container.Register(c => - new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider)); - - using (var db = container.Resolve().Open()) - { - //Create the Customer POCO table if it doesn't already exist - db.CreateTableIfNotExists(); - } - } - } - - - //Web Service DTO's - - [Route("/customers", "GET")] - - public class GetCustomers : IReturn {} - - - public class GetCustomersResponse - - { - public List Results { get; set; } - } - - - [Route("/customers/{Id}", "GET")] - - public class GetCustomer : IReturn - - { - public int Id { get; set; } - } - - - [Route("/customers", "POST")] - - public class CreateCustomer : IReturn - - { - public string Name { get; set; } - } - - - [Route("/customers/{Id}", "PUT")] - - public class UpdateCustomer : IReturn - - { - public int Id { get; set; } - - public string Name { get; set; } - } - - - [Route("/customers/{Id}", "DELETE")] - - public class DeleteCustomer : IReturnVoid - - { - public int Id { get; set; } - } - - - // POCO DB Model - - public class Customer - - { - [AutoIncrement] - public int Id { get; set; } - - public string Name { get; set; } - } - - - //Web Services Implementation - - public class CustomerService : Service - - { - public object Get(GetCustomers request) - { - return new GetCustomersResponse { Results = Db.Select() }; - } - - public object Get(GetCustomer request) - { - return Db.SingleById(request.Id); - } - - public object Post(CreateCustomer request) - { - var customer = new Customer { Name = request.Name }; - Db.Save(customer); - return customer; - } - - public object Put(UpdateCustomer request) - { - var customer = Db.SingleById(request.Id); - if (customer == null) - throw HttpError.NotFound("Customer '{0}' does not exist".Fmt(request.Id)); - - customer.Name = request.Name; - Db.Update(customer); - - return customer; - } - - public void Delete(DeleteCustomer request) - { - Db.DeleteById(request.Id); - } - } - - - ``` - - - ### [Calling the above REST Service from any C#/.NET Client](https://docs.servicestack.net/csharp-add-servicestack-reference.html) - - - > No code-gen required, can re-use above Server DTOs: - - - ```csharp - - var client = new JsonServiceClient(BaseUri); - - - //GET /customers - - var all = client.Get(new GetCustomers()); // Count = 0 - - - //POST /customers - - var customer = client.Post(new CreateCustomer { Name = "Foo" }); - - - //GET /customer/1 - - customer = client.Get(new GetCustomer { Id = customer.Id }); // Name = Foo - - - //GET /customers - - all = client.Get(new GetCustomers()); // Count = 1 - - - //PUT /customers/1 - - customer = client.Put( - new UpdateCustomer { Id = customer.Id, Name = "Bar" }); // Name = Bar - - //DELETE /customers/1 - - client.Delete(new DeleteCustomer { Id = customer.Id }); - - - //GET /customers - - all = client.Get(new GetCustomers()); // Count = 0 - - ``` - - - Same code also works with [Android, iOS, Xamarin.Forms, UWP and WPF clients](https://github.com/ServiceStackApps/HelloMobile). - - - > [F#](https://docs.servicestack.net/fsharp-add-servicestack-reference.html) and - - [VB.NET](https://docs.servicestack.net/vbnet-add-servicestack-reference.html) can re-use same - - [.NET Service Clients](https://docs.servicestack.net/csharp-client.html) and DTO's - - - ### [Calling from TypeScript](https://docs.servicestack.net/typescript-add-servicestack-reference.html#ideal-typed-message-based-api) - - - ```ts - - const client = new JsonServiceClient(baseUrl); - - const { results } = await client.get(new GetCustomers()); - - ``` - - - ### [Calling from Swift](https://docs.servicestack.net/swift-add-servicestack-reference.html#jsonserviceclientswift) - - - ```swift - - let client = JsonServiceClient(baseUrl: BaseUri) - - - client.getAsync(GetCustomers()) - .then { - let results = $0.results; - } - ``` - - - ### [Calling from Java](https://docs.servicestack.net/java-add-servicestack-reference.html#jsonserviceclient-usage) - - - ```java - - JsonServiceClient client = new JsonServiceClient(BaseUri); - - - GetCustomersResponse response = client.get(new GetCustomers()); - - List results = response.results; - - ``` - - - ### [Calling from Kotlin](https://docs.servicestack.net/kotlin-add-servicestack-reference.html#jsonserviceclient-usage) - - - ```kotlin - - val client = JsonServiceClient(BaseUri) - - - val response = client.get(GetCustomers()) - - val results = response.results - - ``` - - - ### [Calling from Dart](https://docs.servicestack.net/dart-add-servicestack-reference) - - - ```dart - - var client = new JsonServiceClient(BaseUri); - - - var response = await client.get(GetCustomers()); - - var results = client.results; - - ``` - - - ### [Calling from jQuery using TypeScript Definitions](https://docs.servicestack.net/typescript-add-servicestack-reference.html#typescript-interface-definitions) - - - ```js - - $.getJSON($.ss.createUrl("/customers", request), request, (r: GetCustomersResponse) => { - var results = r.results; - }); - - ``` - - - Using TypeScript Definitions with Angular HTTP Client: - - - ```ts - - this.http.get(createUrl('/customers', request)).subscribe(r => { - this.results = r.results; - }); - - ``` - - - ### Calling from jQuery - - - ```js - - $.getJSON(baseUri + "/customers", function(r) { - var results = r.results; - }); - - ``` - - - That's all the application code required to create and consume a simple database-enabled REST Web Service! - - - ## Getting Started - - * [Start with the **Getting Started** section](https://docs.servicestack.net/create-your-first-webservice.html) - * [Example Apps and Demos](https://github.com/ServiceStackApps/LiveDemos) - * [Community resources](https://docs.servicestack.net/community-resources.html) - - ### [Release Notes](https://servicestack.net/release-notes) - - - ## Download - - - If you have [NuGet](http://www.nuget.org/) installed, the easiest way to get started is to: - - - ### [Install ServiceStack via NuGet](https://servicestack.net/download). - - - _Latest v4+ on NuGet is a [commercial release](https://servicestack.net/pricing) with [free quotas](https://servicestack.net/download#free-quotas)._ - - - ### [Docs and Downloads for older v3 BSD releases](https://github.com/ServiceStackV3/ServiceStackV3) - - - ### [Live Demos](https://github.com/ServiceStackApps/LiveDemos) - - - **The [Definitive list of Example Projects, Use-Cases, Demos, Starter Templates](https://github.com/ServiceStackApps/LiveDemos)** - - ## Copying - - - Since September 2013, ServiceStack source code is available under GNU Affero General Public License/FOSS License Exception, see license.txt in the source. - - Alternative commercial licensing is also available, see https://servicestack.net/pricing for details. - - - ## Contributing - - - Contributors need to approve the [Contributor License Agreement](https://docs.google.com/forms/d/16Op0fmKaqYtxGL4sg7w_g-cXXyCoWjzppgkuqzOeKyk/viewform) before any code will be reviewed, see the [Contributing docs](https://docs.servicestack.net/contributing.html) for more details. All contributions must include tests verifying the desired behavior. - - - ## OSS Libraries used - - - ServiceStack includes source code of the great libraries below for some of its core functionality. - - Each library is released under its respective licence: - - - [Mono](https://github.com/mono/mono) [(MIT License)](https://github.com/mono/mono/blob/master/LICENSE) - - [Funq IOC](http://funq.codeplex.com) [(MS-PL License)](https://opensource.org/licenses/MS-PL) - - [Fluent Validation](https://github.com/JeremySkinner/FluentValidation) [(Apache License 2.0)](https://github.com/JeremySkinner/FluentValidation/blob/master/License.txt) - - [Mini Profiler](https://github.com/MiniProfiler/dotnet) [(MIT License)](https://github.com/MiniProfiler/dotnet/blob/master/LICENSE.txt) - - [Dapper](https://github.com/StackExchange/Dapper) [(Apache License 2.0)](http://www.apache.org/licenses/LICENSE-2.0) - - [TweetStation's OAuth library](https://github.com/migueldeicaza/TweetStation) [(MIT License)](https://github.com/migueldeicaza/TweetStation/blob/master/LICENSE) - - [MarkdownSharp](https://code.google.com/archive/p/markdownsharp) [(MIT License)](https://opensource.org/licenses/mit-license.php) - - [MarkdownDeep](https://github.com/toptensoftware/markdowndeep) [(Apache License 2.0)](http://www.toptensoftware.com/markdowndeep/license) - - [HtmlCompressor](https://code.google.com/archive/p/htmlcompressor) [(Apache License 2.0)](http://www.apache.org/licenses/LICENSE-2.0) - - [JSMin](https://github.com/douglascrockford/JSMin/blob/master/jsmin.c) [(Apache License 2.0)](http://www.apache.org/licenses/LICENSE-2.0) - - [RecyclableMemoryStream](https://github.com/Microsoft/Microsoft.IO.RecyclableMemoryStream) [(MIT License)](https://github.com/Microsoft/Microsoft.IO.RecyclableMemoryStream/blob/master/LICENSE) - - [ASP.NET MVC](https://github.com/aspnet/Mvc) [(Apache License 2.0)](https://github.com/aspnet/Mvc/blob/release/2.2/LICENSE.txt) - - [CoreFX](https://github.com/dotnet/corefx) [(MIT License)](https://github.com/dotnet/corefx/blob/master/LICENSE.TXT) - - [Nito.AsyncEx](https://github.com/StephenCleary/AsyncEx) [(MIT License)](https://github.com/StephenCleary/AsyncEx/blob/master/LICENSE) - - ## Find out More - - - Follow [@ServiceStack](https://twitter.com/ServiceStack) and - - [+ServiceStack](https://plus.google.com/u/0/communities/112445368900682590445) for project updates. - - - ----- - - - ## Core Team - - - [mythz](https://github.com/mythz) (Demis Bellot) - - [layoric](https://github.com/layoric) (Darren Reid) / [@layoric](https://twitter.com/layoric) - - [xplicit](https://github.com/xplicit) (Sergey Zhukov) / [@quantumcalc](https://twitter.com/quantumcalc) - - [desunit](https://github.com/desunit) (Sergey Bogdanov) / [@desunit](https://twitter.com/desunit) - - [arxisos](https://github.com/arxisos) (Steffen Müller) / [@arxisos](https://twitter.com/arxisos) - - ## Contributors - - - A big thanks to GitHub and all of ServiceStack's contributors: - - - [bman654](https://github.com/bman654) (Brandon Wallace) - - [iristyle](https://github.com/iristyle) (Ethan Brown) - - [superlogical](https://github.com/superlogical) (Jake Scott) - - [itamar82](https://github.com/itamar82) - - [chadwackerman](https://github.com/chadwackerman) - - [derfsplat](https://github.com/derfsplat) - - [johnacarruthers](https://github.com/johnacarruthers) (John Carruthers) - - [mvitorino](https://github.com/mvitorino) (Miguel Vitorino) - - [bsiegel](https://github.com/bsiegel) (Brandon Siegel) - - [mdavid](https://github.com/mdavid) (M. David Peterson) - - [lhaussknecht](https://github.com/lhaussknecht) (Louis Haussknecht) - - [grendello](https://github.com/grendello) (Marek Habersack) - - [SteveDunn](https://github.com/SteveDunn) (Steve Dunn) - - [kcherenkov](https://github.com/kcherenkov) (Konstantin Cherenkov) - - [timryan](https://github.com/timryan) (Tim Ryan) - - [letssellsomebananas](https://github.com/letssellsomebananas) (Tymek Majewski) - - [danbarua](https://github.com/danbarua) (Dan Barua) - - [JonCanning](https://github.com/JonCanning) (Jon Canning) - - [paegun](https://github.com/paegun) (James Gorlick) - - [pvasek](https://github.com/pvasek) (pvasek) - - [derfsplat](https://github.com/derfsplat) (derfsplat) - - [justinrolston](https://github.com/justinrolston) (Justin Rolston) - - [danmiser](https://github.com/danmiser) (Dan Miser) - - [danatkinson](https://github.com/danatkinson) (Dan Atkinson) - - [brainless83](https://github.com/brainless83) (Thomas Grassauer) - - [angelcolmenares](https://github.com/angelcolmenares) (angel colmenares) - - [dbeattie71](https://github.com/dbeattie71) (Derek Beattie) - - [danielwertheim](https://github.com/danielwertheim) (Daniel Wertheim) - - [greghroberts](https://github.com/greghroberts) (Gregh Roberts) - - [int03](https://github.com/int03) (Selim Selçuk) - - [andidog](https://github.com/AndiDog) (AndiDog) - - [chuckb](https://github.com/chuckb) (chuckb) - - [niemyjski](https://github.com/niemyjski) (Blake Niemyjski) - - [mj1856](https://github.com/mj1856) (Matt Johnson) - - [matthieugd](https://github.com/matthieugd) (Matthieu) - - [tomaszkubacki](https://github.com/tomaszkubacki) (Tomasz Kubacki) - - [e11137](https://github.com/e11137) (Rogelio Canedo) - - [davidroth](https://github.com/davidroth) (David Roth) - - [meebey](https://github.com/meebey) (Mirco Bauer) - - [codedemonuk](https://github.com/codedemonuk) (Pervez Choudhury) - - [jrosskopf](https://github.com/jrosskopf) (Joachim Rosskopf) - - [friism](https://github.com/friism) (Michael Friis) - - [mp3125](https://github.com/mp3125) - - [aurimas86](https://github.com/aurimas86) - - [parnham](https://github.com/parnham) (Dan Parnham) - - [yeurch](https://github.com/yeurch) (Richard Fawcett) - - [damianh](https://github.com/damianh) (Damian Hickey) - - [freeman](https://github.com/freeman) (Michel Rasschaert) - - [kvervo](https://github.com/kvervo) (Kvervo) - - [pauldbau](https://github.com/pauldbau) (Paul Du Bois) - - [justinpihony](https://github.com/JustinPihony) (Justin Pihony) - - [bokmadsen](https://github.com/bokmadsen) (Bo Kingo Damgaard) - - [dragan](https://github.com/dragan) (Dale Ragan) - - [sneal](https://github.com/sneal) (Shawn Neal) - - [johnsheehan](https://github.com/johnsheehan) (John Sheehan) - - [jschlicht](https://github.com/jschlicht) (Jared Schlicht) - - [kumarnitin](https://github.com/kumarnitin) (Nitin Kumar) - - [davidchristiansen](https://github.com/davidchristiansen) (David Christiansen) - - [paulecoyote](https://github.com/paulecoyote) (Paul Evans) - - [kongo2002](https://github.com/kongo2002) (Gregor Uhlenheuer) - - [brannonking](https://github.com/brannonking) (Brannon King) - - [alexandrerocco](https://github.com/alexandrerocco) (Alexandre Rocco) - - [cbarbara](https://github.com/cbarbara) - - [assaframan](https://github.com/assaframan) (Assaf Raman) - - [csakshaug](https://github.com/csakshaug) (Christian Sakshaug) - - [johnman](https://github.com/johnman) - - [jarroda](https://github.com/jarroda) - - [ssboisen](https://github.com/ssboisen) (Simon Skov Boisen) - - [paulduran](https://github.com/paulduran) (Paul Duran) - - [pruiz](https://github.com/pruiz) (Pablo Ruiz García) - - [fantasticjamieburns](https://github.com/fantasticjamieburns) - - [pseabury](https://github.com/pseabury) - - [kevingessner](https://github.com/kevingessner) (Kevin Gessner) - - [iskomorokh](https://github.com/iskomorokh) (Igor Skomorokh) - - [royjacobs](https://github.com/royjacobs) (Roy Jacobs) - - [robertmircea](https://github.com/robertmircea) (Robert Mircea) - - [markswiatek](https://github.com/markswiatek) (Mark Swiatek) - - [flq](https://github.com/flq) (Frank Quednau) - - [ashd](https://github.com/ashd) (Ash D) - - [thanhhh](https://github.com/thanhhh) - - [algra](https://github.com/algra) (Alexey Gravanov) - - [jimschubert](https://github.com/jimschubert) (Jim Schubert) - - [gkathire](https://github.com/gkathire) - - [mikaelwaltersson](https://github.com/mikaelwaltersson) (Mikael Waltersson) - - [asunar](https://github.com/asunar) (Alper) - - [chucksavage](https://github.com/chucksavage) (Chuck Savage) - - [sashagit](https://github.com/sashagit) (Sasha) - - [froyke](https://github.com/froyke) (Froyke) - - [dbhobbs](https://github.com/dbhobbs) (Daniel Hobbs) - - [bculberson](https://github.com/bculberson) (Brad Culberson) - - [awr](https://github.com/awr) (Andrew) - - [pingvinen](https://github.com/pingvinen) (Patrick) - - [citndev](https://github.com/CITnDev) (Sebastien Curutchet) - - [cyberprune](https://github.com/cyberprune) - - [jorbor](https://github.com/jorbor) (Jordan Hayashi) - - [bojanv55](https://github.com/bojanv55) - - [i-e-b](https://github.com/i-e-b) (Iain Ballard) - - [pietervp](https://github.com/pietervp) (Pieter Van Parys) - - [franklinwise](https://github.com/franklinwise) - - [ckasabula](https://github.com/ckasabula) (Chuck Kasabula) - - [dortzur](https://github.com/dortzur) (Dor Tzur) - - [allenarthurgay](https://github.com/allenarthurgay) (Allen Gay) - - [viceberg](https://github.com/vIceBerg) - - [vansha](https://github.com/vansha) (Ivan Korneliuk) - - [aaronlerch](https://github.com/aaronlerch) (Aaron Lerch) - - [glikoz](https://github.com/glikoz) - - [danielcrenna](https://github.com/danielcrenna) (Daniel Crenna) - - [stevegraygh](https://github.com/stevegraygh) (Steve Graygh) - - [jrmitch120](https://github.com/jrmitch120) (Jeff Mitchell) - - [manuelnelson](https://github.com/manuelnelson) (Manuel Nelson) - - [babcca](https://github.com/babcca) (Petr Babicka) - - [jgeurts](https://github.com/jgeurts) (Jim Geurts) - - [driis](https://github.com/driis) (Dennis Riis) - - [gshackles](https://github.com/gshackles) (Greg Shackles) - - [jsonmez](https://github.com/jsonmez) (John Sonmez) - - [dchurchland](https://github.com/dchurchland) (David Churchland) - - [softwx](https://github.com/softwx) (Steve Hatchett) - - [ggeurts](https://github.com/ggeurts) (Gerke Geurts) - - [andrewrissing](https://github.com/AndrewRissing) (Andrew Rissing) - - [jjavery](https://github.com/jjavery) (James Javery) - - [suremaker](https://github.com/suremaker) (Wojtek) - - [cheesebaron](https://github.com/cheesebaron) (Tomasz Cielecki) - - [mikkelfish](https://github.com/mikkelfish) (Mikkel Fishman) - - [johngibb](https://github.com/johngibb) (John Gibb) - - [stabbylambda](https://github.com/stabbylambda) (David Stone) - - [mikepugh](https://github.com/mikepugh) (Mike Pugh) - - [permalmberg](https://github.com/permalmberg) (Per Malmberg) - - [adamralph](https://github.com/adamralph) (Adam Ralph) - - [shamsulamry](https://github.com/shamsulamry) (Shamsul Amry) - - [peterlazzarino](https://github.com/peterlazzarino) (Peter Lazzarino) - - [kevin-montrose](https://github.com/kevin-montrose) (Kevin Montrose) - - [msarchet](https://github.com/msarchet) (Michael Sarchet) - - [jeffgabhart](https://github.com/jeffgabhart) (Jeff Gabhart) - - [pkudinov](https://github.com/pkudinov) (Pavel Kudinov) - - [permalmberg](https://github.com/permalmberg) (Per Malmberg) - - [namman](https://github.com/namman) (Nick Miller) - - [leon-andria](https://github.com/leon-andria) (Leon Andria) - - [kkolstad](https://github.com/kkolstad) (Kenneth Kolstad) - - [electricshaman](https://github.com/electricshaman) (Jeff Smith) - - [ecgan](https://github.com/ecgan) (Gan Eng Chin) - - [its-tyson](https://github.com/its-tyson) (Tyson Stolarski) - - [tischlda](https://github.com/tischlda) (David Tischler) - - [connectassist](https://github.com/connectassist) (Carl Healy) - - [starteleport](https://github.com/starteleport) - - [jfoshee](https://github.com/jfoshee) (Jacob Foshee) - - [nardin](https://github.com/nardin) (Mamaev Michail) - - [cliffstill](https://github.com/cliffstill) - - [somya](https://github.com/somya) (Somya Jain) - - [thinkbeforecoding](https://github.com/thinkbeforecoding) (Jérémie Chassaing) - - [paksys](https://github.com/paksys) (Khalil Ahmad) - - [mcguinness](https://github.com/mcguinness) (Karl McGuinness) - - [jpasichnyk](https://github.com/jpasichnyk) (Jesse Pasichnyk) - - [waynebrantley](https://github.com/waynebrantley) (Wayne Brantley) - - [dcartoon](https://github.com/dcartoon) (Dan Cartoon) - - [alexvodovoz](https://github.com/alexvodovoz) (Alex Vodovoz) - - [jluchiji](https://github.com/jluchiji) (Denis Luchkin-Zhou) - - [grexican](https://github.com/grexican) - - [akoslukacs](https://github.com/akoslukacs) (Ákos Lukács) - - [medianick](https://github.com/medianick) (Nick Jones) - - [arhoads76](https://github.com/arhoads76) - - [dylanvdmerwe](https://github.com/dylanvdmerwe) (Dylan v.d Merwe) - - [mattiasw2](https://github.com/mattiasw2) (Mattias) - - [paultyng](https://github.com/paultyng) (Paul Tyng) - - [h2oman](https://github.com/h2oman) (Jason Waterman) - - [anewton](https://github.com/anewton) (Allen Newton) - - [sami1971](https://github.com/sami1971) - - [russellchadwick](https://github.com/russellchadwick) (Russell Chadwick) - - [cyberzed](https://github.com/cyberzed) (Stefan Daugaard Poulsen) - - [filipw](https://github.com/filipw) (Filip Wojcieszyn) - - [ghuntley](https://github.com/ghuntley) (Geoffrey Huntley) - - [baramuse](https://github.com/baramuse) - - [pdegenhardt](https://github.com/pdegenhardt) (Phil Degenhardt) - - [captncraig](https://github.com/captncraig) (Craig Peterson) - - [abattery](https://github.com/abattery) (Jae sung Chung) - - [biliktamas79](https://github.com/biliktamas79) - - [garuma](https://github.com/garuma) (Jérémie Laval) - - [dsimunic](https://github.com/dsimunic) - - [adamfowleruk](https://github.com/adamfowleruk) (Adam Fowler) - - [bfriesen](https://github.com/bfriesen) (Brian Friesen) - - [roryf](https://github.com/roryf) (Rory Fitzpatrick) - - [stefandevo](https://github.com/stefandevo) - - [gdassac](https://github.com/gdassac) - - [metal10k](https://github.com/metal10k) - - [cmelgarejo](https://github.com/cmelgarejo) - - [skaman](https://github.com/skaman) - - [rossipedia](https://github.com/rossipedia) (Bryan J. Ross) - - [wimatihomer](https://github.com/wimatihomer) (Wim Pool) - - [sword-breaker](https://github.com/sword-breaker) - - [adebisi-fa](https://github.com/adebisi-fa) (Adebisi Foluso A.) - - [mbischoff](https://github.com/mbischoff) (M. Bischoff) - - [ivanfioravanti](https://github.com/ivanfioravanti) (Ivan Fioravanti) - - [inhibition](https://github.com/inhibition) (Keith Hassen) - - [joshearl](https://github.com/joshearl) (Josh Earl) - - [friism](https://github.com/friism) (Michael Friis) - - [corkupine](https://github.com/corkupine) - - [bchavez](https://github.com/bchavez) (Brian Chavez) - - [nhhagen](https://github.com/nhhagen) (Niels Henrik Hagen) - - [daggmano](https://github.com/daggmano) (Darren Oster) - - [chappoo](https://github.com/chappoo) (Steve Chapman) - - [julrichkieffer](https://github.com/julrichkieffer) (Julrich Kieffer) - - [adamclarsen](https://github.com/adamclarsen) (Adam Larsen) - - [joero74](https://github.com/joero74) (Joerg Rosenkranz) - - [ddotlic](https://github.com/ddotlic) (Drazen Dotlic) - - [chrismcv](https://github.com/chrismcv) (Chris McVittie) - - [marcioalthmann](https://github.com/marcioalthmann) (Márcio Fábio Althmann) - - [mmertsock](https://github.com/mmertsock) (Mike Mertsock) - - [johnkamau](https://github.com/johnkamau) (John Kamau) - - [uhaciogullari](https://github.com/uhaciogullari) (Ufuk Hacıoğulları) - - [davybrion](https://github.com/davybrion) (Davy Brion) - - [aleshi](https://github.com/aleshi) (Alexander Shiryaev) - - [alexandryz](https://github.com/alexandryz) (Alexandr Zaozerskiy) - - [mistobaan](https://github.com/mistobaan) (Fabrizio Milo) - - [niemyjski](https://github.com/niemyjski) (Blake Niemyjski) - - [alexandernyquist](https://github.com/alexandernyquist) (Alexander Nyquist) - - [mcduck76](https://github.com/mcduck76) - - [kojoru](https://github.com/kojoru) - - [jeremy-bridges](https://github.com/jeremy-bridges) (Jeremy Bridges) - - [andreabalducci](https://github.com/andreabalducci) (Andrea Balducci) - - [robertthegrey](https://github.com/RobertTheGrey) (Robert Greyling) - - [robertbeal](https://github.com/robertbeal) (Robert Beal) - - [improvedk](https://github.com/improvedk) (Mark Rasmussen) - - [foresterh](https://github.com/foresterh) (Jamie Houston) - - [peterkahl](https://github.com/peterkahl) (Peter Kahl) - - [helgel](https://github.com/helgel) - - [anthonycarl](https://github.com/anthonycarl) (Anthony Carl) - - [mrjul](https://github.com/mrjul) (Julien Lebosquain) - - [pwhe23](https://github.com/pwhe23) (Paul Wheeler) - - [aleksd](https://github.com/aleksd) - - [miketrebilcock](https://github.com/miketrebilcock) (Mike Trebilcock) - - [markwoodhall](https://github.com/markwoodhall) (Mark Woodhall) - - [theonlylawislove](https://github.com/theonlylawislove) (Paul Knopf) - - [callumvass](https://github.com/callumvass) (Callum Vass) - - [bpruitt-goddard](https://github.com/bpruitt-goddard) - - [gregpakes](https://github.com/gregpakes) (Greg Pakes) - - [caspiancanuck](https://github.com/caspiancanuck) (Caspian Canuck) - - [merwer](https://github.com/merwer) - - [pavelsavara](https://github.com/pavelsavara) (Pavel Savara) - - [markwalls](https://github.com/markwalls) (Mark Walls) - - [prasannavl](https://github.com/prasannavl) (Prasanna Loganathar) - - [wilfrem](https://github.com/wilfrem) - - [emiba](https://github.com/emiba) - - [lucky-ly](https://github.com/lucky-ly) (Dmitry Svechnikov) - - [hhandoko](https://github.com/hhandoko) (Herdy Handoko) - - [datawingsoftware](https://github.com/datawingsoftware) - - [tal952](https://github.com/tal952) - - [bretternst](https://github.com/bretternst) - - [kevinhoward](https://github.com/kevinhoward) (Kevin Howard) - - [mattbutton](https://github.com/mattbutton) (Matt Button) - - [torbenrahbekkoch](https://github.com/torbenrahbekkoch) (Torben Rahbek Koch) - - [pilotmartin](https://github.com/pilotmartin) (Pilot Martin) - - [catlion](https://github.com/catlion) - - [tstade](https://github.com/tstade) (Toft Stade) - - [niltz](https://github.com/niltz) (Jeff Sawatzky) - - [nhalm](https://github.com/nhalm) - - [fhurta](https://github.com/fhurta) (Filip Hurta) - - [discobanan](https://github.com/discobanan) - - [x-cray](https://github.com/x-cray) - - [jeremistadler](https://github.com/jeremistadler) (Jeremi Stadler) - - [bangbite](https://github.com/bangbite) - - [felipesabino](https://github.com/felipesabino) (Felipe Sabino) - - [xelom](https://github.com/xelom) (Arıl Bozoluk) - - [shiweichuan](https://github.com/shiweichuan) (Weichuan Shi) - - [kojoru](https://github.com/kojoru) (Konstantin Yakushev) - - [eddiegroves](https://github.com/eddiegroves) (Eddie Groves) - - [fetters5](https://github.com/fetters5) - - [rcollette](https://github.com/rcollette) (Richard Collette) - - [urihendler](https://github.com/urihendler) (Uri Hendler) - - [laurencee](https://github.com/laurencee) (Laurence Evans) - - [m-andrew-albright](https://github.com/m-andrew-albright) (Andrew Albright) - - [lee337](https://github.com/lee337) (Lee Venkatsamy) - - [kaza](https://github.com/kaza) - - [mishfit](https://github.com/mishfit) - - [rfvgyhn](https://github.com/rfvgyhn) (Chris) - - [augustoproiete](https://github.com/augustoproiete) (C. Augusto Proiete) - - [sjuxax](https://github.com/sjuxax) (Jeff Cook) - - [madaleno](https://github.com/madaleno) (Luis Madaleno) - - [yavosh](https://github.com/yavosh) (Yavor Shahpasov) - - [fvoncina](https://github.com/fvoncina) (Facundo Voncina) - - [devrios](https://github.com/devrios) (Dev Rios) - - [bfkelsey](https://github.com/bfkelsey) (Ben Kelsey) - - [maksimenko](https://github.com/maksimenko) - - [dixon](https://github.com/dixon) (Jarrod Dixon) - - [kal](https://github.com/kal) (Kal Ahmed) - - [mhanney](https://github.com/mhanney) (Michael Hanney) - - [bcms](https://github.com/bcms) - - [mgravell](https://github.com/mgravell) (Marc Gravell) - - [lafama](https://github.com/lafama) (Denis Ndwiga) - - [jamesgroat](https://github.com/jamesgroat) (James Groat) - - [jamesearl](https://github.com/jamesearl) (James Cunningham) - - [remkoboschker](https://github.com/remkoboschker) (Remko Boschker) - - [shelakel](https://github.com/shelakel) - - [schmidt4brains](https://github.com/schmidt4brains) (Doug Schmidt) - - [joplaal](https://github.com/joplaal) - - [aifdsc](https://github.com/aifdsc) (Stephan Desmoulin) - - [nicklarsen](https://github.com/nicklarsen) (NickLarsen) - - [connectassist](https://github.com/connectassist) (Carl Healy) - - [et1975](https://github.com/et1975) (Eugene Tolmachev) - - [barambani](https://github.com/barambani) - - [nhalm](https://github.com/et1975) - - - *** - - - ## Similar open source projects - - - Similar Open source .NET projects for developing or accessing web services include: - - * [Nancy Fx](http://nancyfx.org) - A Sinatra-inspired lightweight Web Framework for .NET: - * [Fubu MVC](https://fubumvc.github.io/) - A "Front Controller" pattern-style MVC framework designed for use in web applications built on ASP.NET: - * [Rest Sharp](http://restsharp.org) - An open source REST client for .NET -rahulsom/swaggydoc: > - [![Build - Status](https://travis-ci.org/rahulsom/swaggydoc.svg?branch=develop)](https://travis-ci.org/rahulsom/swaggydoc) - - - ![Unmaintained](https://img.shields.io/badge/status-unmaintained-yellow.svg) This repository is not actively maintained. If you are interested in taking it over, please let me know. - - - ## Documentation - - - User Documentation is at https://rahulsom.github.io/swaggydoc - - - ## Contributing - - - Before you can run any other commands, you will have to obtain the swagger assets. - - - ```bash - - ./bowerize.sh - - ``` - - - Running grails3 plugin in dev mode - - ```bash - - ./gradlew swaggydoc-grails3:bootRun - - ``` - - - Running grails2 plugin in dev mode - - ```bash - - ./gradlew grails2:run - - ``` -glennjones/hapi-swagger: > - # hapi-swagger - - - This is a [OpenAPI (aka Swagger)](https://openapis.org/) plug-in for [Hapi](https://hapi.dev/) When installed it will self document the API interface - - in a project. - - - [![Maintainers Wanted](https://img.shields.io/badge/maintainers-wanted-red.svg?style=for-the-badge)](https://github.com/hapi-swagger/hapi-swagger/issues/718) - - ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/hapi-swagger/hapi-swagger/node.js.yml?style=for-the-badge) - - [![npm downloads](https://img.shields.io/npm/dm/hapi-swagger.svg?style=for-the-badge)](https://www.npmjs.com/package/hapi-swagger) - - [![MIT license](http://img.shields.io/badge/license-MIT-blue.svg?style=for-the-badge)](https://raw.github.com/hapi-swagger/hapi-swagger/master/license.txt) - - - ## Compatibility - - - | Version | [Hapi](https://github.com/hapijs/hapi) | [Joi](https://github.com/sideway/joi) | Node | Release Notes | - - | ------- | -------------------------------------- | ------------------------------------- | ------ | --------------------------------------------------------------- | - - | `16.x` | `>=20.0.0 @hapi/hapi` | `>=17.0.0 joi` | `>=14` | [#795](https://github.com/hapi-swagger/hapi-swagger/issues/795) | - - | `15.x` | `>=20.0.0 @hapi/hapi` | `>=17.0.0 joi` | `>=14` | [#782](https://github.com/hapi-swagger/hapi-swagger/issues/782) | - - | `14.x` | `>=19.0.0 @hapi/hapi` | `>=17.0.0 joi` | `>=12` | [#680](https://github.com/hapi-swagger/hapi-swagger/issues/680) | - - | `13.x` | `>=19.0.0 @hapi/hapi` | `>=17.0.0 @hapi/joi` | `>=12` | [#660](https://github.com/hapi-swagger/hapi-swagger/issues/660) | - - | `12.x` | `>=19.0.0 @hapi/hapi` | `>=17.0.0 @hapi/joi` | `>=12` | [#644](https://github.com/hapi-swagger/hapi-swagger/issues/644) | - - | `11.x` | `>=18.4.0 @hapi/hapi` | `>=16.0.0 @hapi/joi` | `>=8` | [#631](https://github.com/hapi-swagger/hapi-swagger/issues/631) | - - | `10.x` | `>=18.3.1 @hapi/hapi` | `>=14.0.0 @hapi/joi` | `>=8` | [#587](https://github.com/hapi-swagger/hapi-swagger/issues/587) | - - | `9.x` | `>=17 hapi` | `<14.0.0` | `>=8` | [#487](https://github.com/hapi-swagger/hapi-swagger/issues/487) | - - | `7.x` | `<17 hapi` | ??? | ??? | [#325](https://github.com/hapi-swagger/hapi-swagger/issues/325) | - - - ## Installation - - - You can add the module to your Hapi using npm: - - - ```bash - - > npm install hapi-swagger --save - - ``` - - - **hapi-swagger** no longer bundles `joi` to fix [#648](https://github.com/hapi-swagger/hapi-swagger/issues/648). Install **hapi-swagger** with peer dependencies using: - - - ```bash - - npx install-peerdeps hapi-swagger - - ``` - - - If you want to view the documentation from your API you will also need to install the `inert` and `vision` plugs-ins which support templates and static - - content serving. - - - ```bash - - > npm install @hapi/inert --save - - > npm install @hapi/vision --save - - ``` - - - ## Documentation - - - - [Options Reference](optionsreference.md) - - - [Usage Guide](usageguide.md) - - - ## Quick start - - - In your Hapi apps please check the main JavaScript file and add the following code to already created a Hapi `server` object. - - You will also add the routes for you API as describe on [hapi website](https://hapi.dev/). - - - ```Javascript - - const Hapi = require('@hapi/hapi'); - - const Inert = require('@hapi/inert'); - - const Vision = require('@hapi/vision'); - - const HapiSwagger = require('hapi-swagger'); - - const Pack = require('./package'); - - - (async () => { - const server = Hapi.server({ - port: 3000, - host: 'localhost' - }); - - const swaggerOptions = { - info: { - title: 'Test API Documentation', - version: Pack.version, - }, - }; - - await server.register([ - Inert, - Vision, - { - plugin: HapiSwagger, - options: swaggerOptions - } - ]); - - try { - await server.start(); - console.log('Server running at:', server.info.uri); - } catch(err) { - console.log(err); - } - - server.route(Routes); - })(); - - ``` - - - ### Tagging your API routes - - - As a project may be a mixture of web pages and API endpoints you need to tag the routes you wish Swagger to - - document. Simply add the `tags: ['api']` property to the route object for any endpoint you want documenting. - - - You can even specify more tags and then later generate tag-specific documentation. If you specify - - `tags: ['api', 'foo']`, you can later use `/documentation?tags=foo` to load the documentation on the - - HTML page (see next section). - - - ```Javascript - - { - method: 'GET', - path: '/todo/{id}/', - options: { - handler: handlers.getToDo, - description: 'Get todo', - notes: 'Returns a todo item by the id passed in the path', - tags: ['api'], // ADD THIS TAG - validate: { - params: Joi.object({ - id : Joi.number() - .required() - .description('the id for the todo item'), - }) - } - }, - } - - ``` - - - Once you have tagged your routes start the application. **The plugin adds a page into your site with the route `/documentation`**, - - so the the full URL for the above options would be `http://localhost:3000/documentation`. - - - ### Typescript - - - **hapi-swagger** exports its own typescript definition file that can be used when registering the plugin with **Hapi**. See example below: - - - #### Install Typescript Definition Files - - - ```sh - - npm i @types/hapi__hapi @types/hapi__inert @types/hapi__joi @types/hapi__vision @types/node hapi-swagger --save-dev - - ``` - - - #### Register Plugin with Typescript - - - ```typescript - - import * as Hapi from '@hapi/hapi'; - - import * as HapiSwagger from 'hapi-swagger'; - - - // code omitted for brevity - - - const swaggerOptions: HapiSwagger.RegisterOptions = { - info: { - title: 'Test API Documentation' - } - }; - - - const plugins: Array> = [ - { - plugin: Inert - }, - { - plugin: Vision - }, - { - plugin: HapiSwagger, - options: swaggerOptions - } - ]; - - - await server.register(plugins); - - ``` - - - ## Contributing - - - Read the [contributing guidelines](./.github/CONTRIBUTING.md) for details. - - - ## Thanks - - - I would like to thank all that have contributed to the project over the last couple of years. This is a hard project to maintain, getting Hapi to work with Swagger is like putting a round plug in a square hole. Without the help of others it would not be possible. -stemey/gform-admin: >+ - #admin-gform - - - admin-gform is a generic client application to administrate data and invoke services. - - - [live demo](http://www.toobop.net/gform-admin) - - - ### Data administration - - - admin-gform generates master detail views to browse, create, update and delete entities via restful services. - - The ui consists of a table for browsing resource documents and a form to edit a single resource. Both table and - - form are created according to the resource's schema. This schema must be supplied in either json schema or gform schema format. - - - - - ### Service invokation - - - admin-gform is a [swagger](http://swagger.wordnik.com) client. It actually exceeds the default swagger ui's features by providing a complete form for - - posting and putting new or changed resources. - - - Limitations: - - - * does not support file upload - - - - ## Installation - - - to install and run the build app use: - - git clone https://github.com/stemey/gform-admin - bower install - grunt build - grunt server dist - open browser at localhost:3333 - - to run the dev app use: - - grunt server - open browser at localhost:3333 - - - ## Configuration - - - The configuration contains the default swagger and gform services to connect to. It is a json file located at /src/app/services.json: - - - { - "services": [ - { - "type": "app/service/BaucisCrudService", - "name": "blog (crud)", - "url": "http://localhost:3333/api/gform" - - }, - { - "type": "app/service/SwaggerMetaService", - "name": "swagger example", - "url": "http://localhost/source/gform-admin-new/src/app/wordnik/api" - - } - ] - } - - - A service has a name displayed in the menu, a url of the service's api and a type. The type defines how to interpret the api - as swagger or gform api. - - - ## Gform-Rest-Api - - - The schemata to create the generic front end is provided through rest services. It works similar to the swagger api, The Api consists of two calls: - - - ### 1. Listing of available resources - - - The main service call returns general meta data of all resources. A resource meta data consists of a name and urls to the schema, the resource and optionally the collection. - - These urls must be absolute or relative to the provided basePath or the url of the listing itself. - - - { - "basePath": "http://localhost:3333/api/", - "resources": [ - { - "name": "vegetable" - "schemaUrl": "./gform/vegetables", - "resourceUrl": "./vegetables/", - "collectionUrl": "./vegetables/", - } - ] - } - - ### 2. The schemata - - - All referenced schema may reference external schemas relative to the basePath as well. - - - - ## Libraries and examples - - - ### Live example - - - [gform-admin](http://www.toobop.net/gform-admin) provides access to swagger example application and crud operations on BlogPost and User data in lcoalstorage. - - - ### Mongoose - - - A complete implementation of the gform rest api for [mongoose](http://www.github.com/Learnboost/mongoose) is available [here](http://www.github.com/stemey/baucis-gform). An example application - - is available [here](http://www.github.com/stemey/mongoose-administration-example) - - - -mac-/ratify: >+ - ratify - - ====== - - - A Hapi plugin for validating the schema of path, query, request body, and response body params using [JSON-schema](http://json-schema.org/), while providing documenation for your end points via [Swagger](https://helloreverb.com/developers/swagger) - - - [![Build Status](https://secure.travis-ci.org/mac-/ratify.png)](http://travis-ci.org/mac-/ratify) - - [![Coverage Status](https://coveralls.io/repos/mac-/ratify/badge.png)](https://coveralls.io/r/mac-/ratify) - - [![Code Climate](https://codeclimate.com/github/mac-/ratify.png)](https://codeclimate.com/github/mac-/ratify) - - [![NPM version](https://badge.fury.io/js/ratify.png)](http://badge.fury.io/js/ratify) - - [![Dependency Status](https://david-dm.org/mac-/ratify.png)](https://david-dm.org/mac-/ratify) - - - [![NPM](https://nodei.co/npm/ratify.png?downloads=true&stars=true)](https://nodei.co/npm/ratify/) - - - ## Contributing - - - This module makes use of a `Makefile` for building/testing purposes. After obtaining a copy of the repo, run the following commands to make sure everything is in working condition before you start your work: - - make install - make test - - Before committing a change to your fork/branch, run the following commands to make sure nothing is broken: - - make test - make test-cov - - Don't forget to bump the version in the `package.json` using the [semver](http://semver.org/spec/v2.0.0.html) spec as a guide for which part to bump. Submit a pull request when your work is complete. - - - ***Notes:*** - - * Please do your best to ensure the code coverage does not drop. If new unit tests are required to maintain the same level of coverage, please include those in your pull request. - - * Please follow the same coding/formatting practices that have been established in the module. - - - ## Installation - - npm install ratify - - ## Usage - - - To install this plugin on your Hapi server, do something similar to this: - - var Hapi = require('hapi'); - var server = new Hapi.Server(); - - var ratifyOptions = {}; - - server.register({ register: require('ratify'), options: ratifyOptions }, function(err) { - if (err) { - console.log('error', 'Failed loading plugin: ratify'); - } - }); - - ## Plugin Options - - - ### `auth` - - - Used to add authentication to the swagger routes that get created by the plugin. Valid values are described [here](https://github.com/spumko/hapi/blob/master/docs/Reference.md#route-options) under the `auth` property. - - - Defaults to `false` - - - ### `baseUrl` - - - The protocol, hostname, and port where the application is running. - - - Defaults to `'http://localhost'` - - - ### `startingPath` - - - The path at which all of the swagger routes begin at. This is the endpoint you would pass to an instance of the swagger UI. - - - Defaults to `'/api-docs'` - - - ### `apiVersion` - - - The version of your API. - - - Defaults to `''` - - - ### `responseContentTypes` - - - A collection of valid response types returned by your services. - - - Defaults to `['application/json']` - - - ### `swaggerHooks` - - - An object in which the property names represent swagger generated elements and the values must be functions to be invoked to customize how those elements are processed. - - - Possible values: - - * `params`: `function(params, route, type)` - - * `operation`: `function(operation, route, resourceType, path)` - - * `routeNameGroup`: `function(route)` - - - ### `errorReporters` - - - An object in which the property keys represent elements that can be validated (`"headers"`, `"query"`, `"path"`, `"payload"`, `"response"`) and the values are initialized [ZSchemaErrors instances](https://github.com/dschenkelman/z-schema-errors) to be used to report those errors. - - - ### Parameter Validation - - - Once your server is set to use ratify, you can specify route-specific validations in each route config like so: - - var route = { - method: 'GET', - path: '/foo/{bar}', - config: { - handler: function(request, reply) { - - }, - plugins: { - ratify: { - path: { - // path parameters schema - }, - query: { - // query parameters schema - }, - headers: { - // header parameters schema - }, - payload: { - // request payload schema - }, - response: { - schema: { - // response payload schema - }, - sample: 100, // percentage of responses to test against the schema - failAction: 'log' // action to take when schena validation fails. Valid options are; 'log' and 'error' - } - - } - } - } - }; - server.route(route); - - All schemas should follow the [JSON schema specification](http://json-schema.org/). - - - ***Notes:*** - - In addition to the JSON schema defined types, ratify allows you to specify "file" as a payload type. If this is specified, no validation against JSON schema is performed, but swagger documentation will still be provided. - - - #### Type Conversion - - - In the process of validating the properties based on the schema, ratify will attempt to convert path, header, and query params to the type defined in the schema. For example, if you have a query paramter called `limit` and it's type is `number`, since all query parameters are parsed as strings by Hapi, ratify will convert the string to a number. - - - Ratify can also specifically convert query parameters that are intended to be arrays. For example, both of the following query strings will result in a property called `types` having an array value: - - - * `?types=first&types=second&types=third` - - * `?types[0]=first&types[2]=third&types[1]=second` - - - Result: - - - ``` - - { - types: ['first', 'second', 'third'] - } - - ``` - - - ### Swagger Documentation - - - Ratify automatically generates routes that produce JSON in the format of the [Swagger API Specification](https://github.com/wordnik/swagger-core). In order to ge tthe most of the documentation, it's best to ensure there are descriptions to all your parameters as allowed by the JSON schema spec. - - - ## Version Compatibility - - - ### Currently compatible with: Hapi 10.x.x (Node v4) - - - * 0.2.x - Hapi 1.x.x - - * 0.3.x - Don't use! - - * 0.4.x - Hapi 4.x.x - - * 0.6.x - Hapi 6.x.x - - * 0.7.x - Hapi 7.x.x - - * 0.8.x - Hapi 8.x.x - - * 0.10.x - Hapi 9.x.x - - * 1.x.x - Hapi 10.x.x (Node v4) - - * 2.x.x - Hapi 11.x.x - - * 3.x.x - Hapi 16.x.x - -marcgibbons/django-rest-swagger: > - # Django REST Swagger: deprecated (2019-06-04) - - - This project is no longer being maintained. Please consider **drf-yasg** as an alternative/successor. I haven't personally used it, but it looks feature-complete and is actively maintained. - - - ### https://github.com/axnsan12/drf-yasg - - - Thanks for all the support and contributions over the years. Special thanks to [Lights on Software](https://lightsonsoftware.com/), [Lincoln Loop](https://lincolnloop.com/) and BNOTIONS for generously donating time to work on this project :heart:. - - - --- - - - [![build-status-badge]][build-status] - - [![codecov](https://codecov.io/gh/marcgibbons/django-rest-swagger/branch/master/graph/badge.svg)](https://codecov.io/gh/marcgibbons/django-rest-swagger) - - [![pypi-version]][pypi] - - - - [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) - - - - #### An API documentation generator for Swagger UI and Django REST Framework - - - Full documentation: http://marcgibbons.github.io/django-rest-swagger/ - - - - ## Installation - - - 1. `pip install django-rest-swagger` - - - 2. Add `rest_framework_swagger` to your `INSTALLED_APPS` setting: - - ```python - INSTALLED_APPS = ( - ... - 'rest_framework_swagger', - ) - ``` - - ## Rendering Swagger Specification and Documentation - - - This package ships with two renderer classes: - - - 1. `OpenAPIRenderer` generates the OpenAPI (fka Swagger) JSON schema specification. This renderer will be presented if: - - `Content-Type: application/openapi+json` is specified in the headers. - - `?format=openapi` is passed as query param - 2. `SwaggerUIRenderer` generates the Swagger UI and requires the `OpenAPIRenderer` - - - - ### Quick Start Example: - - ```python - - from django.conf.urls import url - - from rest_framework_swagger.views import get_swagger_view - - - schema_view = get_swagger_view(title='Pastebin API') - - - urlpatterns = [ - url(r'^$', schema_view) - ] - - ``` - - - ## Requirements - - * Django 1.8+ - - * Django REST framework 3.5.1+ - - * Python 2.7, 3.5, 3.6 - - - - ## Testing - - - - Run `$ tox` to execute the test suite against all supported environments. - - - Run `./runtests.py` to run the test suite within the current environment. - - - ## Bugs & Contributions - - Please report bugs by opening an issue - - - Contributions are welcome and are encouraged! - - - ## Special Thanks - - Many thanks to Tom Christie & all the contributors who have developed [Django REST Framework](http://django-rest-framework.org/) - - - - [build-status-badge]: https://travis-ci.org/marcgibbons/django-rest-swagger.svg?branch=master - - [build-status]: https://travis-ci.org/marcgibbons/django-rest-swagger - - [pypi-version]: https://img.shields.io/pypi/v/django-rest-swagger.svg - - [pypi]: https://pypi.python.org/pypi/django-rest-swagger - - [license]: https://pypi.python.org/pypi/django-rest-swagger/ - - [docs-badge]: https://readthedocs.io/projects/django-rest-swagger/badge/ - - [docs]: http://django-rest-swagger.readthedocs.io/ -signalfx/swagger-client-generator: > - # Swagger Client Generator - - [![Build Status](https://travis-ci.org/signalfx/swagger-client-generator.svg?branch=master)](https://travis-ci.org/signalfx/swagger-client-generator) - - - Generates a client given a requests handler and a [Swagger API Specification](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md) schema (which can be generated with [fetch-swagger-schema](https://github.com/signalfx/fetch-swagger-schema): `npm install -g fetch-swagger-schema; fetch-swagger-schema `). - - - This is intended to be a helper for creating swagger clients by passing in a request handler for the platform being used (e.g., you XHR request handler in browsers, and request in node). It provides [robust client-side validation](https://github.com/signalfx/swagger-validate) according to the API endpoints and converts given data into appropriate url, header, and body information to be consumed by the request handler. - - - ## Example - - ```js - - function requestHandler(error, request){ - if(error) return console.error(error.toString()); - - var xhr = new XMLHttpRequest(); - xhr.open(request.method, request.url) - - if(request.headers){ - Object.keys(request.headers).forEach(function(header){ - xhr.setRequestHeader(header, request.headers[header]); - }); - } - - xhr.onloadend = function(){ - request.options.callback(this.response); - }; - - xhr.send(request.body); - } - - - // assumes that 'schema' already exists in scope and is the schema object for - - // http://petstore.swagger.io/api/api-docs - - var api = swaggerClientGenerator(schema, requestHandler); - - - // for apiKey authorization use: api.auth('my-token') - - // for basicAuth use: api.auth('username', 'password') - - // authorization may be set for any level (api, api.resource, or api.operation) - - - api.pet.getPetById(2, function(response){ - console.log(response); - }); - - ``` - - ## Creating a schema object - - A schema is just a compilation of the Swagger Resource Listing object with each Resource object embedded directly within it. You can fetch one and save it automatically by using [fetch-swagger-schema](https://github.com/signalfx/fetch-swagger-schema): - - ```shell - - # install the fetch-swagger-schema tool - - npm install -g fetch-swagger-schema - - fetch-swagger-schema - - # the generated schema json file will be at - - ``` - - - ## API - - #### `api = swaggerClientGenerator(schemaObject, requestHandler)` - - * *schemaObject* - A json object describing the schema (generally generated by [fetch-swagger-schema](https://github.com/signalfx/fetch-swagger-schema)). - - * *requestHandler* - A function which accepts two parameters `error` and `request`. The error object will be a [ValidationErrors](https://github.com/signalfx/swagger-validate#swaggervalidateerrorsvalidationerrors) object if an validation error occurs, otherwise it will be undefined. The request object is defined below. - - * *api* - An object which can be used as the api for the given schema. The first-level objects are the resources within the schema and the second-level functions are the operations which can be performed on those resources. - - - #### `api.` - - A map of all the resources as defined in the schema to their operation handler (e.g. `api.pet`). - - - #### `requestHandlerResponse = api..(data, options)` - - This is the actual operation handler invoked by the clients (e.g., `api.pet.getPetById`). - - - The operation handler takes two parameters: - - * *data* - A map of the operation data parameters. If the operation only has one parameter, the value may be used directly (i.e. `api.pet.getPetById(1, callback)` is the same as `api.pet.getPetById({petId: 1}, callback)`). - - * *options* - A map of the options to use when calling the operation. This differs based on operation but it may include parameters such as `contentType` or `accept` and it commonly includes options to pass to the request handler (such as a callback function when the request completes). If options is a function, then the `callback` property of options will be a reference to the function for convenience (e.i. `api.pet.getPetById(1, callback)` is the same as `api.pet.getPetById(1, { callback: callback })`. - - - The operation handler processes the data and options, passes the processed `request` data to the `requestHandler` and returns the result of the requestHandler back to the caller. The operation handler does not process the results of the requestHandler before returning it to the caller. - - - #### `url = api...getUrl(data)` - - Intended for advanced use-cases. Returns the URL which would be called if the operation were to be called using this operation handler. The acceptable HTTP method to call this url can be found at `api...operation.method`. - - - #### `requestHandler(error, request)` - - The request handler is the second parameter for the swaggerClientGenerator and will be called whenever an operation is invoked. If there are any validation errors, the errors parameter be a [ValidationErrors](https://github.com/signalfx/swagger-validate#swaggervalidateerrorsvalidationerrors) object describing the validation errors in detail. - - - The request object will have the following properties which should be used to issue the actual HTTP request: - - * *method* - The HTTP method string for the operation - - * *url* - The url string to call for the operation - - * *headers* - A map of the request headers - - * *body* - The body of the request - - * *options* - Options passed in as the second parameter to the operation handler, commonly used for callbacks - - * *operation* - The metadata of the operation being invoked - - * *data* - The raw data used to generate the url, headers, and body - - * *errorTypes* - A map of [all possible error types](https://github.com/signalfx/swagger-validate#swaggervalidateerrorsvalidationerrors) which are used in the error parameter (useful for instanceof checks) - - - ##### `operation` objects - - This object, which is found in either `request.operation` or `api...operation` contains references to the entire schema object: - - * [Operation](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#523-operation-object) - `operation` - - * [API Object](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#522-api-object) - `operation.apiObject` - - * [API Declaration](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#52-api-declaration) - `operation.apiObject.apiDeclaration` - - * [Resource Object](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#512-resource-object) - `operation.apiObject.resourceObject` - - * [Resource Listing](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#51-resource-listing)- `operation.apiObject.resourceObject.resourceListing` - - - ## Developing - - After installing [nodejs](http://nodejs.org) execute the following: - - - ```shell - - git clone https://github.com/signalfx/swagger-ajax-client.git - - cd swagger-ajax-client - - npm install - - npm run dev - - ``` - - The build engine will test and build everything, start a server hosting the `example` folder on [localhost:3000](http://localhost:3000), and watch for any changes and rebuild when nescessary. - - - To generate minified files in `dist`: - - ```shell - - npm run dist - - ``` -solso/source2swagger: >+ - ## Description - - - Coming soon... - - - ## Usage - - - #### Dependencies - - - * Ruby (1.8x or 1.9x) - - * Gem - - * JSON gem (gem install json) - - - #### Parameters - - $ bin/source2swagger - - Usage: source2swagger [options] - -i, --input PATH Directory of the input source code - -e, --ext ("rb"|"c"|"js"|"py") File extension of the source code - -f, --file FILENAME Overwrites options: -i and -e. Takes a single annotated source code file - -c, --comment ("##~"|"//~") Comment tag used to write docs - -o, --output PATH Directory where the json output will be saved (optional) - - #### Example - - $ bin/source2swagger -i ~/project/lib -e "rb" -c "##~" - - This will output the Swagger compatible JSON specs on the terminal. - - - For this example the file annotated with the swagger spec are ruby files (*-e "rb"*). The annotations - - started with *##~* to distinguish them from normal ruby comments that start *#*. - - - The source code is on the directory *~/project/lib* , note that the path is handled recursively, it will analyze all ruby - - file under the declared path. - - - You can also target a single file setting the option *-f* - - $ bin/source2swagger -f ~/data/test/sample3.rb -c "##~" - - - Add *-o /tmp* and it will write the JSON file(s) to */tmp* - - - #### Contributions - - - Feel free to extend the code and issue a pull request, - - - The test suite can be invoked as - - $ rake test - - Requires *rake* and the *gem test/unit* - - - - ## How to - - - Check [test/data/sample3.rb](https://github.com/solso/source2swagger/blob/master/test/data/sample3.rb) for a comprehensive real example of the *source2swagger* inline docs for Ruby. - - - The names of the attributes can be seen on the section Grammar (partially) or better yet in the original [Swagger Specification](http://swagger.wordnik.com/spec). - - - #### API names declaration - - - First you need to declare the API - - ##~ a = source2swagger.namespace("your_api_spec_name") - - This will generate the file your_api_spec_name.json. The name can be declared in multiple files and several times in the same file. Each time *namespace* is invoked it returns the reference to the root element of the API named "your_api_spec_name". - - - #### Setting attributes elements - - - One by one, - - ##~ a.basePath = "http://helloworld.3scale.net" - ##~ a.swaggerVersion = "0.1a" - ##~ a.apiVersion = "1.0" - - or all at the same time, - - ##~ a.set "basePath" => "http://helloworld.3scale.net", "swaggerVersion" => "0.1a", "apiVersion" => "1.0" - - - You can always combine - - ##~ a.set "basePath" => "http://helloworld.3scale.net", "swaggerVersion" => "0.1a" - ##~ a.apiVersion = "1.0" - - #### Adding and element to a list attribute - - ##~ op = a.operations.add - ##~ op.httpMethod = "GET" - ##~ op.tags = ["production"] - ##~ op.nickname = "get_word" - ##~ op.deprecated = false - ##~ - ##~ op = a.operations.add - ##~ op.set :httpMethod => "POST", :tags => ["production"], :nickname => "set_word", :deprecated => false - - - Two elements (*operations*) were added to *a.operations*, you can also add directly if you do not need to have a reference to the variable *op* - - ##~ a.operations.add :httpMethod => "GET", :tags => ["production"], :nickname => "get_word", :deprecated => false - ##~ a.operations.add :httpMethod => "POST", :tags => ["production"], :nickname => "set_word", :deprecated => false - - #### Using variables for common structures - - - The source2swagger notation also allows you to define variables that can be defined anywhere on the source code files as *@name = value*, the value is typically a hash structure in ruby notation (*{"key_1" => "value_1", ... , "key_n" => "value_n"}*) - - - *Note:* all variable declarations are evaluated before the non-variable statements so vars will always available no matter where they are defined. For instance, - - ... - ## in foo.rb - ##~ op.parameters.add @parameter_app_id - ... - ## in bar.rb - ##~ @parameter_app_id = {"name" => "word", "description" => "The word whose sentiment is to be set", "dataType" => "string", "required" => true, "paramType" => "path"} - ... - - - - #### Adding comments - - - You can add comments on the inline docs specification, just use the normal comment tags of your language - - ##~ op = a.operations.add - ## - ## HERE IS MY COMMENT (do not use the comment tag, e.g. ##~ but the comment tag specific of your language, in ruby #) - ## - ##~ op.httpMethod = "GET" - - - - - Check [test/data/sample3.rb](https://github.com/solso/source2swagger/blob/master/test/data/sample3.rb) for a comprehensive real example of the *source2swagger* inline docs for Ruby. - - - - ### Grammar - - - (partial) - - - For a more comprehensive specification of the fields needed to declare your API on the Swagger format you can always go to the [source](http://swagger.wordnik.com/spec) - - $ROOT - - a = source2swagger.namespace(STRING) - - a.basepath = STRING [required, ] - a.swaggerVersion = STRING [] - a.apiVersion = STRING [] - a.apis = LIST[$ENDPOINTS] [required, ] - - a.models = LIST[$MODELS] [] - - $ENDPOINTS - - e = a.apis.add - - e.path = STRING [required, ] - e.format = LIST[STRING] [required, ] - e.description = STRING [required, ] - e.errorResponses = LIST[$ERRORS][] - e.operations = LIST[$OPERATIONS][] - - $OPERATIONS - - o = e.operations.add - - o.httpMethod = STRING [required, ] - o.tags = LIST[STRING] [] - o.nickname = STRING [] - o.deprecated = BOOLEAN [] - o.summary = STRING [] - o.responseClass = STRING [] - o.parameters = LIST[$PARAMETERS][] - - PARAMETERS - - p = o.parameters.add - - p.name = STRING [required] - p.description = STRING [] - p.dataType = STRING [required] - p.allowMultiple = BOOLEAN [] - p.required = BOOLEAN [] - p.paramType = STRING - - ERRORS - - err = e.operations.add - - err.reason = STRING [] - err.code = INT [] - - ## Extra Resources - - - You can edit and view the generated Swagger JSON specs online here: [JSON Editor](http://jsoneditor.appspot.com/) - - - It's pretty basic but it works great for a quick manual inspection and edition - - of the json generated by *source2swagger*. If you know of another online editor - - please let us know. - - - ## License - - - MIT License - - -myfreeweb/octohipster: > - Current [semantic](http://semver.org/) version: - - - ```clojure - - [octohipster "0.2.1-SNAPSHOT"] - - ``` - - - # octohipster [![Build Status](https://travis-ci.org/myfreeweb/octohipster.png?branch=master)](https://travis-ci.org/myfreeweb/octohipster) [![unlicense](https://img.shields.io/badge/un-license-green.svg?style=flat)](http://unlicense.org) - - - Octohipster is - - - - a REST library/toolkit/microframework for Clojure - - - that allows you to build HTTP APIs - - - in a declarative [Webmachine](https://github.com/basho/webmachine/wiki/Overview)-like style, using [Liberator](https://github.com/clojure-liberator/liberator) - - - powered by [Ring](https://github.com/ring-clojure/ring); you can add [rate limiting](https://github.com/myfreeweb/ring-ratelimit), [authentication](https://github.com/cemerick/friend), [metrics](http://metrics-clojure.readthedocs.org/en/latest/ring.html), [URL rewriting](https://github.com/ebaxt/ring-rewrite) and more with just middleware - - - It allows you to make APIs that - - - - support hypermedia ([HAL+JSON](http://stateless.co/hal_specification.html), [Collection+JSON](http://amundsen.com/media-types/collection/) and Link/Link-Template HTTP headers; works with [Frenetic](http://dlindahl.github.com/frenetic/)) - - - support multiple output formats (JSON, EDN, YAML and any custom format) - - - have [Swagger](https://github.com/wordnik/swagger-core/wiki) documentation - - - use [JSON Schema](http://json-schema.org) for validation *and* documentation - - - have pagination - - - ## Concepts - - - - a **resource** is a single endpoint that accepts requests and returns responses - - - a **group** is a collection of resources with a single URL prefix (eg. a group /things contains resources /things/ and /things/{id}) and zero or more shared properties (usually the schema) - - - a **documenter** is a function that returns a resource which documents regular resources (Swagger, HAL root, etc) - - - a **mixin** is a function that is applied to multiple resources to give them shared behavior (eg. collection or entry behavior) - - - a **response handler** is a function that is used to encode response data to a particular content-type (JSON, EDN, YAML, etc.) - - - a **params handler** is a function that is used to decode incoming data from a particular content-type (JSON, EDN, YAML, etc.) - - - ## Usage - - - ```clojure - - (ns example - (:use [octohipster core routes mixins pagination] - [octohipster.documenters swagger schema] - org.httpkit.server) - (:import org.bson.types.ObjectId) - (:require [monger.core :as mg] - [monger.query :as mq] - [monger.collection :as mc] - monger.json)) - - (mg/connect!) - - (mg/set-db! (mg/get-db "octohipster-example")) - - - ;;;; The "model" - - ;;;; tip: make it a separate namespace, eg. app.models.contact - - (def contact-schema - {:id "Contact" - :type "object" - :properties {:name {:type "string"} - :phone {:type "integer"}} - :required [:name]}) - - (defn contacts-count [] (mc/count "contacts")) - - (defn contacts-all [] - (mq/with-collection "contacts" - (mq/find {}) - (mq/skip *skip*) - (mq/limit *limit*))) - (defn contacts-find-by-id [x] (mc/find-map-by-id "contacts" (ObjectId. x))) - - (defn contacts-insert! [x] - (let [id (ObjectId.)] - (mc/insert "contacts" (assoc x :_id id)) - (mc/find-map-by-id "contacts" id))) - (defn contacts-update! [x old] (mc/update "contacts" old x :multi false)) - - (defn contacts-delete! [x] (mc/remove "contacts" x)) - - - ;;;; The resources - - ;; with shared pieces of documentation - - (def name-param - {:name "name", :dataType "string", :paramType "path", :required "true", :description "The name of the contact", :allowMultiple false}) - - (def body-param - {:dataType "Contact", :paramType "body", :required true, :allowMultiple false}) - - (defresource contact-collection - :desc "Operations with multiple contacts" - :mixins [collection-resource] - :clinks {:item ::contact-item} - :data-key :contacts - :exists? (fn [ctx] {:contacts (contacts-all)}) - :post! (fn [ctx] {:item (-> ctx :request :non-query-params contacts-insert!)}) - :count (fn [req] (contacts-count)) - :doc {:get {:nickname "getContacts", :summary "Get all contacts"} - :post {:nickname "createContact", :summary "Create a contact"}}) - - (defresource contact-item - :desc "Operations with individual contacts" - :url "/{_id}" - :mixins [item-resource] - :clinks {:collection ::contact-collection} - :data-key :contact - :exists? (fn [ctx] - (if-let [doc (-> ctx :request :route-params :_id contacts-find-by-id)] - {:contact doc})) - :put! (fn [ctx] - (-> ctx :request :non-query-params (contacts-update! (:contact ctx))) - {:contact (-> ctx :request :route-params :_id contacts-find-by-id)}) - :delete! (fn [ctx] - (-> ctx :contact contacts-delete!) - {:contact nil}) - :doc {:get {:nickname "getContact", :summary "Get a contact", :parameters [name-param]} - :put {:nickname "updateContact", :summary "Overwrite a contact", :parameters [name-param body-param]} - :delete {:nickname "deleteContact", :summary "Delete a contact", :parameters [name-param]}}) - - ;;;; The group - - (defgroup contact-group - :url "/contacts" - :add-to-resources {:schema contact-schema} ; instead of typing the same for all resources in the group - :resources [contact-collection contact-item]) - - ;;;; The handler - - (defroutes site - :groups [contact-group] - :documenters [schema-doc schema-root-doc swagger-doc swagger-root-doc]) - - (defn -main [] (run-server site {:port 8080})) - - ``` - - - Also, [API Documentation](http://myfreeweb.github.com/octohipster) is available. - - - ## Contributing - - - By participating in this project you agree to follow the [Contributor Code of Conduct](http://contributor-covenant.org/version/1/1/0/). - - - Please take over the whole project! - - I don't use Clojure a lot nowadays. - - Talk to me: . - - - ## License - - - This is free and unencumbered software released into the public domain. - - For more information, please refer to the `UNLICENSE` file or [unlicense.org](http://unlicense.org). -gettyimages/spray-swagger: | - ## Use https://github.com/swagger-spray/swagger-spray instead -skrusty/dotswaggen: > - [![Build - Status](https://travis-ci.org/skrusty/dotswaggen.svg?branch=master)](https://travis-ci.org/skrusty/dotswaggen) - - # DotSwagGen - - DotSwagGen is a command line code generator for the swagger specification. It allows you to generate client code for .NET from a simple swagger spec file which defines a REST Api. - - - ## Templates - - DotSwagGen uses a template engine to create code output in any language for a given swagger specification. - - - Currently there are two templates included, a C# Model and a C# Operation template. You can create your own templates for specific requirements or languages. - - - ## Usage - - Usage: dotswaggen -s \ -n test.namespace -o \ - - -s, --swagger Required. Input files to be processed. - - -n, --namespace Required. The namespace to use for generated code - - -o, --output Required. The folder to output rendered code to - - --t-prefix Prefix the template filename for each template type - - --o-prefix Prefix the output filename for each file generated - - --o-single-name The filename to write all output to - - --help Display this help screen. - - ## Swagger Spec Support - - Currently we only support Swagger 1.2. - - 1.1 is planned to arrive soon. -yvasiyarov/swagger: > - - ![alt text]( https://s3.amazonaws.com/tw-chat/attach/579528d6e2f2c2aebfe7f957e4572ca0/1.png "Logo Title Text 1") - - - - ## Swagger UI Generator for Go - - - - - ### About - - - This is a utility for automatically generating API documentation from annotations in Go code. It generates the documentation as JSON, according to the [Swagger Spec](https://github.com/wordnik/swagger-spec), and then displays it using [Swagger UI](https://github.com/swagger-api/swagger-ui). - - - This tool was inspired by [Beego](http://beego.me/docs/advantage/docs.md), and follows the same annotation standards set by Beego. - - The main difference between this tool and Beego is that this generator doesn't depend on the Beego framework. You can use any framework to implement your API (or don't use a framework at all). You just add declarative comments to your API controllers, then run this generator and your documentation is ready! For an example of what such documentation looks like when presented via Swagger UI, see the Swagger [pet store example](http://petstore.swagger.wordnik.com/). - - - This tool focuses on _documentation generation_ as opposed to _client_ generation. If that is all you need, it will be significantly easier to integrate this tool into your existing codebase/workflow as opposed to [goswagger](https://goswagger.io/). One significant advantage of this tool is that it allows you to easily reference objects that are outside of your package. - - - _This tool currently generates Swagger 1.x spec files -- there are plans to update the tool to support Swagger 2.x at some point._ - - - ### Quick Start Guide - - - 1. Add comments to your API source code, [see Declarative Comments Format ](https://github.com/yvasiyarov/swagger/wiki/Declarative-Comments-Format) - - - 2. Download Swagger for Go by using ```go get github.com/yvasiyarov/swagger``` - - - 3. Or, compile the Swagger generator from sources. - `go install` - - This will create a binary in your $GOPATH/bin folder called swagger (Mac/Unix) or swagger.exe (Windows). - - 4. Run the Swagger generator. - Make sure to specify the full package name and an optional entry point (if the entry point isn't `$pkg/main.go`). - - Example: - - ``` - $ pwd - /Users/dselans/Code/go/src/github.com/yvasiyarov/swagger - $ ./$GOPATH/bin/swagger -apiPackage="github.com/yvasiyarov/swagger/example" -mainApiFile=example/web/main.go -output=./API.md -format=markdown - ``` - - - ### Command Line Flags - - | Switch | Description | - - |------------------|---------------------------| - - | **-apiPackage** | Package with API controllers implementation | - - | **-mainApiFile** | Main API file. This file is used for generating the "General API Info" bits. If `-mainApiFile` is not specified, then `$apiPackage/main.go` is assumed. | - - | **-format** | One of: `go\|swagger\|asciidoc\|markdown\|confluence`. Default is `-format="go"`. See See [docs](https://github.com/yvasiyarov/swagger/wiki/Generate-Different-Formats). | - - | **-output** | Output specification. Default varies according to -format. See [docs](https://github.com/yvasiyarov/swagger/wiki/Generate-Different-Formats). | - - | **controllerClass** | Speed up parsing by specifying which receiver objects have the controller methods. The default is to search all methods. The argument can be a regular expression. For example, `-controllerClass="(Context\|Controller)$"` means the receiver name must end in Context or Controller. | - - | **contentsTable** | Whether to generate Table of Contents; default: `true`. | - - | **models** | Generate 'Models' section; default `true`. | - - | **vendoringPath** | Override default vendor directory (eg. `$CWD/vendor` and `$GOPATH/src/$apiPackage/vendor`) | - - | **disableVendoring** | Disable vendor usage altogether | - - | **enableDebug** | Enable debug log output | - - - ### Note on Swagger-UI - - - To run the generated swagger UI (assuming you used -format="go"), copy/move the generated docs.go file to a new folder under GOPATH/src. Also bring in the web.go-example file, renaming it to web.go. Then: `go run web.go docs.go` - - - ### Additional Documentation - - - **Project Status** : [Alpha](https://github.com/yvasiyarov/swagger/wiki/Declarative-Comments-Format) - - - **Declarative Comments Format** : [Read more ](https://github.com/yvasiyarov/swagger/wiki/Declarative-Comments-Format) - - - **Technical Notes** : [Read More](https://github.com/yvasiyarov/swagger/wiki/Technical-Notes) - - - **Known Limitations** : [Read More](https://github.com/yvasiyarov/swagger/wiki/Known-Limitations) - - **Generating Different Format Docs**: [Read More](https://github.com/yvasiyarov/swagger/wiki/Generate-Different-Formats) -SerenaFeng/tornado-swagger: > - # tornado-swagger - - - ## What is tornado-swagger? - - tornado is a wrapper for tornado which enables swagger-ui support. - - - In essense, you just need to wrap the Api instance and add a few python decorators to get full swagger support. - - - ## How to: - - Install: - - - ``` - - pip install . - - ``` - - (This installs tornado and epydoc as well) - - - - And in your program, where you'd usually just use tornado, add just a little bit of sauce and get a swagger spec out. - - - - ```python - - from tornado.web import RequestHandler, HTTPError - - from tornado_swagger import swagger - - - swagger.docs() - - - # You may decorate your operation with @swagger.operation and use docs to inform information - - class ItemNoParamHandler(GenericApiHandler): - @swagger.operation(nickname='create') - def post(self): - """ - @param body: create test results for a item. - @type body: L{Item} - @return 200: item is created. - @raise 400: invalid input - """ - - # Operations not decorated with @swagger.operation do not get added to the swagger docs - - - class ItemNoParamHandler(GenericApiHandler): - def options(self): - """ - I'm not visible in the swagger docs - """ - pass - - - # Then you use swagger.Application instead of tornado.web.Application - - # and do other operations as usual - - - def make_app(): - return swagger.Application([ - (r"/items", ItemNoParamHandler), - (r"/items/([^/]+)", ItemHandler), - (r"/items/([^/]+)/cases/([^/]+)", ItemOptionParamHandler), - ]) - - # You define models like this: - - @swagger.model - - class Item: - """ - @descriptin: - This is an example of a model class that has parameters in its constructor - and the fields in the swagger spec are derived from the parameters to __init__. - @notes: - In this case we would have property1, property2 as required parameters and property3 as optional parameter. - @property property3: Item decription - @ptype property3: L{PropertySubclass} - """ - def __init__(self, property1, property2=None): - self.property1 = property1 - self.property2 = property2 - - # Swagger json: - "models": { - "Item": { - "description": "A description...", - "id": "Item", - "required": [ - "property1", - ], - "properties": [ - "property1": { - "type": "string" - }, - "property2": { - "type": "string" - "default": null - } - ] - } - } - - # If you declare an __init__ method with meaningful arguments - - # then those args could be used to deduce the swagger model fields. - - # just as shown above - - - # if you declare an @property in docs, this property property2 will also be used to deduce the swagger model fields - - class Item: - """ - @property property3: Item description - """ - def __init__(self, property1, property2): - self.property1 = property1 - self.property2 = property2 - - # Swagger json: - "models": { - "Item": { - "description": "A description...", - "id": "Item", - "required": [ - "property1", - ], - "properties": [ - "property1": { - "type": "string" - }, - "property2": { - "type": "string" - } - "property3": { - "type": "string" - } - ] - } - } - - # if you declare an argument with @ptype, the type of this argument will be specified rather than the default 'string' - - class Item: - """ - @ptype property3: L{PropertySubclass} - """ - def __init__(self, property1, property2, property3=None): - self.property1 = property1 - self.property2 = property2 - self.property3 = property3 - - # Swagger json: - "models": { - "Item": { - "description": "A description...", - "id": "Item", - "required": [ - "property1", - ], - "properties": [ - "property1": { - "type": "string" - }, - "property2": { - "type": "string" - }, - "property3": { - "type": "PropertySubclass" - "default": null - } - ] - } - } - - # if you want to declare an list property, you can do it like this: - - class Item: - """ - @ptype property3: L{PropertySubclass} - @ptype property4: C{list} of L{PropertySubclass} - """ - def __init__(self, property1, property2, property3, property4=None): - self.property1 = property1 - self.property2 = property2 - self.property3 = property3 - self.property4 = property4 - - # Swagger json: - "models": { - "Item": { - "description": "A description...", - "id": "Item", - "required": [ - "property1", - ], - "properties": [ - "property1": { - "type": "string" - }, - "property2": { - "type": "string" - }, - "property3": { - "type": "PropertySubclass" - "default": null - }, - "property4": { - "default": null, - "items": { - "type": "PropertySubclass"}, - "type": "array" - } - } - ] - } - } - ``` - - - # Running and testing - - - Now run your tornado app - - - ``` - - python basic.py - - ``` - - - And visit: - - - ``` - - curl http://localhost:7111/swagger/spec - - ``` - - - access to web - - ``` - - http://localhost:7111/swagger/spec.html - - ``` - - - # Passing more metadata to swagger - - customized arguments used in creating the 'swagger.docs' object will be supported later -siemens/restapidoc: "restapidoc [![Build - Status](https://travis-ci.org/siemens/restapidoc.svg?branch=master)](https://\ - travis-ci.org/siemens/restapidoc)\r - - ==========\r - - \r - - This is a RESTful API documentation plugin for the [Grails][Grails] web - application framework.\r - - Very much inspired by [Swagger][Swagger] API documentation, this plugin - reuses the available information of\r - - Grails Domain classes and Controllers to minimize documentation effort and - to improve consistency.\r - - This approach aims to be a deeper and less narrative Grails integration than - the original [Swagger][Swagger] JAX-RS idea. It\r - - * is extending the Grails RestController\r - - * is using Grails HalRenderer\r - - * uses Annotations just for documentation purpose and not for semantic - information\r - - * is as concise as possible\r - - * reuses already some basic annotations from Swagger but\r - - * it is not \"Swagger compatible\" \r - - * Grails 3.0 and above is not supported\r - - \r - - [Grails]: http://grails.org/\r - - [plugins]: http://grails.org/plugins/\r - - [Swagger]: https://github.com/wordnik/swagger-core\r - - \r - - **Current Version 0.1.4**\r - - \r - - ![Grails - restapidoc](https://github.com/siemens/restapidoc/blob/master/screenshot1.png\ - ?raw=true)\r - - \r - - \r - - Quick Start\r - - -----------\r - - * it is recommended to use Grails >= 2.3.7. It is best tested with Grails - 2.4.4. Please install it as required by Grails or use the grailsw wrapper.\r - - * EITHER Use the Binary by adding restapidoc it to your - grails-app/conf/BuildConfig.groovy:\r - - \ ```\r - - \ compile \":restapidoc:0.1.4\"\r - - \ ```\r - - * OR: Download this project by git clone e.g. to directory restapidoc.\r - - \ * cd restapidoc\r - - \ * to test it:\r - - \ ```\r - - \ grails test-app --echoOut\r - - \ ```\r - - \ * The project provides a Grails wrapper, so if you don't have Grails - installed, run the tests with\r - - \ ```\r - - \ grailsw test-app --echoOut\r - - \ ```\r - - \r - - \ * Create a new Grails project parallel to restapidoc. Edit - BuildConfig.groovy, add:\r - - \ ```\r - - \tgrails.plugin.location.'restapidoc'=\"../restapidoc\"\r - - \ ```\r - - \r - - * edit your spring/resources.groovy, add e.g. HalJsonRenderer:\r - - \r - - ```Groovy\r - - \timport grails.rest.render.hal.HalJsonCollectionRenderer\r - - \timport grails.rest.render.hal.HalJsonRenderer\r - - \tbeans = {\r - - \t\thalPCollectionRenderer(HalJsonCollectionRenderer, Pet)\r - - \t\thalPRenderer(HalJsonRenderer, Pet)\r - - \t}\r - - ```\r - - \r - - * add documentation to your Grails Domains e.g.:\r - - \r - - ```Groovy\r - - \timport restapidoc.annotations.ApiDescription\r - - \timport restapidoc.annotations.ApiProperty\r - - \r - - \t@ApiDescription(description = \"Endangered Animals\")\r - - \tclass Pet {\r - - \t\t@ApiProperty(description = \"Binomial name\")\r - - \ \tString name \r - - \t}\r - - ```\r - - \r - - * add documentation to your Grails Controller. If you want some generic - Documentation for RestfulControllers, you can extend - DocumentedRestfulController e.g. here PetController:\r - - \r - - ```Groovy\r - - \timport restapidoc.DocumentedRestfulController\r - - \timport restapidoc.annotations.ApiDescription\r - - \r - - \t@ApiDescription(description=\"Unrealistic shop for endangered animals\")\r - - \tclass PetController extends DocumentedRestfulController {\r - - \t\tstatic responseFormats = ['hal','json']\r - - \t\tPetController() {\r - - \t\t\tsuper(Pet)\r - - \t\t}\r - - \t}\r - - ```\r - - \r - - * start your Grails app and open the Api Controller, e.g. - http://localhost:8080/HalTest/apiBrowse/index\r - - * you can find this sample as fully running Grails Application under - https://github.com/muenchhausen/HalTest\r - - \r - - API Documentation\r - - -----------------\r - - The following Annotations - similar like Swagger - are available:\r - - * ApiIgnore: element will be ignored in documentation\r - - * ApiDescription: used for Domain classes and Controller documentation\r - - * ApiProperty: domain property\r - - * ApiParam: paramter of a controller\r - - * ApiParams: a list of ApiParam\r - - * ApiOperation: controller operation\r - - * ApiResponse: controller operation response\r - - * ApiResponses: List of ApiResponse\r - - * DeleteMethod / GetMethod / PostMethod / PutMethod: marks controller - operation as RESTful CRUD \r - - \r - - \r - - History\r - - -------\r - - * 0.1.4 Grails 2.4.4 tested\r - - * 0.1.3 Grails 2.4.2 tested, issue#4 and issue#5, inherited domain - attributes\r - - * 0.1.2 Grails 2.4.0 support\r - - * 0.1.1 publish binary version of this plugin\r - - * 0.1 initial version\r - - \r - - License\r - - -------\r - - \r - - Copyright (c) Siemens AG, 2013\r - - \r - - This restapidoc plugin is licensed under the terms of the [Apache License, - Version 2.0][Apache License, Version 2.0].\r - - [Apache License, Version 2.0]: - http://www.apache.org/licenses/LICENSE-2.0.html\r\n" -josephpconley/swagger2postman: >- - # swagger2postman - - - [![Join the chat at https://gitter.im/josephpconley/swagger2postman](https://badges.gitter.im/josephpconley/swagger2postman.svg)](https://gitter.im/josephpconley/swagger2postman?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - - Create a Postman collection from Swagger documentation - - - ##Motivation - - - [Swagger UI](https://github.com/swagger-api/swagger-ui) provides a nice way to interact with an API documented by the [Swagger specification](https://github.com/swagger-api/swagger-spec). - - But if you're working with an identical API across multiple environments, or you want to test edge cases that Swagger UI doesn't support - - (like omitting a required query parameter), Swagger UI comes up a bit short. - - - [Postman](https://www.getpostman.com/) to the rescue! Using Postman you can define variables for multiple environments and have more control over request generation. - - - ##Purpose - - This library takes Swagger documentation served in JSON and converts it into a JSON collection which can be imported directly into Postman. - - You can see a full description of the Swagger JSON spec at [http://swagger.io/specification/](http://swagger.io/specification/) - - - ##Command line - - - To convert a Swagger 2.0 JSON file to a valid Postman collection: - - sbt "runMain com.josephpconley.swagger2postman.app.v2.Swagger2PostmanApp [ ... ]" - - To convert a Swagger 1.2 hosted endpoint to a valid Postman collection: - - sbt "runMain com.josephpconley.swagger2postman.app.v12.Swagger2PostmanApp [ ... ]" - - - ##Demo - - - Try out an online version at [http://app.josephpconley.com/swagger2postman](http://app.josephpconley.com/swagger2postman) - - - Or using `curl` to convert a Swagger 2.0 document into a Postman JSON import file: - - curl -X POST --data "@v2petstore-swagger.json" "http://app.josephpconley.com/swagger20?name=my_collection&header_key=header_value" --header "Content-Type:application/json" > my_collection.json - - - ##Multiple environments - - - To take advantage of multi-environment testing, I would first run swagger2postman against a hosted Swagger doc. - - Then I do a simple Find/Replace, replacing the target host with a handlebars variable like `{{host}}`. - - Then I create environments in Postman that define a value for the config key `host`. - - Toggling these environments with your imported collection will let you seamlessly test your API in different environments. - - You can also use environment variables for authentication. If your API uses a header for authentication, then pass a `headerKey`=`{{headerValue}}` - - so that all endpoints get a global authentication header with an environment-dependent value. - - - ##Release Notes - - ### 1.1 - - - Initial support for Swagger 2.0 - - - ### 1.0 - - - Initial support for Swagger 1.2 -wonderlic/swagger-validation: >- - # Validation for swagger-node-express - - - [![Build Status](https://img.shields.io/travis/wonderlic/swagger-validation/master.svg)](https://travis-ci.org/wonderlic/swagger-validation) - - [![NPM version](https://badge.fury.io/js/swagger-validation.svg)](http://badge.fury.io/js/swagger-validation) - - [![Code Climate](https://codeclimate.com/github/wonderlic/swagger-validation/badges/gpa.svg)](https://codeclimate.com/github/wonderlic/swagger-validation) - - - DocumentUp available here: [http://documentup.com/wonderlic/swagger-validation](http://documentup.com/wonderlic/swagger-validation) - - - ## Quick Description - - - #### Validating a request - - This module validates a request from a swagger-node-express application using the existing swagger-node-express objects, - - parameters, and models following the [swagger specification 1.2](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md). - - It returns an array of JavaScript Error objects if there are any validation errors. For now, - - it only uses the message property of the Error object which, using lo-dash or Underscore.js, can be got easily via - - - ```javascript - - var errors = _.pluck(_.pluck([VALIDATION RETURN], 'error'), 'message');) - - ``` - - - #### Validating an object - - While the main intention of this module is to validate the request passed into express via swagger-node-express, - - there are use cases where an object must be validated outside of a request (for example, if an object passed into a - - request is also used in other methods that do their own validation or during unit testing). To support this - - functionality, as of version 1.3.0, if the req object passed into the validate function does not have one of the - - expected paramType properties (query, path, body, form, or header) then validation will be done against - - the req object itself. Therefore, this can be used to validate that an object matches the swagger specification outside - - of a request. Validating an object follows all the same rules outlined under *[Validating a request](#validating-a-request)*, - - but ignores the paramType on the Swagger spec as it already has the object / value to validate. - - - Additionally, as of version 1.4.0, passing in a model name instead of the swagger specification will validate the object - - directly instead of looking at the request. However, this functionality only works with objects. Any non-object passed - - in will return an error instead of being validated. - - - As an example: - - - ```javascript - var validate = require('swagger-validation'); - var models = require("./models.js"); - var ret = validate('[MODEL NAME HERE]', obj, models); - ``` - - - ## Installation - - - Using NPM, include the `swagger-validation` module in your `package.json` dependencies. - - - ```json - - { - ... - "dependencies": { - "swagger-validation": "~1.4", - ... - } - ... - } - - ``` - - - ## Adding validation to swagger-node-express - - - There are few different ways to use this module within swagger-node-express depending on what you are trying to accomplish. - - - ### Use the middleware component of Swagger - - - The benefit of this is that, by default, all methods will have their request validated - - against the parameters specified automatically. - - - ```javascript - - - // add this to the swagger definition, usually defined in the app.js - - swagger.addMiddleware(function(req, res, spec, models) { - var ret = validate(spec, req, models); - if(ret.length) { - var errors = _.pluck(_.pluck(ret, 'error'), 'message'); - var message = 'validation failure - ' + errors.join(); - return { 'code' : 400, 'message': message }; - } - }); - - - ``` - - - **(NOTE: As of 8-7-2014, this is still a pull request of swagger and has not been approved. As such, - - this implementation WILL change if / when it gets pulled into swagger-node-express).** - - - ### Validate each method individually - - - For the following method (using the swagger-application "test application" inside swagger-node-express) - - - ```javascript - - exports.findById = { - 'spec': { - description : "Operations about pets", - path : "/pet/{petId}", - method: "GET", - summary : "Find pet by ID", - notes : "Returns a pet based on ID", - type : "Pet", - nickname : "getPetById", - produces : ["application/json"], - parameters : [param.path("petId", "ID of pet that needs to be fetched", "string")], - responseMessages : [swe.invalid('id'), swe.notFound('pet')] - }, - 'action': function (req,res) { - if (!req.params.petId) { - throw swe.invalid('id'); } - var id = parseInt(req.params.petId); - var pet = petData.getPetById(id); - - if(pet) res.send(JSON.stringify(pet)); - else throw swe.notFound('pet',res); - } - }; - - ``` - - - change it to - - - ```javascript - - exports.findById = { - 'spec': { - description : "Operations about pets", - path : "/pet/{petId}", - method: "GET", - summary : "Find pet by ID", - notes : "Returns a pet based on ID", - type : "Pet", - nickname : "getPetById", - produces : ["application/json"], - parameters : [param.path("petId", "ID of pet that needs to be fetched", "string")], - responseMessages : [swe.invalid('id'), swe.notFound('pet')] - }, - 'action': function (req,res) { - - var validate = require('swagger-validation'); - var models = require("./models.js"); - var _ = require('lodash'); - // models are only needed if this is intended to validate an object - var ret = validate(exports.findById.spec, req, models); - if(ret.length) { - var errors = _.pluck(_.pluck(ret, 'error'), 'message'); - res.send(JSON.stringify({ - 'message': 'validation failure - ' + errors.join(), - 'code': 400 - }), 400); - return; - } - - if (!req.params.petId) { - throw swe.invalid('id'); } - var id = parseInt(req.params.petId); - var pet = petData.getPetById(id); - - if(pet) res.send(JSON.stringify(pet)); - else throw swe.notFound('pet',res); - } - }; - - ``` - - - or, for a little cleaner approach: - - - ```javascript - - exports.findById = { - 'spec': { - description : "Operations about pets", - path : "/pet/{petId}", - method: "GET", - summary : "Find pet by ID", - notes : "Returns a pet based on ID", - type : "Pet", - nickname : "getPetById", - produces : ["application/json"], - parameters : [param.path("petId", "ID of pet that needs to be fetched", "string")], - responseMessages : [swe.invalid('id'), swe.notFound('pet')] - }, - 'action': function (req,res) { - validateReq(req, res, exports.findById.spec, function() { - if (!req.params.petId) { - throw swe.invalid('id'); } - var id = parseInt(req.params.petId); - var pet = petData.getPetById(id); - - if(pet) res.send(JSON.stringify(pet)); - else throw swe.notFound('pet',res); - }); - } - }; - - - // put this somewhere else, either in the same file or put it in a - - // separate module using the standard module.exports Node convention - - var validate = require('swagger-validation'); - - var _ = require('lodash'); - - var models = require("./models.js"); - - - function validateReq(req, res, spec, func) { - var ret = validate(spec, req, models); - if(ret.length) { - var errors = _.pluck(_.pluck(ret, 'error'), 'message'); - res.send(JSON.stringify({ - 'message': 'validation failure - ' + errors.join(), - 'code': 400 - }), 400); - return; - } - - func(); - } - - - ``` - - - ### Modify swagger-node-express directly - - - While this would have the same benefit as the first one that, by default, all methods - - will have their request validated against the parameters specified automatically, this is **non-standard** and **can lead to unintended consequences**. - - This **will** be deprecated / removed once the pull request specified above gets pulled in. - - - ```javascript - - // /swagger-node-express/lib/swagger.js - // lines 418 - 420 currently have - else { - callback(req, res, next); - } - - // change it to - else { - var validate = require('swagger-validation'); - var ret = validate(spec, req, self.allModels); - if(ret.length) { - var errors = _.pluck(_.pluck(ret, 'error'), 'message'); - res.send(JSON.stringify({ - 'message': 'validation failure - ' + errors.join(), - 'code': 400 - }), 400); - return; - } - - callback(req, res, next); - } - - - ``` - - - ## Functionality outside of Swagger specification - - - Swagger-validation adheres to the official swagger specification, but does provide non-standard - - functionality to allow additional validation / ease that the official swagger specification doesn't support. - - - ### String pattern matching (RegExp) - - - It is possible to validate string types using a RegExp pattern defined on your swagger object. For the following example: - - - ```javascript - - exports.findByName = { - spec: { - description : "Find pet by name", - path : "/pet/{petName}", - method: "GET", - type : "Pet", - produces : ["application/json"], - parameters : [{ - id: "petName", - description: "petName", - type: "string", - pattern: "^dr*" - }] - } - }; - - ``` - - - Swagger-validation will now enforce that all names sent to the /pet/{petName} route start with `"dr"`. - - `pattern` will accept any regex string. An invalid regex string will report an error. - - - ### Date pattern matching (moment.js format) - - - Much like the string pattern matching mentioned above, swagger objects with a type of `string` and a format of - - `date` or `date-time` also accept a `pattern` property. However, instead of a RegExp string, they accept a - - [moment.js format string](http://momentjs.com/docs/#/displaying/format/). By default, it uses `moment.ISO_8601()`, - - which should match any ISO 8601 compatible date. If you want to be more explicit, you can specify your own - - format using the `pattern` property. - - - ### Value manipulation - - - In addition to validating the request / object, swagger-validation will replace the value on the request / object - - according to the following chart: - - - | Input Type | Swagger Type | Swagger Format | Output | - - | ----- | ----- | ----- | ----- | - - | string integer/long e.g. `"123"` | `integer` | `int32` or `int64` | integer/long e.g. `123` | - - | string hex e.g. `"0x123"` | `integer` | `int32` or `int64` | integer/long e.g. `291` | - - | string float/double e.g. `"123.01"` | `number` | `float` or `double`| float/double e.g. `123.01` | - - | string boolean e.g. `"true"` | `boolean` | | boolean e.g. `true` | - - | string date e.g. `"2014-08-10"` | `string` | `date` | Date object e.g. `new Date("2014-08-10")`** | - - | string date e.g. `"2014-08-10T12:00:01"` | `string` | `date-time` | Date object e.g. `new Date("2014-08-10T12:00:01")`** | - - - ** The date conversions are done using the [moment.js](//momentjs.com/) library. - - By default, it uses the `moment.ISO_8601()` format for parsing dates, but can be overridden by changing the `pattern` property - - - In addition, if a defaultValue is specified for the param and the value is null, undefined, or an empty string, - - swagger-validation will replace the value on the req with the defaultValue for that parameter. - - - #### NOTE - - As JavaScript doesn't pass method parameters by reference for non object / array values (such as strings or numbers), - - passing in a value type cannot convert the value. Therefore, passing in a value type without an object will not - - convert the value. This only applies when passing in the value itself NOT when the value is part of the request. - - If the value is on the request, regardless of type, it will still convert the value and update the request. - - - ### Validation object - - - Swagger-validation adds another object to the swagger.spec definition called validation that looks like this - - - ```javascript - - validation = { - enabled : [true / false], - replaceValues : [true / false] - }; - - ``` - - - and can be used like - - - ```javascript - - exports.findByName = { - spec: { - description : "Find pet by name", - path : "/pet/{petName}", - method: "GET", - type : "Pet", - validation = { - replaceValues : false - }, - produces : ["application/json"], - parameters : [{ - id: "petName", - description: "petName", - type: "string", - pattern: "/^dr*/i" - }] - } - }; - - ``` - - - The `enabled` property turns on / off swagger-validation holistically for the particular spec.
- - The `replaceValues` property turns on / off the functionality to manipulate values on the req (detailed in the previous section).
- - Both of these values default to true (so validation is enabled as well as it will replace the values on the req). - - - ## Types of validation - - - | Type | Format | Description | - - | ----- | ------ | ----- | - - | `array` | | This checks that each value inside the array corresponds to the type that was specified. It doesn't check that the array contains 'empty' values, even if the array parameter is required as spec doesn't have a way to say all values inside the array are required.

While the spec says `uniqueItems` marks the array to be treated like a set instead of an array (and not that this is invalid if it isn't unique), it does have the potential to lead to an unintentional and unintended loss of data, so this throws a validation error that what you are passing isn't unique over just allowing the non-unique data to be lost. As such, if all the items passed their validation, check for uniqueness. This only validates uniqueness after all the items in the array are validated.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `boolean` | | This only handles native boolean types or converting from `true` / `false` strings, as the concept is not uniform for other types (ie, if it's a number, should it be 0 = false and 1 = true or should any non-zero number be true). However, this only handles strings that are the string representation in JavaScript of their boolean counterparts, so True, TRUE, etc. will not validate.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `integer` | | This allows all forms of a number (so 2, 2.0, 2e0, 0x2). As a hex value COULD be the hex representation of an actual integer (and JavaScript parses it for us anyway), allow JavaScript to treat hex numbers in the way it wants to. Additionally, if a minimum or maximum is defined this ensures the value is greater than the minimum (if minimum defined) or less than the maximum (if maximum defined).

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `integer` | `int32` | This allows all forms of a number (so 2, 2.0, 2e0, 0x2) and allows numbers between -9007199254740991 and +9007199254740991 (both inclusive). As a hex value COULD be the hex representation of an actual integer (and JavaScript parses it for us anyway), allow JavaScript to treat hex numbers in the way it wants to. Additionally, if a minimum or maximum is defined this ensures the value is greater than the minimum (if minimum defined) or less than the maximum (if maximum defined).

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `integer` | `int64` | This allows all forms of a number (so 2, 2.0, 2e0, 0x2) and allows numbers between `Number.MIN_VALUE` (exclusive) and `Number.MAX_VALUE` (inclusive). As a hex value COULD be the hex representation of an actual number (and JavaScript parses it for us anyway), allow JavaScript to treat hex numbers in the way it wants to. Additionally, if a minimum or maximum is defined this ensures the value is greater than the minimum (if minimum defined) or less than the maximum (if maximum defined).

This does have issues with edge case validation (such as Number.MAX_VALUE + 1) as, per [IEEE-754 2008 §4.3.1 spec](http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=4610935), JavaScript does rounding during addition, so essentially, Number.MAX_VALUE + 1 will equal Number.MAX_VALUE not Number.Infinity. There isn't anything we can do about this as it is correct, per spec, but it isn't intuitive.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `file` | | This has no type validation, but it is valid.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `number` | | This allows all forms of a number (so 2, 2.0, 2.2, 2e0, 0x2) and allows numbers between `Number.MIN_VALUE` and `Number.MAX_VALUE` (both inclusive). As a hex value COULD be the hex representation of an actual number (and JavaScript parses it for us anyway), allow JavaScript to treat hex numbers in the way it wants to. Additionally, if a minimum or maximum is defined this ensures the value is greater than the minimum (if minimum defined) or less than the maximum (if maximum defined).

This does have issues with edge case validation (such as Number.MAX_VALUE + 1) as, per [IEEE-754 2008 §4.3.1 spec](http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=4610935), JavaScript does rounding during addition, so essentially, Number.MAX_VALUE + 1 will equal Number.MAX_VALUE not Number.Infinity. There isn't anything we can do about this as it is correct, per spec, but it isn't intuitive.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `number` | `float` | This allows all forms of a number (so 2, 2.0, 2.2, 2e0, 0x2) and allows numbers between `Number.MIN_VALUE` and `Number.MAX_VALUE` (both inclusive). As a hex value COULD be the hex representation of an actual number (and JavaScript parses it for us anyway), allow JavaScript to treat hex numbers in the way it wants to. Additionally, if a minimum or maximum is defined this ensures the value is greater than the minimum (if minimum defined) or less than the maximum (if maximum defined).

This does have issues with edge case validation (such as Number.MAX_VALUE + 1) as, per [IEEE-754 2008 §4.3.1 spec](http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=4610935), JavaScript does rounding during addition, so essentially, Number.MAX_VALUE + 1 will equal Number.MAX_VALUE not Number.Infinity. There isn't anything we can do about this as it is correct, per spec, but it isn't intuitive.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `number` | `double` | This allows all forms of a number (so 2, 2.0, 2.2, 2e0, 0x2) and allows numbers between `Number.MIN_VALUE` and `Number.MAX_VALUE` (both inclusive). As a hex value COULD be the hex representation of an actual number (and JavaScript parses it for us anyway), allow JavaScript to treat hex numbers in the way it wants to. Additionally, if a minimum or maximum is defined this ensures the value is greater than the minimum (if minimum defined) or less than the maximum (if maximum defined).

This does have issues with edge case validation (such as Number.MAX_VALUE + 1) as, per [IEEE-754 2008 §4.3.1 spec](http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=4610935), JavaScript does rounding during addition, so essentially, Number.MAX_VALUE + 1 will equal Number.MAX_VALUE not Number.Infinity. There isn't anything we can do about this as it is correct, per spec, but it isn't intuitive.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `object` | | This checks that the value is a valid Object by iterating through each property on the associated model and calling out to the respective validation method to validate that property. After validating the properties on this object's model, it will recursively look to see if any other models have this model in their subType array. If so, it will validate those properties as well. It will continue to do this until no more types are found in the subType array.

If the parameter is simply object (not a reference to a model), this will only validate that the type is an object and not check any properties of the object.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `string` | | If an enum is defined this ensures that the value is inside the enum list (which is case-sensitive).

If a pattern is defined this also ensures that the value adheres to it.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `string` | `byte` | This has no type validation, but it is valid.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `string` | `date` | There is no definitive definition in the swagger spec as to what constitutes a valid date or date-time (more than likely due to the varied formats a date could have). Therefore, swagger-validation will accept a 'pattern' property on the Swagger Property/Parameter Objects, which is a moment.js format string, that specifies the explicit format expected for the date format. If no pattern property is detected, moment.ISO_8601 will be used by default.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - | `string` | `date-time` | There is no definitive definition in the swagger spec as to what constitutes a valid date or date-time (more than likely due to the varied formats a date could have). Therefore, swagger-validation will accept a 'pattern' property on the Swagger Property/Parameter Objects, which is a moment.js format string, that specifies the explicit format expected for the date format. If no pattern property is detected, moment.ISO_8601 will be used by default.

If "nothing" was passed into the validate function and it's required with no default value, then this will throw a parameter is required error. - - - ## Documentation - - - Full documentation of how all code works in swagger-validation is available in both markdown and HTML format (using jsdoc). - - To create it, run the default Gulp task (cli - gulp default). - - - ## License - - - (The MIT License) - - - Copyright (c) 2014 Wonderlic, Inc. - - - Permission is hereby granted, free of charge, to any person obtaining - - a copy of this software and associated documentation files (the - - 'Software'), to deal in the Software without restriction, including - - without limitation the rights to use, copy, modify, merge, publish, - - distribute, sublicense, and/or sell copies of the Software, and to - - permit persons to whom the Software is furnished to do so, subject to - - the following conditions: - - - The above copyright notice and this permission notice shall be - - included in all copies or substantial portions of the Software. - - - THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -signalfx/swagger-validate: > - # Validate Swagger Objects - - [![Build Status](https://travis-ci.org/signalfx/swagger-validate.svg?branch=master)](https://travis-ci.org/signalfx/swagger-validate) - - - A detailed validation provider for [Swagger](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md) objects. - - - Given a relevant Swagger spec, this tool will provide detailed information about any validation errors which can be - - caught automatically. This is useful for catching invalid requests to a server on the client-side before a call is - - ever issues. Currently, these objects can be validated according to their Swagger specification: - - * [Models](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#527-model-object) (supports inheritance) - - * [Operations](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#523-operation-object) - - * [Data types](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#433-data-type-fields) - - - ## Basic Example - - ```javascript - - var catModel = { - id: 'Cat', - required: ['name'], - properties: { - name: { type: 'string' }, - age: { type: 'number' } - } - }; - - - var myCat = { - name: 'Grumpy', - age: 'blue' - }; - - - var error = swaggerValidate.model(myCat, catModel); - - - console.error(error.toString()); - - // ValidationErrors: Cat is invalid: - - // age is invalid: "blue" is not a number (got a string instead) - - ``` - - - ## Installation and Use - - For nodejs: `npm install swagger-validate` then use `var swaggerValidate = require('swagger-validate')` to include it in a script. - - - For browsers: `bower install swagger-validate` or include the `./dist/swagger-validate.js` file as a script tag to put the swaggerValidate function in the global scope. You may also `require` it with browserify or with Requirejs instead of including it as a script tag. - - - ## API - - - ### var error = swaggerValidate.model(object, model[, models]) - - Validate an object using a given model spec. - - - #### Parameters - - * *object* - the instance to validate against the defined model - - * *model* - the model to use when validating the object - - * *models* - optional map of model names to models to be used when dereferencing linked models (such as $refs or inherited properties). - - - #### Returns - - * *error* or *undefined* - if a validation error is found, a ValidationErrors object will be returned with the details of the error(s). - - - ### swaggerValidate.errors.ValidationErrors - - The primary error object emitted by the validator with the following properties: - - * *name* - The name of the error (always 'ValidationErrors') - - * *message* - A human readable message of the error - - * *specName* - The name of the specification object used for the validation - - * *spec* - The specification used for the validation (such as a model or an operation object) - - * *value* - The object which failed the validation - - * *errors* - A list of ValidationError objects for each invalid field in the given object. - - - ### swaggerValidate.errors.ValidationError - - This is the wrapper around individual validation errors. Each invalid field in a given object will have one ValidationError object within the ValidationErrors.errors list. - - - * *name* - The name of the error (always 'ValidationError') - - * *message* - A human readable message of the error - - * *specName* - The name of the specification object used for the validation - - * *spec* - The specification used for the validation (such as a model property or an operation parameter) - - * *error* - A subtype of DataTypeValidationError object with specific error details. - - - ### swaggerValidate.errors.DataValidationError - - This is a super class for the individual validation errors that can occur in properties. Here's a full list of the different types, all which are accessable via swaggerValidate.errors[*name of error*]: - - * *NotAStringError* - The value was expected to be a string but wasn't. - - * *NotABooleanError* - The value was expected to be a boolen but wasn't. - - * *NotAnArrayError* - The value was expected to be an array but wasn't. - - * *NotVoidError* - The value was expected to be void but wasn't. - - * *NotANumberError* - The value was expected to be a number but wasn't. - - * *NotAnIntegerError* - The value was a number but not an integer as expected. - - * *NumberTooLargeError* - The value was a number but over the maximum value allowed by the model. - - * *NumberTooSmallError* - The value was a number but under the minumum value allowed by the model. - - * *DuplicateInSetError* - The value is an array which has duplicates, which is not allowed by the model. - - * *ErrorsInArrayElementsError* - Errors occurred within the elements of an array. Depending on the type of an array these errors may be of ValidationErrors type or subtypes of DataValidationErrors. - - * *MissingValueError* - The value is required by the model but doesn't exist. - - - ## Developing - - After installing [nodejs](http://nodejs.org) execute the following: - - - ```shell - - git clone https://github.com/signalfx/swagger-validate.git - - cd swagger-validate - - npm install - - npm run dev - - ``` - - The build engine will test and build everything, start a server hosting the `example` folder on [localhost:3000](http://localhost:3000), and watch for any changes and rebuild when nescessary. - - - To generate minified files in `dist`: - - ```shell - - npm run dist - - ``` -DarthFubuMVC/fubumvc: "# Building FubuMVC\r - - \r - - The FubuMVC codebase still uses Rake for build automation, but as of - September 2015, you don't **have** to use Rake to develop with FubuMVC if you - don't want to. You **will need \r - - to have Node.js or Io.js and npm installed** in order to build the client - side assets for FubuMVC's diagnostics package before working with the C# - code.\r - - \r - - ## With Rake\r - - \r - - Assuming you have Ruby 2.1+ installed on your computer, go to a command line - and type...\r - - \r - - 1. bundle install\r - - 1. rake\r - - \r - - \r - - ## Visual Studio.Net Only\r - - \r - - There is a small command file called `build.cmd` that can be executed once - to bring down nuget and npm dependencies and build the client side assets that - FubuMVC \r - - needs for its embedded. diagnostics. Run this command at least once before - opening Visual Studio.Net.\r - - \r - - From there, open the solution file at `src/FubuMVC.sln` and go to town.\r - - \r - - \r - - # Working with Storyteller\r - - \r - - * `rake open_st` -- Opens the Storyteller test suite in the Storyteller - client for interactive editing and execution\r - - * `rake storyteller` -- Runs all the Storyteller specifications\r - - \r - - # Working with Diagnostics\r - - \r - - Open the diagnostics harness application to the browser with the command - `rake diagnostics`. This command will start webpack in a new window against - the client side\r - - attributes in the `javascript` folder in \"watched\" mode. This command also - compiles and starts the `DiagnosticsHarness` application in a NOWIN server - before opening a browser\r - - window to the newly launched application. The browser will auto-refresh - whenever a new version of the webpack `bundle.js` file is saved. You will have - to stop and restart\r - - the FubuMVC application to see any changes to the server side.\r - - \ \r - - \r\n" -kenshoo/swagger-validator: > - # Swagger Validator - - [![Build Status](https://travis-ci.org/kenshoo/swagger-validator.svg?branch=master)](https://travis-ci.org/kenshoo/swagger-validator) - - - ## Overview - - Validates swagger.yaml file. - - Validation are done assuming JAX-RS resources and Jackson POJOs. - - - The default validations include: - - - Resources validations: - - The resource class exists (See x-javaClass) - - The resource class annotated with @Path and that the value matches. - - For each operation validate that: - - Exists method in a resource annotated with the proper annotation (e.g. GET, POST, etc.) - - Operation is tagged. - - Definitions validations: - - The POJO exists (See x-javaClass) - - Property from definition matches a property in POJO (By default property in Swagger equals to field in POJO) - - POJO doesn't use forbidden types (e.g. using primitive types is forbidden) - - Warning is printed if unrecommended type is used. - - ## Validator Elements - - The Swagger Validator expects additional elements to be present in the swagger.yaml to perform the validations. - - #### x-javaClass - - **x-javaClass** defines the fully qualified name of the desired class. This is used to validate that the relevant class really exists in the classpath and it's a starting point for addition validations. - - - ## Download - - The Swagger Validator is distributed using Maven Central. - - - ### Maven Dependency - - ``` - - - com.kenshoo - swagger-validator - ${swagger-validator-version} - - - ``` - - - ## Running - - The SwaggerValidator is a simple Java class. It must be run in the classpath containing all the resources and definitions. - - - #### Example - - ``` - - SwaggerValidator swaggerValidator = new SwaggerValidator(getClass().getResourceAsStream("/swagger.yaml")); - - swaggerValidator.validateDefinitions(); - - swaggerValidator.validateResources(); - - ``` - - See unit tests for more examples. - - - #### Customization - - ``` - - SwaggerValidatorConf conf = new SwaggerValidatorConf() { - @Override - public Set> getForbiddenClasses() { - return Collections.emptySet(); - } - }; - - SwaggerValidator swaggerValidator = new SwaggerValidator(getClass().getResourceAsStream("/swagger.yaml"), conf); - - swaggerValidator.validateDefinitions(); // forbidden types won't be validated - - ``` -nelmio/NelmioApiDocBundle: > - NelmioApiDocBundle - - ================== - - - [![Build Status](https://img.shields.io/github/actions/workflow/status/nelmio/NelmioApiDocBundle/continuous-integration.yml?branch=master&style=flat-square)](https://github.com/nelmio/NelmioApiDocBundle/actions?query=workflow:CI) - - [![Total Downloads](https://poser.pugx.org/nelmio/api-doc-bundle/downloads)](https://packagist.org/packages/nelmio/api-doc-bundle) - - [![Latest Stable - - Version](https://poser.pugx.org/nelmio/api-doc-bundle/v/stable)](https://packagist.org/packages/nelmio/api-doc-bundle) - - - The **NelmioApiDocBundle** bundle allows you to generate a decent documentation - - for your APIs. - - - ## Migrate from 3.x to 4.0 - - - [To migrate from 3.x to 4.0, follow our guide.](https://github.com/nelmio/NelmioApiDocBundle/blob/master/UPGRADE-4.0.md) - - - Version 4.0 brings OpenAPI 3.0 support. If you want to stick to Swagger 2.0, you should use the version 3 of this bundle. - - - ## Migrate from 2.x to 3.0 - - - [To migrate from 2.x to 3.0, follow our guide.](https://github.com/nelmio/NelmioApiDocBundle/blob/master/UPGRADE-3.0.md) - - - ## Installation - - - Open a command console, enter your project directory and execute the following command to download the latest version of this bundle: - - - ``` - - composer require nelmio/api-doc-bundle - - ``` - - - ## Documentation - - - [Read the documentation on symfony.com](https://symfony.com/doc/current/bundles/NelmioApiDocBundle/index.html) - - - ## Contributing - - - See - - [CONTRIBUTING](https://github.com/nelmio/NelmioApiDocBundle/blob/master/CONTRIBUTING.md) - - file. - - - ## Running the Tests - - - Install the [Composer](http://getcomposer.org/) dependencies: - - git clone https://github.com/nelmio/NelmioApiDocBundle.git - cd NelmioApiDocBundle - composer update - - Then run the test suite: - - ./phpunit - - ## License - - - This bundle is released under the MIT license. -astaxie/beego: > - # Beego [![Build - Status](https://travis-ci.org/astaxie/beego.svg?branch=master)](https://travis-ci.org/astaxie/beego) - [![GoDoc](http://godoc.org/github.com/astaxie/beego?status.svg)](http://godoc.org/github.com/astaxie/beego) - [![Foundation](https://img.shields.io/badge/Golang-Foundation-green.svg)](http://golangfoundation.org) - [![Go Report - Card](https://goreportcard.com/badge/github.com/astaxie/beego)](https://goreportcard.com/report/github.com/astaxie/beego) - - - Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend - - services. - - - It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific features such as interfaces and struct - - embedding. - - - ![architecture](https://cdn.nlark.com/yuque/0/2020/png/755700/1607857489109-1e267fce-d65f-4c5e-b915-5c475df33c58.png) - - - Beego is compos of four parts: - - 1. Base modules: including log module, config module, governor module; - - 2. Task: is used for running timed tasks or periodic tasks; - - 3. Client: including ORM module, httplib module, cache module; - - 4. Server: including web module. We will support gRPC in the future; - - - ## Quick Start - - - [Officail website](http://beego.me) - - - [Example](https://github.com/beego-dev/beego-example) - - - > If you could not open official website, go to [beedoc](https://github.com/beego/beedoc) - - - - ### Web Application - - - ![Http Request](https://cdn.nlark.com/yuque/0/2020/png/755700/1607857462507-855ec543-7ce3-402d-a0cb-b2524d5a4b60.png) - - - #### Create `hello` directory, cd `hello` directory - - mkdir hello - cd hello - - #### Init module - - go mod init - - #### Download and install - - go get github.com/astaxie/beego@v2.0.0 - - #### Create file `hello.go` - - - ```go - - package main - - - import "github.com/astaxie/beego/server/web" - - - func main() { - web.Run() - } - - ``` - - - #### Build and run - - go build hello.go - ./hello - - #### Go to [http://localhost:8080](http://localhost:8080) - - - Congratulations! You've just built your first **beego** app. - - - ## Features - - - * RESTful support - - * [MVC architecture](https://github.com/beego/beedoc/tree/master/en-US/mvc) - - * Modularity - - * [Auto API documents](https://github.com/beego/beedoc/blob/master/en-US/advantage/docs.md) - - * [Annotation router](https://github.com/beego/beedoc/blob/master/en-US/mvc/controller/router.md) - - * [Namespace](https://github.com/beego/beedoc/blob/master/en-US/mvc/controller/router.md#namespace) - - * [Powerful development tools](https://github.com/beego/bee) - - * Full stack for Web & API - - - ## Modules - - * [orm](https://github.com/beego/beedoc/tree/master/en-US/mvc/model) - - * [session](https://github.com/beego/beedoc/blob/master/en-US/module/session.md) - - * [logs](https://github.com/beego/beedoc/blob/master/en-US/module/logs.md) - - * [config](https://github.com/beego/beedoc/blob/master/en-US/module/config.md) - - * [cache](https://github.com/beego/beedoc/blob/master/en-US/module/cache.md) - - * [context](https://github.com/beego/beedoc/blob/master/en-US/module/context.md) - - * [governor](https://github.com/beego/beedoc/blob/master/en-US/module/governor.md) - - * [httplib](https://github.com/beego/beedoc/blob/master/en-US/module/httplib.md) - - * [task](https://github.com/beego/beedoc/blob/master/en-US/module/task.md) - - * [i18n](https://github.com/beego/beedoc/blob/master/en-US/module/i18n.md) - - - ## Community - - - * [http://beego.me/community](http://beego.me/community) - - * Welcome to join us in Slack: [https://beego.slack.com](https://beego.slack.com), you can get invited - from [here](https://github.com/beego/beedoc/issues/232) - * QQ Group Group ID:523992905 - - * [Contribution Guide](https://github.com/beego/beedoc/blob/master/en-US/intro/contributing.md). - - - ## License - - - beego source code is licensed under the Apache Licence, Version 2.0 - - (http://www.apache.org/licenses/LICENSE-2.0.html). -signalfx/swagger-ajax-client: > - # Swagger Ajax Client - - - Create XHR clients for [Swagger API Specifications](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md). - - - Given a schema object, this tool returns an api object which can be used to interact with the API server - - described by the schema. The schema can easily be generated using [fetch-swagger-schema](https://github.com/signalfx/fetch-swagger-schema)). - - - # Usage - - To use, include one of these files in your application: - - * *[swagger-ajax-client.js](https://raw.githubusercontent.com/signalfuse/swagger-ajax-client/master/dist/swagger-ajax-client.js)* - - * *[swagger-ajax-client.js.min](https://raw.githubusercontent.com/signalfuse/swagger-ajax-client/master/dist/swagger-ajax-client.min.js)*, a minified version ([source map](https://raw.githubusercontent.com/signalfuse/swagger-ajax-client/master/dist/swagger-ajax-client.min.js.map)) - - - You may also `bower install swagger-ajax-client` to install using bower. Once you've included the script, you can use the swaggerAjaxClient function to generate the api using a given schema object. - - - Schemas can be generated using [fetch-swagger-schema](https://github.com/signalfuse/fetch-swagger-schema). - - - - ## Examples - - - First, a simple example. Let's say you saved a schema json file, then loaded it - - into your app as the `schema` variable. Now you can call operations on the API - - by using swaggerAjaxClient: - - ```javascript - - // Assuming the variable schema exists - - var api = swaggerAjaxClient(schema); - - - // for apiKey authorization use: api.auth('my-token') - - // for basicAuth use: api.auth('username', 'password') - - - api.pet.getPetById(id).then(function(pet){ - console.log(pet); - }); - - ``` - - - - Here's a more advanced case in which we're leveraging promises to implement a - - 'getOrCreate' method, which doesn't actually exist within the api: - - ```javascript - - - var api = swaggerAjaxClient(schema); - - - function getOrCreate(id, name){ - return api.pet.getPetById(id).catch(function(response){ - // If pet doesn't exist, create a new one. - if(response.status === 404){ - var pet = {id: id, name: name}; - return api.pet.addPet(pet).then(function(){ - return pet; - }); - } - - // Unknown error - console.error(response.error.toString()); - }); - } - - - getOrCreate(23, 'bob').then(function(pet){ - console.log('Got pet:', pet); - }, function(error){ - console.error(error.toString()); - }); - - ``` - - - ## API - - - #### `api = swaggerAjaxClient(schema)` - - * *schemaObject* - A json object describing the schema (generated by [fetch-swagger-schema](https://github.com/signalfx/fetch-swagger-schema)). - - * *api* - An object which can be used as the api for the given schema. The first-level objects are the resources within the schema and the second-level functions are the operations which can be performed on those resources. - - - #### `api.` - - A map of all the resources as defined in the schema to their operation handler (e.g. `api.pet`). - - - #### `responsePromise = api..(data, options)` - - This is the actual operation function to initiate a request to the API endpoint (e.g., `api.pet.getPetById`). - - - The operation handler takes two parameters: - - * *data* - A map of the operation data parameters. If the operation only has one parameter, the value may be used directly (i.e. `api.pet.getPetById(1, callback)` is the same as `api.pet.getPetById({petId: 1}, callback)`). - - * *options* - A map of the options to use when calling the operation (see below for full list). - - - The response promise is an ES6 promise. A HTTP response in the 200s range will result - - in a resolved promise and anything else will result in a rejected promises. A resolved - - promise value is whatever the server responded with (JSON is automatically parsed). A - - rejected promise value is a map with a `status`, `data`, and `error` properties, where - - the status is the HTTP status, data is the response body from the server, and error - - is a JavaScript error (if any occurred). - - - Here's an example: - - ```javascript - - // use of .then(successHandler, failHandler) - - responsePromise.then(function(response){ - console.log('successful response:', response); - }, function(response){ - console.log('request failed due to error:', response.error); - }); - - ``` - - - ## Developing - - After installing [nodejs](http://nodejs.org) execute the following: - - - ```shell - - git clone https://github.com/signalfx/swagger-ajax-client.git - - cd swagger-ajax-client - - npm install - - npm run dev - - ``` - - The build engine will test and build everything, start a server hosting the `example` folder on [localhost:3000](http://localhost:3000), and watch for any changes and rebuild when nescessary. - - - To generate minified files in `dist`: - - ```shell - - npm run dist - - ``` -swagger-api/swagger-ui: > - # - - - [![NPM version](https://badge.fury.io/js/swagger-ui.svg)](http://badge.fury.io/js/swagger-ui) - - [![Build Status](https://jenkins.swagger.io/view/OSS%20-%20JavaScript/job/oss-swagger-ui-master/badge/icon?subject=jenkins%20build)](https://jenkins.swagger.io/view/OSS%20-%20JavaScript/job/oss-swagger-ui-master/) - - [![npm audit](https://jenkins.swagger.io/buildStatus/icon?job=oss-swagger-ui-security-audit&subject=npm%20audit)](https://jenkins.swagger.io/job/oss-swagger-ui-security-audit/lastBuild/console) - - ![total GitHub contributors](https://img.shields.io/github/contributors-anon/swagger-api/swagger-ui.svg) - - - ![monthly npm installs](https://img.shields.io/npm/dm/swagger-ui.svg?label=npm%20downloads) - - ![total docker pulls](https://img.shields.io/docker/pulls/swaggerapi/swagger-ui.svg) - - ![monthly packagist installs](https://img.shields.io/packagist/dm/swagger-api/swagger-ui.svg?label=packagist%20installs) - - ![gzip size](https://img.shields.io/bundlephobia/minzip/swagger-ui.svg?label=gzip%20size) - - - ## Introduction - - [Swagger UI](https://swagger.io/tools/swagger-ui/) allows anyone — be it your development team or your end consumers — to visualize and interact with the API’s resources without having any of the implementation logic in place. It’s automatically generated from your OpenAPI (formerly known as Swagger) Specification, with the visual documentation making it easy for back end implementation and client side consumption. - - - ## General - - **👉🏼 Want to score an easy open-source contribution?** Check out our [Good first issue](https://github.com/swagger-api/swagger-ui/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%22) label. - - - **🕰️ Looking for the older version of Swagger UI?** Refer to the [*2.x* branch](https://github.com/swagger-api/swagger-ui/tree/2.x). - - - - This repository publishes three different NPM modules: - - - * [swagger-ui](https://www.npmjs.com/package/swagger-ui) is a traditional npm module intended for use in single-page applications that are capable of resolving dependencies (via Webpack, Browserify, etc). - - * [swagger-ui-dist](https://www.npmjs.com/package/swagger-ui-dist) is a dependency-free module that includes everything you need to serve Swagger UI in a server-side project, or a single-page application that can't resolve npm module dependencies. - - * [swagger-ui-react](https://www.npmjs.com/package/swagger-ui-react) is Swagger UI packaged as a React component for use in React applications. - - - We strongly suggest that you use `swagger-ui` instead of `swagger-ui-dist` if you're building a single-page application, since `swagger-ui-dist` is significantly larger. - - - If you are looking for plain ol' HTML/JS/CSS, [download the latest release](https://github.com/swagger-api/swagger-ui/releases/latest) and copy the contents of the `/dist` folder to your server. - - - - ## Compatibility - - The OpenAPI Specification has undergone 5 revisions since initial creation in 2010. Compatibility between Swagger UI and the OpenAPI Specification is as follows: - - - Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes - - ------------------ | ------------ | -------------------------- | ----- - - 4.0.0 | 2021-11-03 | 2.0, 3.0 | [tag v4.0.0](https://github.com/swagger-api/swagger-ui/tree/v4.0.0) - - 3.18.3 | 2018-08-03 | 2.0, 3.0 | [tag v3.18.3](https://github.com/swagger-api/swagger-ui/tree/v3.18.3) - - 3.0.21 | 2017-07-26 | 2.0 | [tag v3.0.21](https://github.com/swagger-api/swagger-ui/tree/v3.0.21) - - 2.2.10 | 2017-01-04 | 1.1, 1.2, 2.0 | [tag v2.2.10](https://github.com/swagger-api/swagger-ui/tree/v2.2.10) - - 2.1.5 | 2016-07-20 | 1.1, 1.2, 2.0 | [tag v2.1.5](https://github.com/swagger-api/swagger-ui/tree/v2.1.5) - - 2.0.24 | 2014-09-12 | 1.1, 1.2 | [tag v2.0.24](https://github.com/swagger-api/swagger-ui/tree/v2.0.24) - - 1.0.13 | 2013-03-08 | 1.1, 1.2 | [tag v1.0.13](https://github.com/swagger-api/swagger-ui/tree/v1.0.13) - - 1.0.1 | 2011-10-11 | 1.0, 1.1 | [tag v1.0.1](https://github.com/swagger-api/swagger-ui/tree/v1.0.1) - - - ## Documentation - - - #### Usage - - - [Installation](docs/usage/installation.md) - - - [Configuration](docs/usage/configuration.md) - - - [CORS](docs/usage/cors.md) - - - [OAuth2](docs/usage/oauth2.md) - - - [Deep Linking](docs/usage/deep-linking.md) - - - [Limitations](docs/usage/limitations.md) - - - [Version detection](docs/usage/version-detection.md) - - - #### Customization - - - [Overview](docs/customization/overview.md) - - - [Plugin API](docs/customization/plugin-api.md) - - - [Custom layout](docs/customization/custom-layout.md) - - - #### Development - - - [Setting up](docs/development/setting-up.md) - - - [Scripts](docs/development/scripts.md) - - - #### Contributing - - - [Contributing](https://github.com/swagger-api/.github/blob/master/CONTRIBUTING.md) - - - ##### Integration Tests - - - You will need JDK of version 7 or higher as instructed here - - https://nightwatchjs.org/guide/getting-started/installation.html#install-selenium-server - - - Integration tests can be run locally with `npm run e2e` - be sure you aren't running a dev server when testing! - - - ### Browser support - - Swagger UI works in the latest versions of Chrome, Safari, Firefox, and Edge. - - - ### Known Issues - - - To help with the migration, here are the currently known issues with 3.X. This list will update regularly, and will not include features that were not implemented in previous versions. - - - - Only part of the parameters previously supported are available. - - - The JSON Form Editor is not implemented. - - - Support for `collectionFormat` is partial. - - - l10n (translations) is not implemented. - - - Relative path support for external files is not implemented. - - - ## Security contact - - - Please disclose any security-related issues or vulnerabilities by emailing [security@swagger.io](mailto:security@swagger.io), instead of using the public issue tracker. - - - ## License - - - SwaggerUI is licensed under [Apache 2.0 license](https://github.com/swagger-api/swagger-ui/blob/master/LICENSE). - - SwaggerUI comes with an explicit [NOTICE](https://github.com/swagger-api/swagger-ui/blob/master/NOTICE) file - - containing additional legal notices and information. -wkennedy/swagger4spring-web: > - swagger4spring-web - - ================== - - - Please note: This project is no longer actively supported. - - - Supports Swagger 1.3 as of version 0.3.0! - - - This project aims at providing Swagger support to your Spring-Web based application. It will attempt to document your API based on existing Spring-Web annotations if no Swagger annotations exist. If Swagger annotations do exist, it will utilize those in conjunction with the Spring-Web annotations. - - - ##How-To - - - To include swagger4spring-web in your project, you need to include the jar in your project. If you use Maven, please include the following dependency: - - - com.knappsack - swagger4spring-web - 0.3.5 - - - Java 8+ users, please compile your source using the javac "-parameters" argument. This ensures that your parameter names display correctly in your API documentation. - - - In order to use swagger4spring-web in your project, you need to declare an ApiDocumentationController bean in your - - servlet context. For example: - - - - * basePath - optional - the base URL of your web application, for example http://localhost/swagger4spring-web-example - - * baseControllerPackage - optional - this is the package you want swagger4spring-web to scan to look for classes annotated with @Controller. If this is not set, all your packages are scanned. - - * baseModelPackage - optional - this is the package you want to scan if all your model objects are in a specific directory. These classes will be added to your documentation schema. If no package is specified only certain return types and parameters are added to the documentation schema. - - * additionalControllerPackage - optional - if you have more packages with controllers outside of the baseControllerPackage, specify them here. - - * additionalModelPackage - optional - if you have packages outside of the baseModelPackage that you want to scan for models, specify them here. - - * apiVersion - required - this is the version of your API - - * apiInfo - optional - if you have information you wish to provide, such as license and terms of service, set this. - - - If you are using version 0.3.0 or above, you'll also need to add the following to the appropriate Spring context file in your application: - - - - - - - - - - - - Once the ApiDocumentationController is wired, you may call go to your base path + /api/resourceList (ex: http://localhost/swagger4spring-web-example/api/resourceList) in order to retrieve an inventory of your APIs. For an example JSP see this [page](https://github.com/wkennedy/swagger4spring-web-example/blob/master/src/main/webapp/WEB-INF/views/documentation.jsp). - - - #####Alternative Implementation - - - If you wish to use a different request mapping then you may extend create a new controller that extends ApiDocumentationController. For example if you want the URL to be /documentation/resourceList instead of /api/resourceList you can create a controller like this: - - @Controller - @RequestMapping(value = "/documentation") - public class ExampleDocumentationController extends ApiDocumentationController { - - public ExampleDocumentationController() { - setBaseControllerPackage("com.knappsack.swagger4springweb.controllers.api"); - setBaseModelPackage("com.knappsack.swagger4springweb.models"); - setApiVersion("v1"); - } - - @RequestMapping(value = "/", method = RequestMethod.GET) - public String documentation() { - return "documentation"; - } - } - - In this case you don't have to create the controller bean in your servlet context if you are using component scanning and your new controller is set to be picked up in the scan. - - - To see a working example, please take a look at [swagger4spring-web-example](https://github.com/wkennedy/swagger4spring-web-example/ "swagger4spring-web-example"). - - - ##Annotation Support - - The following Spring-Web annotations are supported: - - - * @Controller - - * @RestController - - * @RequestMapping - - * @ResponseBody - - * @RequestBody - - * @PathVariable - - * @RequestParam - - * @ApiExclude - This annotation is unique to swagger4spring-web. It allows you to specify a controller or method for which you do not want to generate Swagger documentation. - - - The following Swagger annotations are supported: - - - * @Api - - * @ApiResponse - - * @ApiResponses - - * @ApiOperation - - * @ApiParam - - * @ApiModel - - * @ApiModelProperty - - - ##External Links - - [Swagger Home](http://developers.helloreverb.com/swagger/ "Swagger Home") - - - [Swagger Wiki](https://github.com/wordnik/swagger-core/wiki "Swagger Wiki") - - - ##Change Log - - https://github.com/wkennedy/swagger4spring-web/wiki/Change-Log - - - ##License - - Copyright (c) 2014 Will Kennedy - - - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - - - The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -sun-opsys/api-doc: '{"message":"Not - Found","documentation_url":"https://docs.github.com/rest/reference/repos#get-a-repository-readme"}' -abelsilva/swaggerwcf: > -

- - SwaggerWcf  - nuget status - -

- - - Generates [Swagger](http://swagger.io/) (2.0) for WCF services and also provides [swagger-ui](https://github.com/swagger-api/swagger-ui). - - - With an API described in Swagger you can use multiple Swagger tools like client generators, see [swagger-codegen](https://github.com/swagger-api/swagger-codegen) for more details. - - - This project has started as a fork from [superstator/Swaggeratr](https://github.com/superstator/Swaggeratr) to implement version 2.0 of Swagger. - - - ## Getting Started - - - ### Step 1: Install SwaggerWcf package - - - ``` - - - Install-Package SwaggerWcf - - - ``` - - - ### Step 2: Configure WCF - - #### ASP.NET - - - Add the route in the `Application_Start` method inside `Global.asax` - - - ```csharp - - - protected void Application_Start(object sender, EventArgs e) - - { - // [.......] - - RouteTable.Routes.Add(new ServiceRoute("api-docs", new WebServiceHostFactory(), typeof(SwaggerWcfEndpoint))); - } - - - ``` - - - Note: You might need to add a reference to `System.ServiceModel.Activation` - - - Edit `Web.config` and add the following (if it doesn't exist yet) inside the `system.serviceModel` block - - - ```xml - - - - - - ``` - - - Edit again `Web.config` and add the following (if it doesn't exist yet) inside the `system.webServer` block - - - ```xml - - - - - - ``` - - #### Self Hosted - - Add an endpoint to your App.config file. - - ```xml - - - - - - - - ``` - - Create a WebServiceHost - - ```csharp - - var swaggerHost = new WebServiceHost(typeof(SwaggerWcfEndpoint)); - - swaggerHost.Open(); - - ``` - - - ### Step 3: Optionaly configure WCF response auto types - - - Add the following to your config file. - - This will allow the WCF service to accept requests and send replies based on the `Content-Type` headers. - - - ```xml - - - - - - - - - - - - - - ``` - - - ### Step 4: Configure WCF services general information - - #### Configure via config file - - Add the following to your config file and change the values accordingly - - - ```xml - - -
- - - - - - - - - - - - - - - - - - - - - ``` - - - Notes: - - * make sure the `configSections` block is the first child of `configuration` - - * `tags` will be described further down - - - #### Configure via code - - Configure the base properties via code. New: You can add security settings to your api (see also the new Security-Methodattribute) - - - ```csharp - - var info = new Info - - { - - Description = "Sample Service to test SwaggerWCF", - - Version = "0.0.1" - - // etc - - }; - - - var security = new SecurityDefinitions - - { - { - "api-gateway", new SecurityAuthorization - { - Type = "oauth2", - Name = "api-gateway", - Description = "Forces authentication with credentials via an api gateway", - Flow = "password", - Scopes = new Dictionary - { - { "author", "use author scope"}, - { "admin", "use admin scope"}, - }, - AuthorizationUrl = "http://yourapi.net/oauth/token" - } - } - }; - - - SwaggerWcfEndpoint.Configure(info, security); - - ``` - - - ### Step 5: Decorate WCF services interfaces - - - For each method, configure the `WebInvoke` or `WebGet` attribute, and add a `SwaggerWcfPath` attribute. - - - ```csharp - - - [ServiceContract] - - public interface IStore - - { - [SwaggerWcfPath("Create book", "Create a book on the store")] - [WebInvoke(UriTemplate = "/books", - BodyStyle = WebMessageBodyStyle.Bare, - Method = "POST", - RequestFormat = WebMessageFormat.Json, - ResponseFormat = WebMessageFormat.Json)] - [OperationContract] - Book CreateBook(Book value); - - // [.......] - } - - - ``` - - - ### Step 6: Decorate WCF services class - - - Add the `SwaggerWcf` and `AspNetCompatibilityRequirements` attributes to the class providing the base path for the service (the same as used in step 2). - - Optinally, for each method, add the `SwaggerWcfTag` to categorize the method and the `SwaggerWcfResponse` for each possible response from the service. - - - ```csharp - - - [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] - - [SwaggerWcf("/v1/rest")] - - public class BookStore : IStore - - { - [SwaggerWcfTag("Books")] - [SwaggerWcfResponse(HttpStatusCode.Created, "Book created, value in the response body with id updated")] - [SwaggerWcfResponse(HttpStatusCode.BadRequest, "Bad request", true)] - [SwaggerWcfResponse(HttpStatusCode.InternalServerError, - "Internal error (can be forced using ERROR_500 as book title)", true)] - public Book CreateBook(Book value) - { - // [.......] - } - - // [.......] - } - - - ``` - - - ### Step 7: Decorate data types used in WCF services - - - ```csharp - - - [DataContract(Name = "book")] - - [Description("Book with title, first publish date, author and language")] - - [SwaggerWcfDefinition(ExternalDocsUrl = "http://en.wikipedia.org/wiki/Book", ExternalDocsDescription = "Description of a book")] - - public class Book - - { - [DataMember(Name = "id")] - [Description("Book ID")] - public string Id { get; set; } - - // [.......] - } - - - ``` - - - Note: make sure you add at least the `DataContract` and `DataMember` attributes in classes and properties - - - ## Attributes - - - | Attribute | Used in | Description | Options | - - | ------------------------ |------------------------------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------- | - - | `SwaggerWcf` | `Class`, `Interface` | Enable parsing WCF service | `ServicePath` | - - | `SwaggerWcfHidden` | `Class`, `Method`, `Property`, `Parameter` | Hide element from Swagger | | - - | `SwaggerWcfTag` | `Class`, `Method`, `Property`, `Parameter` | Add a tag to an element | `TagName`, `HideFromSpec` | - - | `SwaggerWcfHeader` | `Method` | Configure method HTTP headers | `Name`, `Required`, `Description`, `DefaultValue` | - - | `SwaggerWcfPath` | `Method` | Configure a method in Swagger | `Summary`, `Description`, `OperationId`, `ExternalDocsDescription`, `ExternalDocsUrl`, `Deprecated` | - - | `SwaggerWcfParameter` | `Parameter` | Configure method parameters | `Required`, `Description`, `ParameterType` | - - | `SwaggerWcfProperty` | `Property` | Configure property parameters | `Required`, `Description`, `Minimum`, `Maximum`, `Default`, ... | - - | `SwaggerWcfResponse` | `Method` | Configure method return value | `Code`, `Description`, `EmptyResponseOverride`, `Headers` | - - | `SwaggerWcfDefinition` | `Class` | Configure a data type | `ExternalDocsDescription`, `ExternalDocsUrl` | - - | `SwaggerWcfReturnType` | `Method` | Override method return type | `ReturnType` | - - | `SwaggerWcfContentTypes` | `Method` | Override consume/produce content-types | `ConsumeTypes`, `ProduceTypes` | - - | `SwaggerWcfSecurity` | `Method` | Add security background to this method | `SecurityDefinitionName`, `params Scopes` | - - - - ## Tags - - - Tags are used to create categories in Swagger UI. - - - In SwaggerWcf they can also be used to hide or show elements from the Swagger output using the configuration file. - - - Using the configuration from step 4, any elements with the tag `LowPerformance` will be hidden from Swagger. - - - When a `SwaggerWcfTag` is added to an element, it may be configured with `HideFromSpec`. - - This will prevent this tag to be displayed in the Swagger output. - - - When combined with `SwaggerWcfHidden`, if the tag has the value `visible` as `true` in `web.config` file, the element will be visible - - - ## Query Parameter - - - To specify query parameters to a function you may use the following syntax - - - ```csharp - - [WebGet(UriTemplate = "/books?filter={filter}", BodyStyle = WebMessageBodyStyle.Bare)] - - Book[] ReadBooks(string filter = null); - - ``` - - - ## Optional Parameters - - - To specify a paramter as optional for swagger-ui provide a default value for the parameter on the interface. - - ```csharp - - public string Foo(string bar = null); - - ``` - - - ## Optional Properties - - - To mark a property as optional or required, use the `IsRequired` parameter on the `DataMember` attribute. - - - - ## TODO - - - * Add some options to configuration in `Web.config` - - * Tests - - - ## How to Improve It - - - Fork this project [abelsilva/swaggerwcf](https://github.com/abelsilva/swaggerwcf) and submit pull requests. -fleekjs/fleek-parser: '{"message":"Not - Found","documentation_url":"https://docs.github.com/rest/reference/repos#get-a-repository-readme"}' -pipermerriam/flex: > - # FLEX - - - [![Build Status](https://badgen.net/travis/pipermerriam/flex)](https://travis-ci.org/pipermerriam/flex) - - [![Documentation Status](https://readthedocs.org/projects/flex-swagger/badge/?version=latest)](https://readthedocs.org/projects/flex-swagger/?badge=latest) - - [![PyPi version](https://badgen.net/pypi/v/flex)](https://pypi.org/project/flex/) - - [![PyPi downloads](https://img.shields.io/pypi/dm/flex.svg)](https://pypi.python.org/pypi/flex) - - - Validation tooling for [Swagger 2.0](https://github.com/wordnik/swagger-spec/blob/master/versions/2.0.md) specifications. - - - - [Documentation on ReadTheDocs](http://flex-swagger.readthedocs.org/en/latest/) - - - ## Features - - - * Validate swagger schemas. - - * JSON Schema Validation - - * Validation of request/response objects against schema. - - * Command Line interface. - - - - # CLI Name Change - - - Starting in version 5.0.0 the CLI interface has been changed to `swagger-flex` - - due to a collision with the Apache Flex project. -yahehe/Nancy.Swagger: > - # Nancy.Swagger [![Build - status](https://ci.appveyor.com/api/projects/status/jm2q8t8y4u18n03r)](https://ci.appveyor.com/project/yahehe/nancy-swagger) - - - Nancy plugin for generated API documentation in Swagger format. - - - The Swagger specification (v2.0) can be found [here](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md). - - - ### Documentation - - - Documentation for Nancy.Swagger can be found in the [wiki pages](https://github.com/yahehe/Nancy.Swagger/wiki) - - - ### NuGet Packages - - - Versions 2.2.0+ of this code uses Nancy v2 and is designed for .NET 4.5.2 and .NET Standard 1.6. - - - Version 2.1.1 is designed for Nancy v1.4.3 on .Net 4.0+, and creates a Swagger 2.0 document. - - - Version 0.* is designed for Nancy v1.4.3, but creates a Swagger 1.2 document. - - If for some reason you need to make a change against this version of Nancy.Swagger, you can checkout the 1.4.3-stable branch. - - The code in this repository contains the code for the following NuGet packages: - - https://www.nuget.org/packages/Swagger.ObjectModel - - https://www.nuget.org/packages/Nancy.Swagger - - https://www.nuget.org/packages/Nancy.Swagger.Annotations - - - ### How to Contribute - - - Simply fork/clone this repository and start making whatever improvements you want! We'll try to make sure there are 'newbie' tickets available for those looking to start contributing. - - - ### CI NuGet Feed - - - The [CI NuGet feed](https://www.myget.org/gallery/nancy-swagger) can be found at https://www.myget.org/F/nancy-swagger/ -penx/openapi-mock: > - # OpenAPI Mock - - - CLI utility to start a mock server based upon a Swagger/OpenAPI JSON or YAML spec file. - - - Uses [swagger-node-runner](https://github.com/theganyo/swagger-node-runner) and [sway](https://github.com/apigee-127/sway). - - - ## Install - - - `npm install -g openapi-mock` - - - - ## Usage - - - ``` - - Usage: openapi-mock [options] - - - - Options: - - -V, --version output the version number - -m, --mock path to mock directory - -c, --config path to config file - -p, --port port to start the mock server on - -h, --help output usage information - ``` -apigee/undefined: '{"message":"Not - Found","documentation_url":"https://docs.github.com/rest/reference/repos#get-a-repository-readme"}' -xerions/phoenix_swagger: > - # PhoenixSwagger - - - [![Build Status](https://travis-ci.org/xerions/phoenix_swagger.svg?branch=master)](https://travis-ci.org/xerions/phoenix_swagger) - - [![Module Version](https://img.shields.io/hexpm/v/phoenix_swagger.svg)](https://hex.pm/packages/phoenix_swagger) - - [![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/phoenix_swagger/) - - [![Total Download](https://img.shields.io/hexpm/dt/phoenix_swagger.svg)](https://hex.pm/packages/phoenix_swagger) - - [![License](https://img.shields.io/hexpm/l/phoenix_swagger.svg)](https://github.com/xerions/phoenix_swagger/blob/master/LICENSE) - - [![Last Updated](https://img.shields.io/github/last-commit/xerions/phoenix_swagger.svg)](https://github.com/xerions/phoenix_swagger/commits/master) - - - `PhoenixSwagger` is the library that provides [swagger](http://swagger.io/) integration - - to the [phoenix](http://www.phoenixframework.org/) web framework. - - - Generate a swagger api specification from phoenix router and controllers - - Serve [swagger-ui](https://swagger.io/swagger-ui/) - - Validate requests against parameter schemas - - Validate responses against schemas in tests - - # Installation - - - Follow the [getting started guide](https://hexdocs.pm/phoenix_swagger/getting-started.html) to install and configure `PhoenixSwagger`. - - - # Guides - - - See the [full documentation on hexdocs.pm](https://hexdocs.pm/phoenix_swagger) or browse the [guides](https://github.com/xerions/phoenix_swagger/tree/master/guides) directory. - - - # Contributing - - - Issues and pull requests welcome. You'll also find help on the [#phoenix_swagger](https://elixir-lang.slack.com/messages/phoenix_swagger) channel on the [elixir-lang slack](https://elixir-lang.slack.com). - - - # License - - - [Mozilla Public License 2.0](./LICENSE) -apiaryio/fury-adapter-swagger: > - # Fury Swagger 2.0 Adapter - - - This repository has moved location to [API Elements: JS](https://github.com/apiaryio/api-elements.js). -fleekjs/fleek-response: '{"message":"Not - Found","documentation_url":"https://docs.github.com/rest/reference/repos#get-a-repository-readme"}' -marcelojaloto/SwagDoc: > - # SwagDoc - - SwagDoc is a Delphi library to generate swagger.json file for Swagger Spec version 2.0. Create a public documentation REST API using Swagger 2.0 for Delphi Language. SwagDoc's only responsibility is to generate the swagger.json file. The swagger.json file is responsible for containing all the documentation for your REST API. This file must be attached to the Swagger UI (User Interface) files. - - - [![PayPal donate button](https://user-images.githubusercontent.com/26885358/62580349-60bd8780-b87c-11e9-901e-425cf2a83671.png)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AW8TZ2QTDA7K8) - - - - ## Swagger (Open API) - version 2.0 - - - SwagDoc follows the specification 2.0 because it is more popular in the market and also because it is considered a more stable version to exist the longest. SwagDoc does not yet support the Swagger 3.0 version, but depending on the demand and contributions to the project it may evolve to support spec 3.0. - - - The main prerequisite for working with SwagDoc is to know the Swagger 2.0 specification that can be viewed in the link below. - - - https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md - - - https://swagger.io/docs/specification/2-0/basic-structure/ - - - When creating a Swagger documentation for your REST API you can produce a page like the following example. - - - https://app.swaggerhub.com/apis-docs/swagdoc/sample-api/v1 - - - ![image](https://user-images.githubusercontent.com/20048296/46588904-c6cd5880-ca79-11e8-8a8a-ec38ba7ff95a.png) - - - - ## Json Schema - - - https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#schemaObject - - - http://json-schema.org - - - - ## SwagDoc Speeches - - - https://www.youtube.com/watch?v=9U3HP3B5UT0 (Pt-Br) - - - https://www.youtube.com/watch?v=PhgMQAd8O6c (Pt-Br) - - - - ## Swagger References and Tutorials - - - https://swagger.io/swagger/media/blog/wp-content/uploads/2017/02/Documenting-An-Existing-API-with-Swagger-2.pdf - - - https://idratherbewriting.com/learnapidoc/pubapis_swagger_intro.html - - - - ## Swagger Tools - - - - Swagger: - - https://swagger.io - - - - Swagger Editor: - - https://editor.swagger.io - - - - Swagger Hub: - - https://swagger.io/tools/swaggerhub - - - - The classic swagger sample: - - http://petstore.swagger.io - - - - Tools and Integrations: - - https://swagger.io/tools/open-source/open-source-integrations - - - - ## Swagger UI distribution files - - - For you to produce a page containing a Swagger documentation you need the Swagger UI distribution files. - - - These files you can find in the github swagger-api / swagger-ui repository. - - - https://github.com/swagger-api/swagger-ui/tree/master/dist - - - ![image](https://user-images.githubusercontent.com/20048296/39937130-2925f868-5525-11e8-921d-c9ff0f59fefd.png) - - - - First you need to download the swagger user interface files and generate the swagger.json file. You then need to change the index.html file to indicate the relative path of the location where the swagger.json file is located on your web server that is hosting the swagger user interface files. - - - See an example below. - - - ![image](https://user-images.githubusercontent.com/20048296/39946376-49ad0df0-5544-11e8-8a5c-0980f5e6c257.png) -senchalabs/connect: > -
- - - connect logo - - - [![NPM Version][npm-version-image]][npm-url] - - [![NPM Downloads][npm-downloads-image]][npm-url] - - [![Build Status][github-actions-ci-image]][github-actions-ci-url] - - [![Test Coverage][coveralls-image]][coveralls-url] - - -
- - Connect is an extensible HTTP server framework for [node](http://nodejs.org) using "plugins" known as _middleware_. - - ```js - - var connect = require('connect'); - - var http = require('http'); - - - var app = connect(); - - - // gzip/deflate outgoing responses - - var compression = require('compression'); - - app.use(compression()); - - - // store session state in browser cookie - - var cookieSession = require('cookie-session'); - - app.use(cookieSession({ - keys: ['secret1', 'secret2'] - })); - - - // parse urlencoded request bodies into req.body - - var bodyParser = require('body-parser'); - - app.use(bodyParser.urlencoded({extended: false})); - - - // respond to all requests - - app.use(function(req, res){ - res.end('Hello from Connect!\n'); - }); - - - //create node.js http server and listen on port - - http.createServer(app).listen(3000); - - ``` - - - ## Getting Started - - - Connect is a simple framework to glue together various "middleware" to handle requests. - - - ### Install Connect - - - ```sh - - $ npm install connect - - ``` - - - ### Create an app - - - The main component is a Connect "app". This will store all the middleware - - added and is, itself, a function. - - - ```js - - var app = connect(); - - ``` - - - ### Use middleware - - - The core of Connect is "using" middleware. Middleware are added as a "stack" - - where incoming requests will execute each middleware one-by-one until a middleware - - does not call `next()` within it. - - - ```js - - app.use(function middleware1(req, res, next) { - // middleware 1 - next(); - }); - - app.use(function middleware2(req, res, next) { - // middleware 2 - next(); - }); - - ``` - - - ### Mount middleware - - - The `.use()` method also takes an optional path string that is matched against - - the beginning of the incoming request URL. This allows for basic routing. - - - ```js - - app.use('/foo', function fooMiddleware(req, res, next) { - // req.url starts with "/foo" - next(); - }); - - app.use('/bar', function barMiddleware(req, res, next) { - // req.url starts with "/bar" - next(); - }); - - ``` - - - ### Error middleware - - - There are special cases of "error-handling" middleware. There are middleware - - where the function takes exactly 4 arguments. When a middleware passes an error - - to `next`, the app will proceed to look for the error middleware that was declared - - after that middleware and invoke it, skipping any error middleware above that - - middleware and any non-error middleware below. - - - ```js - - // regular middleware - - app.use(function (req, res, next) { - // i had an error - next(new Error('boom!')); - }); - - - // error middleware for errors that occurred in middleware - - // declared before this - - app.use(function onerror(err, req, res, next) { - // an error occurred! - }); - - ``` - - - ### Create a server from the app - - - The last step is to actually use the Connect app in a server. The `.listen()` method - - is a convenience to start a HTTP server (and is identical to the `http.Server`'s `listen` - - method in the version of Node.js you are running). - - - ```js - - var server = app.listen(port); - - ``` - - - The app itself is really just a function with three arguments, so it can also be handed - - to `.createServer()` in Node.js. - - - ```js - - var server = http.createServer(app); - - ``` - - - ## Middleware - - - These middleware and libraries are officially supported by the Connect/Express team: - - - [body-parser](https://www.npmjs.com/package/body-parser) - previous `bodyParser`, `json`, and `urlencoded`. You may also be interested in: - - [body](https://www.npmjs.com/package/body) - - [co-body](https://www.npmjs.com/package/co-body) - - [raw-body](https://www.npmjs.com/package/raw-body) - - [compression](https://www.npmjs.com/package/compression) - previously `compress` - - [connect-timeout](https://www.npmjs.com/package/connect-timeout) - previously `timeout` - - [cookie-parser](https://www.npmjs.com/package/cookie-parser) - previously `cookieParser` - - [cookie-session](https://www.npmjs.com/package/cookie-session) - previously `cookieSession` - - [csurf](https://www.npmjs.com/package/csurf) - previously `csrf` - - [errorhandler](https://www.npmjs.com/package/errorhandler) - previously `error-handler` - - [express-session](https://www.npmjs.com/package/express-session) - previously `session` - - [method-override](https://www.npmjs.com/package/method-override) - previously `method-override` - - [morgan](https://www.npmjs.com/package/morgan) - previously `logger` - - [response-time](https://www.npmjs.com/package/response-time) - previously `response-time` - - [serve-favicon](https://www.npmjs.com/package/serve-favicon) - previously `favicon` - - [serve-index](https://www.npmjs.com/package/serve-index) - previously `directory` - - [serve-static](https://www.npmjs.com/package/serve-static) - previously `static` - - [vhost](https://www.npmjs.com/package/vhost) - previously `vhost` - - Most of these are exact ports of their Connect 2.x equivalents. The primary exception is `cookie-session`. - - - Some middleware previously included with Connect are no longer supported by the Connect/Express team, are replaced by an alternative module, or should be superseded by a better module. Use one of these alternatives instead: - - - `cookieParser` - - [cookies](https://www.npmjs.com/package/cookies) and [keygrip](https://www.npmjs.com/package/keygrip) - - `limit` - - [raw-body](https://www.npmjs.com/package/raw-body) - - `multipart` - - [connect-multiparty](https://www.npmjs.com/package/connect-multiparty) - - [connect-busboy](https://www.npmjs.com/package/connect-busboy) - - `query` - - [qs](https://www.npmjs.com/package/qs) - - `staticCache` - - [st](https://www.npmjs.com/package/st) - - [connect-static](https://www.npmjs.com/package/connect-static) - - Checkout [http-framework](https://github.com/Raynos/http-framework/wiki/Modules) for many other compatible middleware! - - - ## API - - - The Connect API is very minimalist, enough to create an app and add a chain - - of middleware. - - - When the `connect` module is required, a function is returned that will construct - - a new app when called. - - - ```js - - // require module - - var connect = require('connect') - - - // create app - - var app = connect() - - ``` - - - ### app(req, res[, next]) - - - The `app` itself is a function. This is just an alias to `app.handle`. - - - ### app.handle(req, res[, out]) - - - Calling the function will run the middleware stack against the given Node.js - - http request (`req`) and response (`res`) objects. An optional function `out` - - can be provided that will be called if the request (or error) was not handled - - by the middleware stack. - - - ### app.listen([...]) - - - Start the app listening for requests. This method will internally create a Node.js - - HTTP server and call `.listen()` on it. - - - This is an alias to the `server.listen()` method in the version of Node.js running, - - so consult the Node.js documentation for all the different variations. The most - - common signature is [`app.listen(port)`](https://nodejs.org/dist/latest-v6.x/docs/api/http.html#http_server_listen_port_hostname_backlog_callback). - - - ### app.use(fn) - - - Use a function on the app, where the function represents a middleware. The function - - will be invoked for every request in the order that `app.use` is called. The function - - is called with three arguments: - - - ```js - - app.use(function (req, res, next) { - // req is the Node.js http request object - // res is the Node.js http response object - // next is a function to call to invoke the next middleware - }) - - ``` - - - In addition to a plan function, the `fn` argument can also be a Node.js HTTP server - - instance or another Connect app instance. - - - ### app.use(route, fn) - - - Use a function on the app, where the function represents a middleware. The function - - will be invoked for every request in which the URL (`req.url` property) starts with - - the given `route` string in the order that `app.use` is called. The function is - - called with three arguments: - - - ```js - - app.use('/foo', function (req, res, next) { - // req is the Node.js http request object - // res is the Node.js http response object - // next is a function to call to invoke the next middleware - }) - - ``` - - - In addition to a plan function, the `fn` argument can also be a Node.js HTTP server - - instance or another Connect app instance. - - - The `route` is always terminated at a path separator (`/`) or a dot (`.`) character. - - This means the given routes `/foo/` and `/foo` are the same and both will match requests - - with the URLs `/foo`, `/foo/`, `/foo/bar`, and `/foo.bar`, but not match a request with - - the URL `/foobar`. - - - The `route` is matched in a case-insensitive manner. - - - In order to make middleware easier to write to be agnostic of the `route`, when the - - `fn` is invoked, the `req.url` will be altered to remove the `route` part (and the - - original will be available as `req.originalUrl`). For example, if `fn` is used at the - - route `/foo`, the request for `/foo/bar` will invoke `fn` with `req.url === '/bar'` - - and `req.originalUrl === '/foo/bar'`. - - - ## Running Tests - - - ```bash - - npm install - - npm test - - ``` - - - ## People - - - The Connect project would not be the same without all the people involved. - - - The original author of Connect is [TJ Holowaychuk](https://github.com/tj) - - - The current lead maintainer is [Douglas Christopher Wilson](https://github.com/dougwilson) - - - [List of all contributors](https://github.com/senchalabs/connect/graphs/contributors) - - - ## License - - - [MIT](LICENSE) - - - [coveralls-image]: https://badgen.net/coveralls/c/github/senchalabs/connect/master - - [coveralls-url]: https://coveralls.io/r/senchalabs/connect?branch=master - - [github-actions-ci-image]: https://badgen.net/github/checks/senchalabs/connect/master?label=ci - - [github-actions-ci-url]: https://github.com/jshttp/senchalabs/connect?query=workflow%3Aci - - [npm-downloads-image]: https://badgen.net/npm/dm/connect - - [npm-url]: https://npmjs.org/package/connect - - [npm-version-image]: https://badgen.net/npm/v/connect -Yelp/bravado: > - .. image:: - https://github.com/Yelp/bravado/workflows/build/badge.svg?branch=master - :target: https://github.com/Yelp/bravado/actions?query=workflow%3Abuild - - .. image:: https://img.shields.io/coveralls/Yelp/bravado.svg - :target: https://coveralls.io/r/Yelp/bravado - - .. image:: https://img.shields.io/pypi/v/bravado.svg - :target: https://pypi.python.org/pypi/bravado/ - :alt: PyPi version - - .. image:: https://img.shields.io/pypi/pyversions/bravado.svg - :target: https://pypi.python.org/pypi/bravado/ - :alt: Supported Python versions - - Bravado - - ========== - - - About - - ----- - - - Bravado is a Yelp maintained fork of `digium/swagger-py `__ - - for use with `OpenAPI Specification version 2.0 `__ (previously - - known as Swagger). - - - From the OpenAPI Specification project: - - The goal of The OpenAPI Specification is to define a standard, - language-agnostic interface to REST APIs which allows both humans and - computers to discover and understand the capabilities of the service - without access to source code, documentation, or through network traffic - inspection. - - Client libraries can automatically be generated from the OpenAPI specification, - - however Bravado aims to be a complete replacement for code generation - - (`swagger-codegen `__). - - - Example Usage - - ------------- - - - .. code-block:: Python - - from bravado.client import SwaggerClient - client = SwaggerClient.from_url('http://petstore.swagger.io/v2/swagger.json') - pet = client.pet.getPetById(petId=1).response().result - - Example with Basic Authentication - - --------------------------------- - - - .. code-block:: python - - from bravado.requests_client import RequestsClient - from bravado.client import SwaggerClient - - http_client = RequestsClient() - http_client.set_basic_auth( - 'api.yourhost.com', - 'username', 'password' - ) - client = SwaggerClient.from_url( - 'http://petstore.swagger.io/v2/swagger.json', - http_client=http_client, - ) - pet = client.pet.getPetById(petId=1).response().result - - Example with Header Authentication - - ---------------------------------- - - - .. code-block:: python - - from bravado.requests_client import RequestsClient - from bravado.client import SwaggerClient - - http_client = RequestsClient() - http_client.set_api_key( - 'api.yourhost.com', 'token', - param_name='api_key', param_in='header' - ) - client = SwaggerClient.from_url( - 'http://petstore.swagger.io/v2/swagger.json', - http_client=http_client, - ) - pet = client.pet.getPetById(petId=1).response().result - - Example with Fido Client (Async Http Client) - - -------------------------------------------- - - - .. code-block:: python - - # Install bravado with fido extra (``pip install bravado[fido]``) - from bravado.fido_client import FidoClient - from bravado.client import SwaggerClient - - http_client = FidoClient() - client = SwaggerClient.from_url( - 'http://petstore.swagger.io/v2/swagger.json', - http_client=http_client, - ) - pet = client.pet.getPetById(petId=1).response().result - - Documentation - - ------------- - - - More documentation is available at http://bravado.readthedocs.org - - - Installation - - ------------ - - - .. code-block:: bash - - # To install bravado with Synchronous Http Client only. - $ pip install bravado - - # To install bravado with Synchronous and Asynchronous Http Client (RequestsClient and FidoClient). - $ pip install bravado[fido] - - Development - - =========== - - - Code is documented using `Sphinx `__. - - - `virtualenv `__. is - - recommended to keep dependencies and libraries isolated. - - - Setup - - ----- - - - .. code-block:: bash - - # Run tests - tox - - # Install git pre-commit hooks - tox -e pre-commit install - - Contributing - - ------------ - - - 1. Fork it ( http://github.com/Yelp/bravado/fork ) - - 2. Create your feature branch (``git checkout -b my-new-feature``) - - 3. Add your modifications - - 4. Commit your changes (``git commit -m "Add some feature"``) - - 5. Push to the branch (``git push origin my-new-feature``) - - 6. Create new Pull Request - - - Releasing a new version (Yelpers only) - - -------------------------------------- - - See https://yelpwiki.yelpcorp.com/pages/viewpage.action?pageId=19022447 - - - License - - ------- - - - Copyright (c) 2013, Digium, Inc. All rights reserved. - - Copyright (c) 2014-2021, Yelp, Inc. All rights reserved. - - - Bravado is licensed with a `BSD 3-Clause - - License `__. -stackia/test2doc.js: > - # test2doc.js - Build API docs from your tests - - - [![npm](https://img.shields.io/npm/l/test2doc.svg)](https://www.npmjs.com/package/test2doc) [![npm](https://img.shields.io/npm/v/test2doc.svg)](https://www.npmjs.com/package/test2doc) [![CI](https://github.com/stackia/test2doc.js/actions/workflows/ci.yml/badge.svg)](https://github.com/stackia/test2doc.js/actions/workflows/ci.yml) [![Coverage Status](https://coveralls.io/repos/github/stackia/test2doc.js/badge.svg)](https://coveralls.io/github/stackia/test2doc.js) - - - test2doc.js helps you seamlessly integrate API documentation generation to your test flow. - - - You write something like this: - - - ```javascript - - const doc = require('test2doc') - - const request = require('supertest') // We use supertest as the HTTP request library - - require('should') // and use should as the assertion library - - - // For Koa, you should exports app.listen() or app.callback() in your app entry - - const app = require('./my-express-app.js') - - - after(function () { - doc.emit('api-documentation.apib') // Or doc.emit('api-documentation.yaml', 'swagger') if you like Swagger - }) - - - doc.group('Products').is((doc) => { - describe('#Products', function () { - doc.action('Get all products').is((doc) => { - it('should get all products', function () { - // Write specs towards your API endpoint as you would normally do - // Just decorate with some utility methods - return request(app) - .get(doc.get('/products')) - .query( - doc.query({ - minPrice: doc - .val( - 10, - 'Only products of which price >= this value should be returned' - ) - .required(), - }) - ) - .expect(200) - .then((res) => { - doc.resHeaders(res.headers) - body = doc.resBody(res.body) - body.desc('List of all products').should.not.be.empty() - body[0].should.have.properties('id', 'name', 'price') - body[0].price.desc('Price of this product').should.be.a.Number() - }) - }) - }) - }) - }) - - ``` - - - And then test2doc.js will capture all the info provided by you via `doc.get` / `doc.query` / `doc.resBody` / `myVar.desc`. You can choose a generator to generate the final documents based on these collected information. Since we capture every thing we need from tests, you will always get up-to-date documents. - - - Currently we provide [**API Blueprint**](https://apiblueprint.org/) generator and [**Swagger**](http://swagger.io/) generator. - - - test2doc.js is not designed to run on a specified test framework, which means you can use this in conjunction with any test frameworks and assertion libraries. - - - We provide an extension for supertest called [supertest-test2doc](https://github.com/stackia/supertest-test2doc), which makes it much easier to integrate test2doc.js with [supertest](https://github.com/visionmedia/supertest). - - - ## Installation - - - Install test2doc.js as an npm module and save it to your package.json file as a development dependency: - - - ``` - - npm install test2doc --save-dev - - ``` - - - Once installed it can now be referenced by simply calling `require('test2doc')`. - - - _The npm package name is `test2doc` without `.js` suffix._ - - - ## Getting Started - - - First require this library, for convenience we use `doc` as the imported variable name: - - - ```javascript - - const doc = require('test2doc') - - ``` - - - test2doc.js has two core concepts: `group` and `action`. A `group` is a collection of `action`s and child `group`s, and an `action` describes a real API endpoint (HTTP method / url / queries / request body / response body / headers). Like a tree, `action`s are leaf nodes and `group`s are non-leaf nodes. - - - The `doc` variable imported here is the root `group`. When you call `doc.group('Name of this subgroup')`, it returns a new object represents the sub `group`, which has exactly the same interfaces as the root `group`. - - - When you call `doc.action('Name of this action')`, it returns a new object represents the `action`, which has different interfaces compared to `group`. - - - For convenience, we usually use the variable name `doc` all the way to make it easy to write clean codes. - - - Some methods of `group` object are: - - - - `doc.title(title)` - set title of this group - - - `doc.desc(...descriptions)` - give descriptions for this group - - - `doc.basePath(basePath)` - set base path for this group - - - `doc.group(childGroupTitle)` - create a child group, returns the child group - - - Some methods of `action` object are: - - - - `doc.get(url, parameters)` - Capture a string as the url, returns this url so you call pass to your HTTP request library - - - `doc.resBody(body)` - Capture an object as the response body, returns an proxy of this object - - - _Full list can be found at [API references](#api-references) section._ - - - Methods like `doc.resBody(body)` / `doc.val(value, ...descriptions)` and so on returns an [ES6 Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) of the object passed in. So we can add custom methods to these objects like `desc(...descriptions)`, `required()`, etc. However because JS doesn't allow proxying non-object value (number / null / undefined etc.), we will create wrapper objects around these values. If these wrapper objects don't work well with your assertion / request library, you can use `doc.uncapture(object)` to get the original value. - - - Once you have collected all the info needed to build the documentations, call `emit` on the root group to emit the actual documentation file. Generally you will do this in a global `after` hook. - - - ## API references - - - ### Group - - - #### Methods - - - - `title (title)` - set title of this group - - return: this group - - `desc (...descriptions)` - give descriptions for this group - - A group can have multiple descriptions. Generally each description will be rendered as a paragraph. - - return: this group - - `scheme (...schemes)` - set supported schemes on this group - - e.g. `scheme('http', 'https', 'ws', 'wss')` - - return: this group - - `host (host)` - set hostname for this group - - Only hostname, without 'http://' or trailing slash. - - return: this group - - `version (version)` - set API version for this group - - return: this group - - `basePath (basePath, parameters)` - set base path for this group - - e.g. `basePath('/v0/product/:id', { id: doc.val('123', 'Product ID') })` - - return: this group - - `val (value, ...descriptions)` - capture an value and give it descriptions - - return: a proxy of `value` - - `params (parameters)` - describe parameters for the base path - - Same as the second parameter in `basePath(basePath, parameters)` - - return: this group - - `query (queries)` - describe queries for the base path - - return: this group - - `reqHeaders (headers)` - describe common request headers for all actions in this group - - e.g. `doc.reqHeaders({ 'x-my-header': 'foobar', 'x-my-array-header': ['value1', 'value2'] })` - - return: this group - - `group (title)` - create a child group titled `title` - - return: the newly created child group - - `action (title)` - create an action titled `title` belonging to this group - - return: the newly created action - - `is (collectFn)` - call `collectFn` with this group as the first argument - - Usually used in chaining call. - - e.g. `doc.group('a child group').is(doc => { ... })`, first `doc` refers to the parent group, second `doc` refers to the child group - - return: this group, or a promise if `collectFn` returns a promise, which will be resolved with this group when the promise returned by `collectFn` finishes. - - `uncapture (object, shouldSliceArray = false)` - uncapture an object (strip the proxy) - - If `shouldSliceArray` is true, then any array in `object` will be subsetted according to offset() and limit() set on it. - - return: an uncaptured object, with all its children and nested children uncaptured - - `emit (file, generator = 'apib', options = {})` - generate the actual documentation file - - `file` can be a filename or a file descriptor. It's the same object passed into `fs.writeFileSync`. - - If `file` is omitted, the generated text will be the return value. - - Available generators: `apib` / `swagger` - - return: void - - ### Action - - - #### Methods - - - - `get/post/put/delete/...(url, parameters)` - shortcut of `method(method).url(url, parameters)` - - Supports all methods provided by npm package [methods](https://www.npmjs.com/package/methods). - - return: the url with parameters filled in - - `method (method)` - set request method of this action - - return: this action - - `title (title)` - set title of this action - - return: this action - - `desc (...descriptions)` - give descriptions for this action - - return: this action - - `url (url, parameters)` - describe url and url parameters for this action - - `url` can be [an express-route-style path](https://expressjs.com/en/guide/routing.html#route-paths), which can include parameters - - use `parameters` to describe parameters in the url - - return: the url with parameters filled in - - `val (value, ...descriptions)` - Same as `group`.`val` - - - `anotherExample ()` - as a seperator between different exapmles - - an example = params + query + reqBody + resBody - - return: this action - - e.g. - - ``` - - doc.params ...blahblah... doc.query ...blahblah... doc.reqBody ...blahblah... doc.resBody - - doc.anotherExample() // Divide into two examples in a same code block - - doc.params ...blahblah... doc.query ...blahblah... doc.reqBody ...blahblah... doc.resBody - - ``` - - - - `params (parameters, returnProxy = false)` - Same as `group`.`params`, except this is for action - - - `query (queries, returnProxy = false)` - Same as `group`.`query`, except this is for action - - - `reqHeader (name, value, returnProxy = false)` - describe a single header for this action - - e.g. `doc.reqHeader('authorization', 'Bearer 123456')` returns `['authorization', 'Bearer 123456']` - - return: an array with two items, `name` and `value` - - `reqHeaders (headers, returnProxy = false)` - describe request headers for this action - - e.g. `doc.reqHeaders({ 'x-my-header': 'foobar', 'x-my-array-header': ['value1', 'value2'] })` - - return: the `headers` object passed in, or a proxy of `headers` if `returnProxy` is true - - `reqBody (body, description, returnProxy = false)` - Capture an object as the request body and give it a description - - return: the `body` object passed in, or a proxy of `body` if `returnProxy` is true - - `resHeaders (headers)` - describe response headers for this action - - e.g. `doc.resHeaders({ 'content-type': 'application-json', 'x-total-page': '16' })` - - return: a proxy of `headers` - - `status (statusCode)` - describe the response HTTP status code for this action - - return: the `statusCode` passed in - - `resBody (body)` - Capture an object as the response body - - return: a proxy of `body` - - `is (collectFn)` - Same as `group`.`is`, except the parameter passed to `collectFn` is this action - - - `uncapture (object)` - Same as `group`.`uncapture` - - - ### Captured Objects - - - #### Methods - - - - `desc (...descriptions)` - give descriptions for this object - - return: this captured object - - `required ()` - mark this as required - - return: this captured object - - `optional ()` - mark this as optional (opposite to `required()`) - - return: this captured object - - `nullable (nullable = true)` - mark this as nullable or non-nullable - - return: this captured object - - `fixed (fixed = true)` - mark this as [fixed](https://apiblueprint.org/documentation/mson/specification.html#353-type-attribute) - - return: this captured object - - `fixedType (fixedType = true)` - mark this as [fixed-type](https://apiblueprint.org/documentation/mson/specification.html#353-type-attribute) - - return: this captured object - - `enum (...possibleValues)` - mark this should be a member of `possibleValues` - - return: this captured object - - `default (defaultValue)` - mark the default value for this - - return: this captured object - - `sample (...sampleValues)` - give a sample value for this - - return: this captured object - - `offset (offset)` - specify the offset in the array to be included in the documents - - Only makes sense if this is an array - - Useful if you only want to include a subset of this array in the documents - - return: this captured object - - `limit (limit)` - specify the number of items from the offset in the array to be included in the documents - - Only makes sense if this is an array - - Useful if you only want to include a subset of this array in the documents - - return: this captured object - - `uncapture (shouldSliceArray = false)` - uncapture this - - If `shouldSliceArray` is true, then any array in this object will be subsetted according to offset() and limit() set on it. - - return: the uncaptured original object for this - - ## Roadmap - - - - [x] Add tests and integrate with Travis CI - - - [x] Swagger support - - - [x] Write [an extension for supertest](https://github.com/stackia/supertest-test2doc) to simplify grammer - - - [ ] Incremental document generation - - - [ ] CONTRIBUTION guide - - - [ ] An official website - - - ## License - - - The project is released under [MIT License](https://github.com/stackia/test2doc.js/blob/master/LICENSE). -RobWin/assertj-swagger: > - = assertj-swagger - - :author: Robert Winkler - - :version: 0.9.0 - - :hardbreaks: - - - image:https://travis-ci.org/RobWin/assertj-swagger.svg["Build Status", link="https://travis-ci.org/RobWin/assertj-swagger"] image:https://coveralls.io/repos/RobWin/assertj-swagger/badge.svg?branch=master["Coverage Status", link="https://coveralls.io/r/RobWin/assertj-swagger"] image:https://api.bintray.com/packages/robwin/maven/assertj-swagger/images/download.svg[link="https://bintray.com/robwin/maven/assertj-swagger/_latestVersion"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"] image:https://img.shields.io/badge/Twitter-rbrtwnklr-blue.svg["Twitter", link="https://twitter.com/rbrtwnklr"] - - - == Overview - - - assertj-swagger is a https://github.com/joel-costigliola/assertj-core[assertj] library which compares a contract-first https://github.com/swagger-api/swagger-spec[Swagger] YAML/JSON file with a code-first Swagger JSON output (e.g. from https://github.com/springfox/springfox[springfox] or https://github.com/swagger-api/swagger-core/wiki/Java-JAXRS-Quickstart[JAX-RS Swagger]). assertj-swagger allows to validate that the API implementation is in compliance with a contract specification for two test patterns: Documentation Driven Contracts and Consumer Driven Contracts. - - - The Documentation Driven Contracts test pattern, useful for public APIs, validates using `#isEqualTo` and will validate that the design first documentation contract matches the implementation in its entirety. - - - The Consumer Driven Contracts test pattern, useful for internal microservice APIs, validates using `#satisfiesContract` and will validate that the implementation provides, at minimum, the requirements of the design first consumer contract. This pattern allows for extension points in the API resources, resource methods, and models. - - - The library supports the Swagger v2.0 specification. assertj-swagger compares Swagger objects like Paths, Parameters and Definitions. It does not compare __unimportant__ Swagger objects like info, descriptions or summaries. - - - == Usage guide - - - === Adding assertj-swagger to your project - - The project is published in JCenter and Maven Central. - - - ==== Maven - - - [source,xml, subs="specialcharacters,attributes"] - - ---- - - - - - false - - central - bintray - http://jcenter.bintray.com - - - - - - io.github.robwin - assertj-swagger - {version} - - - ---- - - - ==== Gradle - - - [source,groovy, subs="attributes"] - - ---- - - repositories { - jcenter() - } - - - compile "io.github.robwin:assertj-swagger:{version}" - - ---- - - - === Using assertj-swagger in an integration test - - - Using assertj-swagger is simple. For example, if you are using https://github.com/spring-projects/spring-boot[Spring Boot] and https://github.com/springfox/springfox[springfox] or https://github.com/swagger-api/swagger-core/wiki/Java-JAXRS-Quickstart[JAX-RS Swagger], you can validate your Swagger JSON in an integration test. - - - The following code sample shows how to validate an API using the Documentation Driven Contract test pattern: - - - [source, java] - - ---- - - @RunWith(SpringJUnit4ClassRunner.class) - - @SpringApplicationConfiguration(classes = Application.class) - - @IntegrationTest - - @WebAppConfiguration - - public class AssertjSwaggerDocumentationDrivenTest { - @Test - public void validateThatImplementationMatchesDocumentationSpecification(){ - String designFirstSwagger = SwaggerAssertTest.class.getResource("/swagger.yaml").getPath(); - SwaggerAssertions.assertThat("http://localhost:8080/v2/api-docs") - .isEqualTo(designFirstSwagger); - } - } - - ---- - - - The following code sample shows how to validate an API using the Consumer Driven Contract test pattern: - - - [source, java] - - ---- - - @RunWith(SpringJUnit4ClassRunner.class) - - @SpringApplicationConfiguration(classes = Application.class) - - @IntegrationTest - - @WebAppConfiguration - - public class AssertjSwaggerConsumerDrivenTest { - @Test - public void validateThatImplementationSatisfiesConsumerSpecification(){ - String designFirstSwagger = SwaggerAssertTest.class.getResource("/swagger-consumer1.yaml").getPath(); - SwaggerAssertions.assertThat("http://localhost:8080/v2/api-docs") - .satisfiesContract(designFirstSwagger); - } - } - - ---- - - - ==== Example output - - - For Documentation Driven Contract tests, Assertj-swagger fails a test if it finds differences between the implementation and the specification. - - - [source] - - ---- - - The following 4 assertions failed: - - 1) [Checking Paths] - - Expecting: - <["/api/pet", "/api/pet/findByStatus", "/api/pet/findByTags", "/api/pet/{petId}", "/api/store/order", "/api/store/order/{orderId}", "/api/user", "/api/user/createWithArray", "/api/user/createWithList", "/api/user/login", "/api/user/logout", "/api/user/{username}"]> - to contain only: - <["/pets", "/pets/findByStatus", "/pets/findByTags", "/pets/{petId}", "/stores/order", "/stores/order/{orderId}", "/users", "/users/createWithArray", "/users/createWithList", "/users/login", "/users/logout", "/users/{username}"]> - elements not found: - <["/pets/findByTags", "/users/logout", "/users", "/stores/order", "/users/createWithArray", "/pets", "/users/createWithList", "/pets/findByStatus", "/pets/{petId}", "/users/{username}", "/stores/order/{orderId}", "/users/login"]> - and elements not expected: - <["/api/store/order", "/api/user", "/api/user/createWithList", "/api/pet", "/api/pet/findByTags", "/api/user/createWithArray", "/api/user/login", "/api/pet/{petId}", "/api/store/order/{orderId}", "/api/user/{username}", "/api/pet/findByStatus", "/api/user/logout"]> - - 2) [Checking properties of definition 'Order'] - - Expecting: - <["complete", "id", "identifier", "petId", "quantity", "shipDate", "status"]> - to contain only: - <["id", "petId", "quantity", "shipDate", "status", "complete"]> - elements not found: - <[]> - and elements not expected: - <["identifier"]> - - 3) [Checking properties of definition 'User'] - - Expecting: - <["email", "firstName", "id", "identifier", "lastName", "password", "phone", "userStatus", "username"]> - to contain only: - <["id", "username", "firstName", "lastName", "email", "password", "phone", "userStatus"]> - elements not found: - <[]> - and elements not expected: - <["identifier"]> - - 4) [Checking properties of definition 'Pet'] - - Expecting: - <["category", "id", "identifier", "name", "photoUrls", "status", "tags"]> - to contain only: - <["id", "category", "name", "photoUrls", "tags", "status"]> - elements not found: - <[]> - and elements not expected: - <["identifier"]> - ---- - - - For Consumer Driven Contract tests, Assertj-swagger fails a test if it finds missing resources, methods, models, or properties in the implementation which are required by the consumer specification. - - - [source] - - ---- - - The following 4 assertions failed: - - 1) [Checking Paths] - - Expecting: - <["/pets", "/pets/findByStatus", "/pets/findByTags", "/pets/{petId}", "/stores/order", "/stores/order/{orderId}", "/users", "/users/createWithArray", "/users/createWithList", "/users/login", "/users/logout", "/users/{username}"]> - to contain: - <["/animals/{animalId}", "/pets", "/pets/findByStatus", "/pets/{petId}"]> - but could not find: - <["/animals/{animalId}"]> - - 2) [Checking Definitions] - - Expecting: - <["User", "Category", "Pet", "Tag", "Order"]> - to contain: - <["Category", "Pet", "Animal", "Tag"]> - but could not find: - <["Animal"]> - - 3) [Checking properties of definition 'Pet'] - - Expecting: - <["id", "category", "name", "photoUrls", "tags", "status"]> - to contain: - <["photoUrls", "extraProperty", "name", "id", "category", "tags", "status"]> - but could not find: - <["extraProperty"]> - - 4) [Checking property 'extraProperty' of definition 'Pet'] - - Expecting actual not to be null - - ---- - - - === Using assertj-swagger in a unit test - - - If you are using the https://github.com/spring-projects/spring-framework[spring-framework] and https://github.com/springfox/springfox[springfox], Spring's MVC Test framework can also be used to validate the Swagger JSON output against your contract-first Swagger specification. - - That way you can make sure that the implementation is in compliance with the design specification. - - - The following code sample shows how to write a unit test using the Documentation Driven Contract test pattern: - - - [source, java] - - ---- - - @Test - - public void validateThatImplementationFitsDesignSpecification() throws Exception { - String designFirstDocumentationSwaggerLocation = Swagger2MarkupTest.class.getResource("/swagger.yaml").getPath(); - - MvcResult mvcResult = this.mockMvc.perform(get("/v2/api-docs") - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andReturn(); - - String springfoxSwaggerJson = mvcResult.getResponse().getContentAsString(); - SwaggerAssertions.assertThat(new SwaggerParser().parse(springfoxSwaggerJson)).isEqualTo(designFirstDocumentationSwaggerLocation); - } - - ---- - - - The following code sample shows how to write a unit test using the Consumer Driven Contract test pattern: - - - [source, java] - - ---- - - @Test - - public void validateThatImplementationFitsDesignSpecification() throws Exception { - String designFirstConsumerSwaggerLocation = Swagger2MarkupTest.class.getResource("/swagger-consumer1.yaml").getPath(); - - MvcResult mvcResult = this.mockMvc.perform(get("/v2/api-docs") - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andReturn(); - - String springfoxSwaggerJson = mvcResult.getResponse().getContentAsString(); - SwaggerAssertions.assertThat(new SwaggerParser().parse(springfoxSwaggerJson)).satisfiesContract(designFirstConsumerSwaggerLocation); - } - - ---- - - - === Customizing assertj-swagger's behaviour - - - For most use cases, the default behaviour will be sufficient. However, you can override the default behaviour in various ways by placing a Java property file, `/assertj-swagger.properties`, at the root of your classpath. It is also possible to override the configuration in your tests; construct an instance of the `SwaggerAssert` class with a custom configuration if this is required. - - - The following overrides are available: - - - ==== Disable various types of checks which are enabled by default - - - * `assertj.swagger.validateDefinitions=false`: disable all validation of definitions - - ** `assertj.swagger.validateProperties=false`: disable validation of properties of definitions - - *** `assertj.swagger.validateRefProperties=false`: disable validation of reference (`$ref`) properties of definitions - - *** `assertj.swagger.validateArrayProperties=false`: disable validation of array properties of definitions - - *** `assertj.swagger.validateByteArrayProperties=false`: disable validation of byte-array properties of definitions - - *** `assertj.swagger.validateStringProperties=false`: disable validation of string properties of definitions - - ** `assertj.swagger.validateModels=false`: disable validation of models - - * `assertj.swagger.validatePaths=false`: disable all validation of endpoint definitions - - * `assertj.swagger.validateResponseWithStrictlyMatch=false`: allow actual contract return extra return code - - - ==== Enable various types of checks which are disabled by default - - - The following settings are disabled by default, as they will cause schema comparisions to be too brittle for many users. They can be enabled if required. - - - * `assertj.swagger.validateInfo=true`: enable comparison of the info section - - * `assertj.swagger.validateVersion=true`: enable comparison of the schema version numbers - - - ==== Disable checks for certain paths or definitions in 'actual' schema - - - This feature is useful in development situations, where you have written a contract-first schema by hand, and are validating a contract-last schema generated by a partially-implemented API. - - - To ignore unimplemented endpoints, try something like: - - - [source] - - ---- - - assertj.swagger.pathsToIgnoreInExpected=\ - /v1/friends/{id},\ - /v1/groups/{groupId} - ---- - - - To ignore unimplemented definitions, use something like: - - - [source] - - ---- - - assertj.swagger.definitionsToIgnoreInExpected=\ - Foo,\ - Bar - ---- - - - To ignore unimplemented properties, use something like: - - - [source] - - ---- - - assertj.swagger.propertiesToIgnoreInExpected=\ - Foo.prop1,\ - Bar.prop2 - ---- - - - - ==== Comparing expected and actual paths in schemas - - - It is occasionally useful to be able to compare schemas, where due to limitations in tools and libraries, endpoint - - paths don't align. Specifying a `basePath` setting in your design-first schema here won't work -- it's only used by - - Swagger tooling to generate paths at runtime, and does *not* form part of the logical pathname of your endpoints. - - For instance, in your design-first schema, you may specify a set of endpoints and a `basePath`, while your generated - - schema (generated from, say, Springfox) has a common prefix prepended on the endpoint paths; e.g.: - - - [source] - - ---- - - /pets/findByStatus ! design-first schema - - ---- - - - and - - - [source] - - ---- - - /v2/pets/findByStatus ! actual schema - - ---- - - - To ensure that assertj-swagger is comparing like-with-like in this situation, you could use the following in your - - configuration file: - - - [source] - - ---- - - assertj.swagger.pathsPrependExpected=/v2 - - ---- - - - - == License - - - Copyright 2015 Robert Winkler - - - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -mobilcom-debitel/got-swag: > - # Got Swag? - - - A tool to test Swagger-powered APIs automatically through monkey testing. - - Also allows for custom tests written directly in Swagger files - - or in separate test suites. - - Includes command-line and programmatic interfaces. - - Install via `npm install got-swag -g`. - - - ## Usage - - - ``` - - got-swag ... [-m] [-t ] [-T] [-v] [-w] - Test a Swagger URL or file (YAML). Additional files are merged. - - Options: - -m, --monkey Run monkey tests on GET endpoints - -l, --monkey-limit Maximum number of parameter combinations for each - monkey GET, default is 50 - -t, --timeout Set a timeout (in milliseconds) for test step execution, - default is 2000 ms - -T, --trace Trace: Log requests and responses - -V, --version Show version - -w, --watch Watch the Swagger files and rerun tests on changes - ``` - - - Most Mocha options are valid. See https://mochajs.org/#usage for details. - - - - ## Monkey Testing - - - The most basic usage of `got-swag` is monkey testing: - - Each GET endpoint of a service is validated using minimal variable - - input, if any, and the definitions from the services' Swagger file. - - The endpoints are requested with random authentication/variable combinations - - until one combination leads to a response status code less than 400. - - - Just invoke got-swag on a URL with the `-m` switch: - - - ``` - - got-swag http://petstore.swagger.io/v2/swagger.json -m - - ``` - - - See [monkeystore.yaml](examples/monkeystore.yaml) for an example of input variables. - - - - ## Custom Tests - - - Additionally, `got-swag` allows to embed custom tests in Swagger files - - or separate test suites. - - The test steps are written in JS using a small domain-specific language. - - Every step is evaluated, even if a previous step failed. - - - For example, see [petstore.yaml](examples/petstore.yaml) (embedded) and - - [yoda.yaml](examples/yoda.yaml) (separate). - - - - ## Test Syntax Reference - - - ### [Assertions](https://nodejs.org/api/assert.html) - - - - `ok( actual )` - - - `equal( actual, expected )` - - - `notEqual( actual, expected )` - - - `deepEqual( actual, expected )` - - - `notDeepEqual( actual, expected )` - - - `strictEqual( actual, expected )` - - - `notStrictEqual( actual, expected )` - - - `deepStrictEqual( actual, expected )` - - - `notDeepStrictEqual( actual, expected )` - - - `match( actualString, expectedPattern )` - - - ### Validation - - - - `validate( data, schema )` - - Validate JSON data against a [JSON schema](http://json-schema.org/) - - If `data` or `schema` are omitted (strictly equal to `undefined`), - the last response is validated against the current operation's response schema - - ### Requests - - - - `request( options )` - - Requests the current endpoint - - `options` is optional, see [http](https://nodejs.org/api/http.html) - - `options.data` sets the request body - - Shortcuts: - - `get( url, headers )` - - `post( url, data, headers )` - - `put( url, data, headers )` - - `delete( url, headers )` - - `options( url, headers )` - - `head( url, headers )` - - Use `null` for `url` to request the current endpoint - - `headers` are optional - - ### Authentication - - - - `auth( securityDefinitionId, credentials, scopes )` - - Authenticates against a security definition - - `scopes` are optional and inferred from the API if possible - - ### Utility - - - - `encodeURIComponent( s )` encodes a string for URI transmission - - - `log( value )` logs a value - - - `stringify( value )` alias of JSON.stringify - - - `parse( string )` alias of JSON.parse - - - `byteLength( string )` alias of Buffer.byteLength for computing 'Content-Length' header manually - - - `monkeyAuth()` tries to authenticate using known method/credentials - - - `monkeyGet()` tries to GET using known parameters - - - ### Variables - - - - `vars`: Variables reusable for all tests - - You can write to `vars` in test steps, see example - - `req`: Last request data - - - `res`: Last response data - - `res.statusCode`: Integer response status code - - `res.headers`: Response headers - - `res.body`: String response body - - `res.json`: Parsed JSON response, if any - - `api`: Complete Swagger API - - - ### Extension Syntax - - - You can define extension Swagger files on top of existing Swagger files - - using the `'#/path': value` syntax. - - For reference, see [extended-petstore.yaml](examples/extended-petstore.yaml). - - - - ## Programmatic Usage - - - ```js - - var gotSwag = require( 'got-swag' ); - - - // test api and report as JSON - - gotSwag.test( 'swag.yaml', 'vars.yaml' ).then( function ( report ) { - console.log( report ); - } ); - - - // describe mocha tests in current suite - - describe( 'My test suite', function () { - gotSwag.describe( 'swag.yaml', 'vars.yaml', { parent: this } ); - } ); - - ``` - - - - ## Notes - - - - Currently, `got-swag` only supports JSON - - - The DSL is sandboxed using [vm](https://nodejs.org/api/vm.html) - - - If you see something like - `.../node_modules/got-swag/lib/validate.js:24 throw new Error( result.errors );` - in your console, it's a [Node.js Bug](https://github.com/nodejs/node/issues/7397) -metosin/ring-swagger: > - # Ring-Swagger [![Build - Status](https://travis-ci.org/metosin/ring-swagger.svg?branch=master)](https://travis-ci.org/metosin/ring-swagger) - [![Downloads](https://versions.deps.co/metosin/ring-swagger/downloads.svg)](https://versions.deps.co/metosin/ring-swagger) - - - [Swagger](http://swagger.io/) 2.0 implementation for Clojure/Ring using [Plumatic Schema](https://github.com/Plumatic/schema) (support for [clojure.spec](http://clojure.org/about/spec) via [spec-tools](https://github.com/metosin/spec-tools)). - - - - Transforms deeply nested Schemas into Swagger JSON Schema definitions - - - Extended & symmetric JSON & String serialization & coercion - - - Middleware for handling Schemas Validation Errors & Publishing swagger-data - - - Local api validator - - - Swagger artifact generation - - [swagger.json](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#specification) via `ring.swagger.swagger2/swagger-json` - - [Swagger UI](https://github.com/swagger-api/swagger-ui) bindings. (get the UI separately as [jar](https://github.com/metosin/ring-swagger-ui) or from [NPM](https://www.npmjs.com/package/swagger-ui)) - - ## Latest version - - - [![Clojars Project](http://clojars.org/metosin/ring-swagger/latest-version.svg)](http://clojars.org/metosin/ring-swagger) - - - The [CHANGELOG](https://github.com/metosin/ring-swagger/blob/master/CHANGELOG.md). - - - Requires Java 1.8+ - - - ## Web libs using Ring-Swagger - - - - [Compojure-Api](https://github.com/metosin/compojure-api) for Compojure - - - [fnhouse-swagger](https://github.com/metosin/fnhouse-swagger) for fnhouse - - - [route-swagger](https://github.com/frankiesardo/route-swagger) for Pedestal - - - [yada](https://github.com/juxt/yada) - - - [kekkonen](https://github.com/metosin/kekkonen) - - - ## Getting help - - - [Clojurians slack](https://clojurians.slack.com/) ([join](http://clojurians.net/)) has a channel [#ring-swagger](https://clojurians.slack.com/messages/ring-swagger/) for Ring-swagger related issues. You can also ask questions about Ring-swagger on other channels at Clojurians Slack or at #clojure on Freenode IRC (mention or `ring-swagger` to highlight us). - - - ## Info - - - Route definitions are expected as a clojure Map defined by the Schema [Contract](https://github.com/metosin/ring-swagger/blob/master/src/ring/swagger/swagger2_schema.clj). - - The Schema allows mostly any extra keys as ring-swagger tries not to be on your way - one can pass any valid Swagger spec data in. - - - [API Docs](http://metosin.github.io/ring-swagger/doc/). - - - ### Simplest possible example - - - ```clojure - - (require '[ring.swagger.swagger2 :as rs]) - - - (rs/swagger-json {}) - - - ; {:swagger "2.0", - - ; :info {:title "Swagger API", :version "0.0.1"}, - - ; :produces ["application/json"], - - ; :consumes ["application/json"], - - ; :paths {}, - - ; :definitions {}} - - ``` - - - ### More complete example - - - Info, tags, routes and anonymous nested schemas. - - - ```clojure - - (require '[schema.core :as s]) - - - (s/defschema User {:id s/Str, - :name s/Str - :address {:street s/Str - :city (s/enum :tre :hki)}}) - - (s/with-fn-validation - (rs/swagger-json - {:info {:version "1.0.0" - :title "Sausages" - :description "Sausage description" - :termsOfService "http://helloreverb.com/terms/" - :contact {:name "My API Team" - :email "foo@example.com" - :url "http://www.metosin.fi"} - :license {:name "Eclipse Public License" - :url "http://www.eclipse.org/legal/epl-v10.html"}} - :tags [{:name "user" - :description "User stuff"}] - :paths {"/api/ping" {:get {}} - "/user/:id" {:post {:summary "User Api" - :description "User Api description" - :tags ["user"] - :parameters {:path {:id s/Str} - :body User} - :responses {200 {:schema User - :description "Found it!"} - 404 {:description "Ohnoes."}}}}}})) - - ; {:swagger "2.0", - - ; :info {:title "Sausages", - - ; :version "1.0.0", - - ; :description "Sausage description", - - ; :termsOfService "http://helloreverb.com/terms/", - - ; :contact {:name "My API Team", - - ; :email "foo@example.com", - - ; :url "http://www.metosin.fi"}, - - ; :license {:name "Eclipse Public License", - - ; :url "http://www.eclipse.org/legal/epl-v10.html"}}, - - ; :produces ["application/json"], - - ; :consumes ["application/json"], - - ; :tags [{:name "user", :description "User stuff"}], - - ; :paths {"/api/ping" {:get {:responses {:default {:description ""}}}}, - - ; "/user/{id}" {:post {:summary "User Api", - - ; :description "User Api description", - - ; :tags ["user"], - - ; :parameters [{:in "path", - - ; :name "id", - - ; :description "", - - ; :required true, - - ; :type "string"} - - ; {:in "body", - - ; :name "User", - - ; :description "", - - ; :required true, - - ; :schema {:$ref "#/definitions/User"}}], - - ; :responses {200 {:schema {:$ref "#/definitions/User"}, - - ; :description "Found it!"}, - - ; 404 {:description "Ohnoes."}}}}}, - - ; :definitions {"User" {:type "object", - - ; :properties {:id {:type "string"}, - - ; :name {:type "string"}, - - ; :address {:$ref "#/definitions/UserAddress"}}, - - ; :additionalProperties false, - - ; :required (:id :name :address)}, - - ; "UserAddress" {:type "object", - - ; :properties {:street {:type "string"}, - - ; :city {:type "string", - - ; :enum (:tre :hki)}}, - - ; :additionalProperties false, - - ; :required (:street :city)}}} - - ``` - - - producing the following ui: - - - ![ring-swagger](https://raw.githubusercontent.com/wiki/metosin/ring-swagger/ring-swagger.png) - - - ## Customizing Swagger Spec output - - - One can pass extra options-map as a third parameter to `swagger-json`. The following options are available: - - - ```clojure - :ignore-missing-mappings? - (false) boolean whether to silently ignore - missing schema to JSON Schema mappings. if - set to false, IllegalArgumentException is - thrown if a Schema can't be presented as - JSON Schema. - - :default-response-description-fn - ((constantly "")) - a fn to generate default - response descriptions from http status code. - Takes a status code (Int) and returns a String. - - :handle-duplicate-schemas-fn - (ring.swagger.core/ignore-duplicate-schemas), - a function to handle possible duplicate schema - definitions. Takes schema-name and set of found - attached schema values as parameters. Returns - sequence of schema-name and selected schema value. - - :collection-format - Sets the collectionFormat for query and formData - parameters. - Possible values: multi, ssv, csv, tsv, pipes." - ``` - - - For example, to get default response descriptions from the [HTTP Spec](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes), - - you can do the following: - - - ```clojure - - (require '[ring.util.http-status :as status]) - - - (rs/swagger-json - {:paths {"/hello" {:post {:responses {200 nil - 425 nil - 500 {:description "FAIL"}}}}}} - {:default-response-description-fn status/get-description}) - - ; {:swagger "2.0" - - ; :info {:title "Swagger API" :version "0.0.1"} - - ; :consumes ["application/json"] - - ; :produces ["application/json"] - - ; :definitions {} - - ; :paths {"/hello" {:post {:responses {200 {:description "OK"} - - ; 425 {:description "The collection is unordered."} - - ; 500 {:description "FAIL"}}}}}} - - ``` - - - ## Validating the Swagger Spec - - - The generated full spec can be validated against the [Swagger JSON Schema](https://raw.githubusercontent.com/reverb/swagger-spec/master/schemas/v2.0/schema.json) - - with the help of [scjsv](https://github.com/metosin/scjsv). - - - ```clojure - - (require '[ring.swagger.validator :as v]) - - - (v/validate (rs/swagger-json {:paths {"/api/ping" {:get nil}}})) - - ; nil - - - (v/validate (rs/swagger-json {:pathz {"/api/ping" {:get nil}}})) - - ; ({:level "error" - - ; :schema {:loadingURI "#", :pointer ""} - - ; :instance {:pointer ""} - - ; :domain "validation" - - ; :keyword "additionalProperties" - - ; :message "object instance has properties which are not allowed by the schema: [\"pathz\"]", :unwanted ["pathz"]}) - - ``` - - - For more information about creating your own adapter, see [Collecting API Documentation](https://github.com/metosin/ring-swagger/wiki/Collecting-API-Documentation). - - - ## Transforming the Swagger Spec - - - There are the following utility functions for transforming the spec (on the client side): - - - `ring.swagger.swagger2/transform-operations` - transforms the operations under the :paths of a ring-swagger spec - - by applying `(f operation)` to all operations. If the function returns nil, the given operation is removed. - - - As an example, one can filter away all operations with `:x-no-doc` set to `true`: - - - ```clojure - - (defn remove-x-no-doc [endpoint] - (if-not (some-> endpoint :x-no-doc true?) - endpoint)) - - (transform-operations remove-x-no-doc {:paths {"/a" {:get {:x-no-doc true}, :post {}} - "/b" {:put {:x-no-doc true}}}})) - ; {:paths {"/a" {:post {}}}} - - ``` - - - ## Web Schemas - - - [Prismatic Schema](https://github.com/Prismatic/schema) is used to describe both the input & output schemas for routes. - - - As Swagger 2.0 Spec Schema is a deterministic subset of JSON Schema, so not all Clojure Schema elements can be used. - - - ### Schema to Swagger JSON Schema conversion - - - There are two possible methods to do this: - - - 1. class-based dispatch via `ring.swagger.json-schema/convert-class`. - - 2. protocol-based dispatch via `ring.swagger.json-schema/JsonSchema` - the `convert` fn. - - - Both take the Schema and swagger options map as arguments. Options contain also `:in` to denote the possible location - - of the schema (`nil`, `:query`, `:header`, `:path`, `:formData` and `:body`). - - - To support truly symmetric web schemas, one needs also to ensure both JSON Serialization and - - deserialization/coercion from JSON. - - - ### Class-based dispatch - - - ```clojure - - (require '[ring.swagger.json-schema :as json-schema]) - - - (defmethod json-schema/convert-class java.sql.Date [_ _] {:type "string" :format "date"}) - - ``` - - - #### Protocol-based dispatch - - - ```clojure - - (require '[ring.swagger.json-schema :as json-schema]) - - - (extend-type java.util.regex.Pattern - json-schema/JsonSchema - (json-schema/convert [e _] - {:type "string" :pattern (str e)})) - ``` - - - One can also use the options to create more accurate specs (via the `:in` option). - - - ```clojure - - (extend-type schema.core.Maybe - json-schema/JsonSchema - (convert [e {:keys [in]}] - (let [schema (->swagger (:schema e))] - (if (#{:query :formData} in) - (assoc schema :allowEmptyValue true) - schema)))) - ``` - - - ### Out-of-the-box supported Schema elements - - - | Clojure Schema | JSON Schema | Sample JSON | - - | --------------------------------------------|--------------------------|:-----------:| - - | `Integer` | integer, int32 | `1` - - | `Long`, `s/Int` | integer, int64 | `1` - - | `Double`, `Number`, `s/Num` | number, double | `1.2` - - | `String`, `s/Str`, `Keyword`, `s/Keyword`, `Symbol`, `s/Symbol`, `s/Any` non-body-parameter | string | `"kikka"` - - | `Boolean` | boolean | `true` - - | `nil`, `s/Any` body-parameter | void | - - | `java.util.regex.Pattern`, | string, regex | `[a-z0-9]` - - | `#"[a-z0-9]+"` | string, pattern | `"a6"` - - | `s/Uuid`, `java.util.UUID` | string, uuid | `"77e70512-1337-dead-beef-0123456789ab"` - - | `java.util.Date`, `org.joda.time.DateTime`, `s/Inst`, `java.time.Instant` | string, date-time | `"2014-02-18T18:25:37.456Z"`, also without millis: `"2014-02-18T18:25:37Z"` - - | `org.joda.time.LocalDate`, `java.time.LocalDate` | string, date | `"2014-02-19"` - - | `org.joda.time.LocalTime`, `java.time.LocalTime` | string, time | `"16:22"` - - | `(s/enum X Y Z)` | *type of X*, enum(X,Y,Z) - - | `(s/maybe X)` | *type of X* - - | `(s/both X Y Z)` | *type of X* - - | `(s/constrained X pred)` | *type of X* - - | `(s/conditional p1 X p2 Y p3 Z)` | *one of type X, Y, Z* - - | `(s/cond-pre X Y Z)` | *one of type X, Y, Z* - - | `(s/either X Y Z)` | *type of X* - - | `(s/named X name)` | *type of X* - - | `(s/one X name)` | *type of X* - - | `(s/recursive Var)` | *Ref to (model) Var* - - | `(s/eq X)` | *type of class of X*, enum(X) - - | `(s/optional-key X)` | *optional key* - - | `(s/required-key X)` | *required key* - - | `s/Keyword` (as a key) | *ignored* - - - - All supported types have symmetric JSON serialization (Cheshire encoders) & deserialization (Schema coercions) - - - Vectors, Sets and Maps can be used as containers - - - Maps are presented as Complex Types and References. Model references are resolved automatically. - - Nested maps are transformed automatically into flat maps with generated child references - - Maps can be within valid containers (as only element - heterogeneous schema sequences not supported by the spec) - - ### Missing Schema elements - - - If Ring-swagger can't transform the Schemas into JSON Schemas, by default a `IllegalArgumentException` will be thrown. - - Setting the `:ignore-missing-mappings?` to `true` causes the errors to be ignored - missing schema elements will be - - ignored from the generated Swagger schema. - - - ### Body and Response model names - - - Standard Prismatic Schema names are used. Nested schemas are traversed and all found sub-schemas are named - - automatically - so that they can be referenced in the generated Swagger spec. - - - Swagger 2.0 squashes all api models into a single global namespace, so schema name collisions can happen. - - When this happens, the function defined by `:handle-duplicate-schemas-fn` option is called to resolve the collision. - - By default, the collisions are ignored. - - - One accidental reason for schema name collisions is the use of normal `clojure.core` functions to create transformed - - copies of the schemas. The normal core functions retain the original schema meta-data and by so the schema name. - - - ```clojure - - (s/defschema User {:id s/Str, :name s/Str}) - - (def NewUser (dissoc User :id)) ; dissoc does not remove the schema meta-data - - - (meta User) - - ; {:name User :ns user} - - - - (meta NewUser) - - ; {:name User :ns user} <--- fail, now there are two User-schemas around. - - ``` - - - There are better schema transformers functions available at [schema-tools](https://github.com/metosin/schema-tools). - - It's an implicit dependency of ring-swagger. - - - ### Extra Schema elements supported by `ring.swagger.json-schema-dirty` - - - Some Schema elements are impossible to accurately describe within boundaries of JSON-Schema or Swagger spec. - - You can require `ring.swagger.json-schema-dirty` namespace to get JSON Schema dispatching for the following: - - - **WARNING** Swagger-UI might not display these correctly and the code generated by swagger-codegen will be inaccurate. - - - | Clojure | JSON Schema | Sample | - - | --------|-------|:------------:| - - | `(s/conditional pred X pred Y pred Z)` | x-oneOf: *type of X*, *type of Y*, *type of Z* - - | `(s/if pred X Y)` | x-oneOf: *type of X*, *type of Y* - - - ### Schema coercion - - - Ring-swagger uses [Schema coercions](http://plumatic.github.io/schema-0-2-0-back-with-clojurescript-data-coercion) - - for transforming the input data into vanilla Clojure and back. - - - There are two coercers in `ring.swagger.coerce`, the `json-schema-coercion-matcher` and `query-schema-coercion-matcher`. - - These are enchanced versions of the original Schema coercers, adding support for all the supported Schema elements, - - including Dates & Regexps. - - - #### Custom Coercions - - - In order to allow for custom input coercion, ring-swagger includes a multimethod 'custom-matcher' that can be implemented for custom input types. For example, to coerce currency strings into joda.money.Money objects, you can implement the following: - - - ```clojure - - (require '[ring.swagger.coerce :as coerce]) - - (import org.joda.money.Money) - - - (defmethod coerce/custom-matcher org.joda.money.Money [_] #(org.joda.money.Money/parse %)) - - ``` - - - This will allow org.joda.money.Money objects in your Schema definitions to be coerced correctly. However, this is only for coercing input, see [Schema to Swagger JSON Schema conversion](#schema-to-swagger-json-schema-conversion) for examples on transforming output. - - - #### Coerce! - - - Ring-swagger provides a convenience function for coercion, `ring.swagger.schema/coerce!`. It returns either a valid - - coerced value of slingshots an Map with type `:ring.swagger.schema/validation`. One can catch these exceptions via - - `ring.swagger.middleware/wrap-validation-errors` and return a JSON-friendly map of the contents. - - - ```clojure - - (require '[schema.core :as s]) - - (require '[ring.swagger.schema :refer [coerce!]]) - - - (s/defschema Bone {:size Long, :animal (s/enum :cow :tyrannosaurus)}) - - - (coerce! Bone {:size 12, :animal "cow"}) - - ; {:animal :cow, :size 12} - - - (coerce! Bone {:animal :sheep}) - - ; ExceptionInfo throw+: #schema.utils.ErrorContainer{:error {:animal (not (#{:tyrannosaurus :cow} :sheep)), :size missing-required-key}, :type :ring.swagger.schema/validation} ring.swagger.schema/coerce! (schema.clj:57) - - ``` - - - ## Adding description to Schemas - - - One can add extra meta-data, including descriptions to schema elements using `ring.swagger.json-schema/field` and `ring.swagger.json-schema/describe` functions. These work by adding meta-data to schema under `:json-schema`-key. Objects which don't natively support meta-data, like Java classes, are wrapped automatically into `ring.swagger.json-schema/FieldSchema` to enable the meta-data. - - - ### Example - - - ```clojure - - (require '[schema.core :as s]) - - (require '[ring.swagger.schema :as rs]) - - (require '[ring.swagger.json-schema :as rjs]) - - - (s/defschema Required - (rjs/field - {(s/optional-key :name) s/Str - (s/optional-key :title) s/Str - :address (rjs/field - {:street (rsjs/field s/Str {:description "description here"})} - {:description "Streename" - :example "Ankkalinna 1"})} - {:minProperties 1 - :description "I'm required" - :example {:name "Iines" - :title "Ankka"}})) - - ; produces the following JSON Schema models => - - ; - - ; {"Required" {:type "object" - - ; :description "I'm required" - - ; :example {:name "Iines" - - ; :title "Ankka"} - - ; :minProperties 1 - - ; :required [:address] - - ; :properties {:name {:type "string"} - - ; :title {:type "string"} - - ; :address {:$ref "#/definitions/RequiredAddress"}} - - ; :additionalProperties false} - - ; "RequiredAddress" {:type "object" - - ; :description "Streename" - - ; :example "Ankkalinna 1" - - ; :properties {:street {:type "string" - - ; :description "description here"}} - - ; :required [:street] - - ; :additionalProperties false}} - - ``` - - - ## License - - - Copyright © 2014-2018 [Metosin Oy](http://www.metosin.fi) - - - Distributed under the Eclipse Public License, the same as Clojure. -byjg/php-swagger-test: > - # PHP Swagger Test - - - [![Opensource ByJG](https://img.shields.io/badge/opensource-byjg-success.svg)](http://opensource.byjg.com) - - [![GitHub source](https://img.shields.io/badge/Github-source-informational?logo=github)](https://github.com/byjg/php-swagger-test/) - - [![GitHub license](https://img.shields.io/github/license/byjg/php-swagger-test.svg)](https://opensource.byjg.com/opensource/licensing.html) - - [![GitHub release](https://img.shields.io/github/release/byjg/php-swagger-test.svg)](https://github.com/byjg/php-swagger-test/releases/) - - [![Build Status](https://travis-ci.com/byjg/php-swagger-test.svg?branch=master)](https://travis-ci.com/byjg/php-swagger-test) - - [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/byjg/php-swagger-test/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/byjg/php-swagger-test/?branch=master) - - - - A set of tools for testing in your REST calls based on the OpenApi specification using PHPUnit. - - Currently, this library supports the OpenApi specifications `2.0` (formerly swagger) and `3.0`. - - Some features like callbacks, links and references to external documents/objects weren't implemented. - - - PHP Swagger Test can help you to test your REST Api. You can use this tool both for Unit Tests or Functional Tests. - - - This tool reads a previously Swagger JSON file (not YAML) and enables you to test the request and response. - - You can use the tool "https://github.com/zircote/swagger-php" for creating the JSON file when you are developing your - - rest API. - - - The ApiTestCase's assertion process is based on throwing exceptions if some validation or test failed. - - - ## Use cases for PHP Swagger test - - - You can use the Swagger Test library as: - - - - Functional test cases - - - Unit test cases - - - Runtime parameters validator - - - Validate your specification - - - - ### Functional Test cases - - - Swagger Test provides the class `SwaggerTestCase` for you extend and create a PHPUnit test case. The code will try to - - make a request to your API Method and check if the request parameters, status and object returned are OK. - - - ```php - - setSchema($schema); - } - - /** - * Test if the REST address /path/for/get/ID with the method GET returns what is - * documented on the "swagger.json" - */ - public function testGet() - { - $request = new \ByJG\ApiTools\ApiRequester(); - $request - ->withMethod('GET') - ->withPath("/path/for/get/1"); - - $this->assertRequest($request); - } - - /** - * Test if the REST address /path/for/get/NOTFOUND returns a status code 404. - */ - public function testGetNotFound() - { - $request = new \ByJG\ApiTools\ApiRequester(); - $request - ->withMethod('GET') - ->withPath("/path/for/get/NOTFOUND") - ->assertResponseCode(404); - - $this->assertRequest($request); - } - - /** - * Test if the REST address /path/for/post/ID with the method POST - * and the request object ['name'=>'new name', 'field' => 'value'] will return an object - * as is documented in the "swagger.json" file - */ - public function testPost() - { - $request = new \ByJG\ApiTools\ApiRequester(); - $request - ->withMethod('POST') - ->withPath("/path/for/post/2") - ->withRequestBody(['name'=>'new name', 'field' => 'value']); - - $this->assertRequest($request); - } - - /** - * Test if the REST address /another/path/for/post/{id} with the method POST - * and the request object ['name'=>'new name', 'field' => 'value'] will return an object - * as is documented in the "swagger.json" file - */ - public function testPost2() - { - $request = new \ByJG\ApiTools\ApiRequester(); - $request - ->withMethod('POST') - ->withPath("/path/for/post/3") - ->withQuery(['id'=>10]) - ->withRequestBody(['name'=>'new name', 'field' => 'value']); - - $this->assertRequest($request); - } - - } - - ``` - - - ### Functional Tests without a Webserver - - - Sometimes, you want to run functional tests without making the actual HTTP - - requests and without setting up a webserver for that. Instead, you forward the - - requests to the routing of your application kernel which lives in the same - - process as the functional tests. In order to do that, you need a bit of - - glue code based on the `AbstractRequester` baseclass: - - - ```php - - class MyAppRequester extends ByJG\ApiTools\AbstractRequester - - { - /** @var MyAppKernel */ - private $app; - - public function __construct(MyAppKernel $app) - { - parent::construct(); - $this->app = $app; - } - - protected function handleRequest(RequestInterface $request) - { - return $this->app->handle($request); - } - } - - ``` - - You now use an instance of this class in place of the `ApiRequester` class from the examples above. Of course, if you need to apply changes to the request, or the response in order - - to fit your framework, this is exactly the right place to do it. - - - @todo: Explain in the Docs sections the `RestServer` component - - - ### Using it as Unit Test cases - - - If you want mock the request API and just test the expected parameters, you are sending and - - receiving you have to: - - - **1. Create the Swagger or OpenAPI Test Schema** - - - ```php - - getRequestParameters($path, $method); - - - // Returns a SwaggerResponseBody instance - - $bodyResponseDef = $schema->getResponseParameters($path, $method, $statusExpected); - - ``` - - - **3. Match the result** - - - ```php - - match($requestBody); - } - - $bodyResponseDef->match($responseBody); - - ``` - - - If the request or response body does not match with the definition an exception NotMatchException will - - be thrown. - - - ### Runtime parameters validator - - - This tool was not developed only for unit and functional tests. You can use to validate if the required body - - parameters is the expected. - - - So, before your API Code you can validate the request body using: - - - ```php - - getRequestParameters($path, $method); - - $bodyRequestDef->match($requestBody); - - ``` - - - ## Validate your Specification - - - PHP Swagger has the class `MockRequester` with exact the same functionalities of `ApiRequester` class. The only - - difference is the `MockRequester` don't need to request to a real endpoint. - - - This is used to validate request and response against your OpenAPI spec without running any server code. - - - ```php - - withBody(new MemoryStream(json_encode([ - "id" => 1, - "name" => "Spike", - "photoUrls" => [] - ]))); - - // The MockRequester does not send the request to a real endpoint - // Just returning the expected Response object sent in the constructor - $request = new \ByJG\ApiTools\MockRequester($expectedResponse); - $request - ->withMethod('GET') - ->withPath("/pet/1"); - - $this->assertRequest($request); // That should be "True" based on the specification - } - } - - ``` - - - ## Integration with PSR7 - - - You can populate the `ApiRequester`/`MockRequester` with the information provided by the `RequestInterface` PSR7 interface. - - - e.g. - - - ```php - - withMethod("GET") - ->withBody('{"foo":"bar"}'); - - $request = new \ByJG\ApiTools\ApiRequester(); - - $request->withPsr7Request($psr7Request); - - - // Return a ResponseInterface PSR7 component - - $response = $request->send(); - - ``` - - - - - ## Install - - - ```bash - - composer require "byjg/swagger-test=3.1.*" - - ``` - - - ## Questions? - - - Please raise your issue on [Github issue](https://github.com/byjg/php-swagger-test/issues). - - - ## References - - - This project uses the [byjg/webrequest](https://github.com/byjg/webrequest) component. - - It implements the PSR-7 specification, and a HttpClient / MockClient to do the requests. - - Check it out to get more information. - - - ---- - - [Open source ByJG](http://opensource.byjg.com) -alekseyl/mini-apivore: > - # MiniApivore - - - MiniApivore is an adaptation of the apivore gem for mini-test instead of rspec. - - - Original project: https://github.com/westfieldlabs/apivore - - - So base credits should go to the apivore authors, this is 60% copy/paste of original project. - - Rem: didn't forked it cause didn't expect it to be a relatively small set of changes. - - - Code-Test-Document, the idea of how things are need to be done: https://medium.com/@leshchuk/code-test-document-9b79921307a5 - - - ## What's new/different - - * Swagger schema can be loaded from a file or directly. There can be one schema per MiniTestClass. - - * Removed all dependencies of active support and rails. See tests as an example on how - to use a mini-apivore outside a rails - * Didn't implement a custom schema validator ( but I kept the original schema and code from apivore in case of a future need ) - - * The test for untested routes now added by default at the end of all runnable_methods - - * Much more simplified tests against original project, rspec is replaced with minitest - - * Removed all rspec dependencies and usage. - - - ## Installation - - - Add this line to your application's Gemfile: - - - ```ruby - - gem 'mini-apivore' - - ``` - - - And then execute: - - $ bundle - - Or install it yourself as: - - $ gem install mini-apivore - - ## Usage - - - To start testing routes with mini_apivore you need: - - - * ```require 'mini_apivore' ``` in you MiniTest class file - - * ```include MiniApivore``` in you MiniTest class - - * ```init_swagger('/apidocs.json')``` init swagger-schema against which yourtest are gonna run - - * Run ```check_route( :get, '/cards.json', OK )``` against all routes in your swagger schema - - - You can see example in test/mini_apivore/mini_apivore/api_schemas_test.rb - - - Here another complete example of testing simple internal REST api for Card model - - with devise integration as authentication framework - - - ```ruby - - #mini_apivore_helper.rb - - require 'mini_apivore' - - - # this is simple intermediate class for apivore tes classes - - class MiniApivoreTest < ActionDispatch::IntegrationTest - include Devise::Test::IntegrationHelpers - include MiniApivore - - # swagger checker initialized once per class, but since we using one definition - # for all we can just redefine original swagger_checker - def swagger_checker; - SWAGGER_CHECKERS[MiniApivoreTest] - end - - - end - - ``` - - - The most readable way to handle check_routes, especially when you have nested resources i.e. like always :), - - is to create a set of named route helpers for the TestClass, may be even extract it to a module if it's a generalized helpers. - - - Then you need to redefine ```prepare_error_backtrace```, cause assert for correct execution is hidden deep in stack - and instead of pointing to just to that useless stack frame you need show something upper and may be more context, - so you can redefine ```prepare_error_backtrace``` and deliver valuable context! - - Here is an example how you can handle simple resource route testing, as you can see you can read it - - without a context of a routes structure and without verbosity: - - ```ruby - - #cards_api_test.rb - - require 'test_helper' - - require 'mini_apivore_helper' - - - class CardsApiTest < MiniApivoreTest - - #------- DEFINE CLASS SPECIFIC NAMED ROUTE HELPERS ---------------- - def __get_cards(expectation) - check_route( :get, '/cards.json', expectation ) - end - - def __get_card( card, expectation) - # check_route will use to_param inside - check_route( :get, '/cards/{id}.json', expectation, id: card ) - end - - def __update_card( card, expectation, params = {}) - # check_route will use to_param inside - check_route( :patch, '/cards/{id}.json', expectation, id: card, **params) - end - - def __create_card( expectation, params = {}) - check_route( :post, '/cards.json', expectation, params ) - end - - def __delete_card(card, expectation) - check_route( :delete, '/cards/{id}.json', expectation, id: card ) - end - #------- DEFINE CLASS SPECIFIC NAMED ROUTE HELPERS DONE ----------- - # - # failure need a proper stackframe and a context around: - def prepare_error_backtrace - # it will deliver something like this: - #"/app/test/helpers/base_routes_helpers.rb:57:in `__create_card'", - #"/app/test/integration/cards_api_test.rb:71:in `block (2 levels) in '", - Thread.current.backtrace[2..-1].slice_after{|trc| trc[/check_route/] }.to_a.last[0..1] - end - - test 'cards unauthorized' do - card = cards(:valid_card_1) - __get_cards( NOT_AUTHORIZED ) - __get_card( card, NOT_AUTHORIZED ) - __update_card( card, NOT_AUTHORIZED, _data: { card: { title: '1' } } ) - __create_card( NOT_AUTHORIZED, _data: { card: { title: '1' } } ) - __delete_card( card, NOT_AUTHORIZED ) - end - - test 'cards forbidden' do - sign_in( :first_user ) - # card with restricted privileges - card = cards(:restricted_card) - - __get_card( card, FORBIDDEN ) - __update_card( card, FORBIDDEN, id: card, _data: { card: { title: '1' } } ) - - # this may be added if not all users can create cards - # check_route( :post, '/cards.json', FORBIDDEN, _data: { card: { title: '1' } } ) - - __delete_card( card, FORBIDDEN) - end - - test 'cards not_found' do - sign_in( :first_user ) - card = Card.new(id: -1) - __get_card( card, NOT_FOUND ) - __update_card( card, NOT_FOUND ) - __delete_card( card, NOT_FOUND ) - end - - test 'cards REST authorized' do - sign_in( :first_user ) - __get_cards( OK ) - __get_cards( cards(:valid_card_1), OK ) - - assert_difference( -> { Card.count } ) do - __create_card( OK, _data: { - card: { title: 'test card creation', - card_preview_img_attributes: { - upload: fixture_file_upload( Rails.root.join('test', 'fixtures', 'files', 'test.png') ,'image/png') - } - } } ) - end - created_card = Card.last - assert_equal( 'test card creation', created_card.title ) - - __update_card( created_card, OK, _data: { card: { title: 'Nothing' } } ) - assert_equal( created_card.reload.title, 'Nothing' ) - - assert_difference( -> { Card.count }, -1 ) do - __delete_card( created_card, NO_CONTENT ) - end - - end - end - - ``` - - - ## Development - - - After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. - - - To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). - - - ## Contributing - - - Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/mini-apivore. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. - - - ## License - - - The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). -Surnet/swagger-jsdoc: > - # swagger-jsdoc - - - This library reads your [JSDoc](https://jsdoc.app/)-annotated source code and generates an [OpenAPI (Swagger) specification](https://swagger.io/specification/). - - - [![npm Downloads](https://img.shields.io/npm/dm/swagger-jsdoc.svg)](https://www.npmjs.com/package/swagger-jsdoc) - - ![CI](https://github.com/Surnet/swagger-jsdoc/workflows/CI/badge.svg) - - - ## Getting started - - - Imagine having API files like these: - - - ```javascript - - /** - * @openapi - * /: - * get: - * description: Welcome to swagger-jsdoc! - * responses: - * 200: - * description: Returns a mysterious string. - */ - app.get('/', (req, res) => { - res.send('Hello World!'); - }); - - ``` - - - The library will take the contents of `@openapi` (or `@swagger`) with the following configuration: - - - ```javascript - - const swaggerJsdoc = require('swagger-jsdoc'); - - - const options = { - definition: { - openapi: '3.0.0', - info: { - title: 'Hello World', - version: '1.0.0', - }, - }, - apis: ['./src/routes*.js'], // files containing annotations as above - }; - - - const openapiSpecification = swaggerJsdoc(options); - - ``` - - - The resulting `openapiSpecification` will be a [swagger tools](https://swagger.io/tools/)-compatible (and validated) specification. - - - ![swagger-jsdoc example screenshot](./docs/screenshot.png) - - - ## System requirements - - - - Node.js 12.x or higher - - - You are viewing `swagger-jsdoc` v6 which is published in CommonJS module system. - - - ## Installation - - - ```bash - - npm install swagger-jsdoc --save - - ``` - - - Or - - - ```bash - - yarn add swagger-jsdoc - - ``` - - - ## Supported specifications - - - - OpenAPI 3.x - - - Swagger 2 - - - AsyncAPI 2.0 - - - ## Validation of swagger docs - - - By default `swagger-jsdoc` tries to parse all docs to it's best capabilities. If you'd like to you can instruct an Error to be thrown instead if validation failed by setting the options flag `failOnErrors` to `true`. This is for instance useful if you want to verify that your swagger docs validate using a unit test. - - - ```javascript - - const swaggerJsdoc = require('swagger-jsdoc'); - - - const options = { - failOnErrors: true, // Whether or not to throw when parsing errors. Defaults to false. - definition: { - openapi: '3.0.0', - info: { - title: 'Hello World', - version: '1.0.0', - }, - }, - apis: ['./src/routes*.js'], - }; - - - const openapiSpecification = swaggerJsdoc(options); - - ``` - - - ## Documentation - - - Click on the version you are using for further details: - - - - [7.x](https://github.com/Surnet/swagger-jsdoc/tree/v7/docs) - - - [6.x](https://github.com/Surnet/swagger-jsdoc/tree/v6/docs) - - - [5.x](https://github.com/Surnet/swagger-jsdoc/tree/v5) -domaindrivendev/Swashbuckle: > - | :mega: Calling for Maintainers | - - |--------------| - - | With the introduction of [ASP.NET Core](https://www.asp.net/core), I've now shifted my focus to the Core-specific project - [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore). That will be receiving most of my (already limited) personal time, and so I won't have the capacity to maintain this one at a sufficient rate. Still, I'd love to see it live on and am seeking one or two "core" contributors / maintainers to help out. Ideally, these would be people who have already contributed through PRs and understand the inner workings and overall design. Once signed-up, we can agree on an approach that works - ultimately, I want to remove myself as the bottleneck to merging PRs and getting fresh Nugets published. If you're interested, please let me know by adding a comment [here](https://github.com/domaindrivendev/Swashbuckle/issues/1053) | - - - Swashbuckle - - ========= - - - [![Build status](https://ci.appveyor.com/api/projects/status/qoesh4nm6tb6diuk?svg=true)](https://ci.appveyor.com/project/domaindrivendev/swashbuckle) - - - Seamlessly adds a [Swagger](http://swagger.io/) to WebApi projects! Combines ApiExplorer and Swagger/swagger-ui to provide a rich discovery, documentation and playground experience to your API consumers. - - - In addition to its Swagger generator, Swashbuckle also contains an embedded version of [swagger-ui](https://github.com/swagger-api/swagger-ui) which it will automatically serve up once Swashbuckle is installed. This means you can complement your API with a slick discovery UI to assist consumers with their integration efforts. Best of all, it requires minimal coding and maintenance, allowing you to focus on building an awesome API! - - - And that's not all ... - - - Once you have a Web API that can describe itself in Swagger, you've opened the treasure chest of Swagger-based tools including a client generator that can be targeted to a wide range of popular platforms. See [swagger-codegen](https://github.com/swagger-api/swagger-codegen) for more details. - - - **Swashbuckle Core Features:** - - - * Auto-generated [Swagger 2.0](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md) - - * Seamless integration of swagger-ui - - * Reflection-based Schema generation for describing API types - - * Extensibility hooks for customizing the generated Swagger doc - - * Extensibility hooks for customizing the swagger-ui - - * Out-of-the-box support for leveraging Xml comments - - * Support for describing ApiKey, Basic Auth and OAuth2 schemes ... including UI support for the Implicit OAuth2 flow - - - **Swashbuckle 5.0** - - - Swashbuckle 5.0 makes the transition to Swagger 2.0. The 2.0 schema is significantly different to its predecessor (1.2) and, as a result, the Swashbuckle config interface has undergone yet another overhaul. Checkout the [transition guide](#transitioning-to-swashbuckle-50) if you're upgrading from a prior version. - - - ## Getting Started ## - - - There are currently two Nuget packages - the Core library (Swashbuckle.Core) and a convenience package (Swashbuckle) - that provides automatic bootstrapping. The latter is only applicable to regular IIS hosted Web APIs. For all other hosting environments, you should only install the Core library and then follow the instructions below to manually enable the Swagger routes. - - - Once installed and enabled, you should be able to browse the following Swagger docs and UI endpoints respectively: - - - ***\/swagger/docs/v1*** - - - ***\/swagger*** - - - ### IIS Hosted ### - - - If your service is hosted in IIS, you can start exposing Swagger docs and a corresponding swagger-ui by simply installing the following Nuget package: - - Install-Package Swashbuckle - - This will add a reference to Swashbuckle.Core and also install a bootstrapper (App_Start/SwaggerConfig.cs) that enables the Swagger routes on app start-up using [WebActivatorEx](https://github.com/davidebbo/WebActivator). - - - ### Self-hosted ### - - - If your service is self-hosted, just install the Core library: - - Install-Package Swashbuckle.Core - - Then manually enable the Swagger docs and, optionally, the swagger-ui by invoking the following extension methods (in namespace Swashbuckle.Application) on an instance of HttpConfiguration (e.g. in Program.cs) - - - ```csharp - - httpConfiguration - .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API")) - .EnableSwaggerUi(); - ``` - - - ### OWIN ### - - - If your service is hosted using OWIN middleware, just install the Core library: - - Install-Package Swashbuckle.Core - - Then manually enable the Swagger docs and swagger-ui by invoking the extension methods (in namespace Swashbuckle.Application) on an instance of HttpConfiguration (e.g. in Startup.cs) - - - ```csharp - - httpConfiguration - .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API")) - .EnableSwaggerUi(); - ``` - - - ## Troubleshooting ## - - - Troubleshooting??? I thought this was all supposed to be "seamless"? OK you've called me out! Things shouldn't go wrong, but if they do, take a look at the [FAQs](#troubleshooting-and-faqs) for inspiration. - - - ## Customizing the Generated Swagger Docs ## - - - The following snippet demonstrates the minimum configuration required to get the Swagger docs and swagger-ui up and running: - - ```csharp - - httpConfiguration - .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API")) - .EnableSwaggerUi(); - ``` - - - These methods expose a range of configuration and extensibility options that you can pick and choose from, combining the convenience of sensible defaults with the flexibility to customize where you see fit. Read on to learn more. - - - ### Custom Routes ### - - - The default route templates for the Swagger docs and swagger-ui are "swagger/docs/{apiVersion}" and "swagger/ui/{\*assetPath}" respectively. You're free to change these so long as the provided templates include the relevant route parameters - {apiVersion} and {\*assetPath}. - - - ```csharp - - httpConfiguration - .EnableSwagger("docs/{apiVersion}/swagger", c => c.SingleApiVersion("v1", "A title for your API")) - .EnableSwaggerUi("sandbox/{*assetPath}"); - ``` - - - In this case the URL to swagger-ui will be `sandbox/index`. - - - ### Pretty Print ### - - - If you want the output Swagger docs to be indented properly, enable the __PrettyPrint__ option as following: - - - ```cs - - httpConfiguration - .EnableSwagger(c => c.PrettyPrint()) - .EnableSwaggerUi(); - ``` - - - ### Additional Service Metadata ### - - - In addition to operation descriptions, Swagger 2.0 includes several properties to describe the service itself. These can all be provided through the configuration API: - - - ```csharp - - httpConfiguration - .EnableSwagger(c => - { - c.RootUrl(req => GetRootUrlFromAppConfig()); - - c.Schemes(new[] { "http", "https" }); - - c.SingleApiVersion("v1", "Swashbuckle.Dummy") - .Description("A sample API for testing and prototyping Swashbuckle features") - .TermsOfService("Some terms") - .Contact(cc => cc - .Name("Some contact") - .Url("http://tempuri.org/contact") - .Email("some.contact@tempuri.org")) - .License(lc => lc - .Name("Some License") - .Url("http://tempuri.org/license")); - }); - ``` - - #### RootUrl #### - - - By default, the service root url is inferred from the request used to access the docs. However, there may be situations (e.g. proxy and load-balanced environments) where this does not resolve correctly. You can workaround this by providing your own code to determine the root URL. - - - #### Schemes #### - - - If schemes are not explicitly provided in a Swagger 2.0 document, then the scheme used to access the docs is taken as the default. If your API supports multiple schemes and you want to be explicit about them, you can use the __Schemes__ option. - - - #### SingleApiVersion #### - - - Use this to describe a single version API. Swagger 2.0 includes an "Info" object to hold additional metadata for an API. Version and title are required but you may also provide additional fields as shown above. - - - __NOTE__: If your Web API is hosted in IIS, you should avoid using full-stops in the version name (e.g. "1.0"). The full-stop at the tail of the URL will cause IIS to treat it as a static file (i.e. with an extension) and bypass the URL Routing Module and therefore, Web API. - - - ### Describing Multiple API Versions ### - - - If your API has multiple versions, use __MultipleApiVersions__ instead of __SingleApiVersion__. In this case, you provide a lambda that tells Swashbuckle which actions should be included in the docs for a given API version. Like __SingleApiVersion__, __Version__ also returns an "Info" builder so you can provide additional metadata per API version. - - - ```csharp - - httpConfiguration - .EnableSwagger(c => - { - c.MultipleApiVersions( - (apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion), - (vc) => - { - vc.Version("v2", "Swashbuckle Dummy API V2"); - vc.Version("v1", "Swashbuckle Dummy API V1"); - }); - }); - .EnableSwaggerUi(c => - { - c.EnableDiscoveryUrlSelector(); - }); - ``` - - - \* You can also enable a select box in the swagger-ui (as shown above) that displays a discovery URL for each version. This provides a convenient way for users to browse documentation for different API versions. - - - ### Describing Security/Authorization Schemes ### - - - You can use BasicAuth, __ApiKey__ or __OAuth2__ options to describe security schemes for the API. See https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md for more details. - - - ```csharp - - httpConfiguration - .EnableSwagger(c => - { - //c.BasicAuth("basic") - // .Description("Basic HTTP Authentication"); - - //c.ApiKey("apiKey") - // .Description("API Key Authentication") - // .Name("apiKey") - // .In("header"); - - c.OAuth2("oauth2") - .Description("OAuth2 Implicit Grant") - .Flow("implicit") - .AuthorizationUrl("http://petstore.swagger.wordnik.com/api/oauth/dialog") - //.TokenUrl("https://tempuri.org/token") - .Scopes(scopes => - { - scopes.Add("read", "Read access to protected resources"); - scopes.Add("write", "Write access to protected resources"); - }); - - c.OperationFilter(); - }); - .EnableSwaggerUi(c => - { - c.EnableOAuth2Support("test-client-id", "test-realm", "Swagger UI"); - }); - ``` - - __NOTE:__ These only define the schemes and need to be coupled with a corresponding "security" property at the document or operation level to indicate which schemes are required for each operation. To do this, you'll need to implement a custom IDocumentFilter and/or IOperationFilter to set these properties according to your specific authorization implementation - - - \* If your API supports the OAuth2 Implicit flow, and you've described it correctly, according to the Swagger 2.0 specification, you can enable UI support as shown above. - - - ### Customize the Operation Listing ### - - - If necessary, you can ignore obsolete actions and provide custom grouping/sorting strategies for the list of Operations in a Swagger document: - - - ```csharp - - httpConfiguration - .EnableSwagger(c => - { - c.IgnoreObsoleteActions(); - - c.GroupActionsBy(apiDesc => apiDesc.HttpMethod.ToString()); - - c.OrderActionGroupsBy(new DescendingAlphabeticComparer()); - }); - ``` - - #### IgnoreObsoleteActions #### - - - Set this flag to omit operation descriptions for any actions decorated with the Obsolete attribute - - - __NOTE__: If you want to omit specific operations but without using the Obsolete attribute, you can create an IDocumentFilter or make use of the built in ApiExplorerSettingsAttribute - - - #### GroupActionsBy #### - - - Each operation can be assigned one or more tags which are then used by consumers for various reasons. For example, the swagger-ui groups operations according to the first tag of each operation. By default, this will be the controller name but you can use this method to override with any value. - - - #### OrderActionGroupsBy #### - - - You can also specify a custom sort order for groups (as defined by __GroupActionsBy__) to dictate the order in which operations are listed. For example, if the default grouping is in place (controller name) and you specify a descending alphabetic sort order, then actions from a ProductsController will be listed before those from a CustomersController. This is typically used to customize the order of groupings in the swagger-ui. - - - ### Modifying Generated Schemas ### - - - Swashbuckle makes a best attempt at generating Swagger compliant JSON schemas for the various types exposed in your API. However, there may be occasions when more control of the output is needed. This is supported through the following options: - - - ```csharp - - httpConfiguration - .EnableSwagger(c => - { - c.MapType(() => new Schema { type = "integer", format = "int32" }); - - c.SchemaFilter(); - - //c.UseFullTypeNameInSchemaIds(); - - c.SchemaId(t => t.FullName.Contains('`') ? t.FullName.Substring(0, t.FullName.IndexOf('`')) : t.FullName); - - c.IgnoreObsoleteProperties(); - - c.DescribeAllEnumsAsStrings(); - }); - ``` - - - #### MapType #### - - - Use this option to override the Schema generation for a specific type. - - - It should be noted that the resulting Schema will be placed "inline" for any applicable Operations. While Swagger 2.0 supports inline definitions for "all" Schema types, the swagger-ui tool does not. It expects "complex" Schemas to be defined separately and referenced. For this reason, you should only use the __MapType__ option when the resulting Schema is a primitive or array type. - - - If you need to alter a complex Schema, use a Schema filter. - - - #### SchemaFilter #### - - - If you want to post-modify "complex" Schemas once they've been generated, across the board or for a specific type, you can wire up one or more Schema filters. - - - ISchemaFilter has the following interface: - - - ```csharp - - void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type); - - ``` - - - A typical implementation will inspect the system Type and modify the Schema accordingly. If necessary, the schemaRegistry can be used to obtain or register Schemas for other Types - - - #### UseFullTypeNamesInSchemaIds #### - - - In a Swagger 2.0 document, complex types are typically declared globally and referenced by unique Schema Id. By default, Swashbuckle does NOT use the full type name in Schema Ids. In most cases, this works well because it prevents the "implementation detail" of type namespaces from leaking into your Swagger docs and UI. However, if you have multiple types in your API with the same class name, you'll need to opt out of this behavior to avoid Schema Id conflicts. - - - #### SchemaId #### - - - Use this option to provide your own custom strategy for inferring SchemaId's for describing "complex" types in your API. - - - #### IgnoreObsoleteProperties #### - - - Set this flag to omit schema property descriptions for any type properties decorated with the Obsolete attribute - - - #### DescribeAllEnumsAsStrings #### - - - In accordance with the built in JsonSerializer, Swashbuckle will, by default, describe enums as integers. You can change the serializer behavior by configuring the StringEnumConverter globally or for a given enum type. Swashbuckle will honor this change out-of-the-box. However, if you use a different approach to serialize enums as strings, you can also force Swashbuckle to describe them as strings. - - - ### Modifying Generated Operations ### - - - Similar to Schema filters, Swashbuckle also supports Operation and Document filters: - - - ```csharp - - httpConfiguration - .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API")) - { - c.OperationFilter(); - - c.DocumentFilter(); - }); - ``` - - #### OperationFilter #### - - - Post-modify Operation descriptions once they've been generated by wiring up one or more Operation filters. - - - IOperationFilter has the following interface: - - - ```csharp - - void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription); - - ``` - - - A typical implementation will inspect the ApiDescription and modify the Operation accordingly. If necessary, the schemaRegistry can be used to obtain or register Schemas for Types that are used in the Operation. - - - #### DocumentFilter #### - - - Post-modify the entire Swagger document by wiring up one or more Document filters. - - - IDocumentFilter has the following interface: - - - ```csharp - - void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer); - - ``` - - - This gives full control to modify the final SwaggerDocument. You can gain additional context from the provided SwaggerDocument (e.g. version) and IApiExplorer. You should have a good understanding of the [Swagger 2.0 spec.](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md) before using this option. - - - ### Wrapping the SwaggerGenerator with Additional Behavior ### - - - The default implementation of ISwaggerProvider, the interface used to obtain Swagger metadata for a given API, is the SwaggerGenerator. If neccessary, you can inject your own implementation or wrap the existing one with additional behavior. For example, you could use this option to inject a "Caching Proxy" that attempts to retrieve the SwaggerDocument from a cache before delegating to the built-in generator: - - - ```csharp - - httpConfiguration - .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API")) - { - c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider)); - }); - ``` - - - ### Including XML Comments ### - - - If you annotate Controllers and API Types with [Xml Comments](http://msdn.microsoft.com/en-us/library/b2s063f7(v=vs.110).aspx), you can incorporate those comments into the generated docs and UI. The Xml tags are mapped to Swagger properties as follows: - - - * **Action summary** -> Operation.summary - - * **Action remarks** -> Operation.description - - * **Parameter summary** -> Parameter.description - - * **Type summary** -> Schema.descripton - - * **Property summary** -> Schema.description (i.e. on a property Schema) - - - You can enable this by providing the path to one or more XML comments files: - - ```csharp - - httpConfiguration - .EnableSwagger(c => - { - c.SingleApiVersion("v1", "A title for your API"); - c.IncludeXmlComments(GetXmlCommentsPathForControllers()); - c.IncludeXmlComments(GetXmlCommentsPathForModels()); - }); - ``` - - - NOTE: You will need to enable output of the XML documentation file. This is enabled by going to project properties -> Build -> Output. The "XML documentation file" needs to be checked and a path assigned, such as "bin\Debug\MyProj.XML". You will also want to verify this across each build configuration. Here's an example of reading the file, but it may need to be modified according to your specific project settings: - - - ```csharp - - httpConfiguration - .EnableSwagger(c => - { - var baseDirectory = AppDomain.CurrentDomain.BaseDirectory; - var commentsFileName = Assembly.GetExecutingAssembly().GetName().Name + ".XML"; - var commentsFile = Path.Combine(baseDirectory, commentsFileName); - - c.SingleApiVersion("v1", "A title for your API"); - c.IncludeXmlComments(commentsFile); - c.IncludeXmlComments(GetXmlCommentsPathForModels()); - }); - ``` - - #### Response Codes #### - - - Swashbuckle will automatically create a "success" response for each operation based on the action's return type. If it's a void, the status code will be 204 (No content), otherwise 200 (Ok). This mirrors WebApi's default behavior. If you need to change this and/or list additional response codes, you can use the non-standard "response" tag: - - - ```csharp - - /// Account created - - /// Username already in use - - public int Create(Account account) - - ``` - - ### Working Around Swagger 2.0 Constraints ### - - - In contrast to Web API, Swagger 2.0 does not include the query string component when mapping a URL to an action. As a result, Swashbuckle will raise an exception if it encounters multiple actions with the same path (sans query string) and HTTP method. You can workaround this by providing a custom strategy to pick a winner or merge the descriptions for the purposes of the Swagger docs - - - ```csharp - - httpConfiguration - .EnableSwagger((c) => - { - c.SingleApiVersion("v1", "A title for your API")); - c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); - }); - ``` - - See the following discussion for more details: - - - - - - ## Customizing the swagger-ui ## - - - The swagger-ui is a JavaScript application hosted in a single HTML page (index.html), and it exposes several customization settings. Swashbuckle ships with an embedded version and includes corresponding configuration methods for each of the UI settings. If you require further customization, you can also inject your own version of "index.html". Read on to learn more. - - - ### Customizations via the configuration API ### - - - If you're happy with the basic look and feel but want to make some minor tweaks, the following options may be sufficient: - - - ```csharp - - httpConfiguration - .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API")) - .EnableSwaggerUi(c => - { - c.InjectStylesheet(containingAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testStyles1.css"); - c.InjectJavaScript(containingAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testScript1.js"); - c.SetValidatorUrl("http://localhost/validator"); - c.DisableValidator(); - c.DocExpansion(DocExpansion.List); - c.SupportedSubmitMethods("GET", "HEAD") - }); - ``` - - - #### InjectStylesheet #### - - - Use this to enrich the UI with one or more additional CSS stylesheets. The file(s) must be included in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to the method as shown above. See [Injecting Custom Content](#injecting-custom-content) for step by step instructions. - - - #### InjectJavaScript #### - - - Use this to invoke one or more custom JavaScripts after the swagger-ui has loaded. The file(s) must be included in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to the method as shown above. See [Injecting Custom Content](#injecting-custom-content) for step by step instructions. - - - #### SetValidatorUrl/DisableValidator #### - - - By default, swagger-ui will validate specs against swagger.io's online validator and display the result in a badge at the bottom of the page. Use these options to set a different validator URL or to disable the feature entirely. - - - #### DocExpansion #### - - - Use this option to control how the Operation listing is displayed. It can be set to "None" (default), "List" (shows operations for each resource), or "Full" (fully expanded: shows operations and their details). - - - #### SupportedSubmitMethods #### - - - Specify which HTTP operations will have the 'Try it out!' option. An empty parameter list disables it for all operations. - - - ### Provide your own "index" file ### - - - As an alternative, you can inject your own version of "index.html" and customize the markup and swagger-ui directly. Use the __CustomAsset__ option to instruct Swashbuckle to return your version instead of the default when a request is made for "index". As with all custom content, the file must be included in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to the method as shown below. See [Injecting Custom Content](#injecting-custom-content) for step by step instructions. - - - For compatibility, you should base your custom "index.html" off [this version](https://github.com/domaindrivendev/Swashbuckle/blob/v5.5.3/Swashbuckle.Core/SwaggerUi/CustomAssets/index.html) - - - ```csharp - - httpConfiguration - .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API")) - .EnableSwaggerUi(c => - { - c.CustomAsset("index", yourAssembly, "YourWebApiProject.SwaggerExtensions.index.html"); - }); - ``` - - - ### Injecting Custom Content ### - - - The __InjectStylesheet__, __InjectJavaScript__ and __CustomAsset__ options all share the same mechanism for providing custom content. In each case, the file must be included in your project as an "Embedded Resource". The steps to do this are described below: - - - 1. Add a new file to your Web API project. - - 2. In Solution Explorer, right click the file and open its properties window. Change the "Build Action" to "Embedded Resource". - - - This will embed the file in your assembly and register it with a "Logical Name". This can then be passed to the relevant configuration method. It's based on the Project's default namespace, file location and file extension. For example, given a default namespace of "YourWebApiProject" and a file located at "/SwaggerExtensions/index.html", then the resource will be assigned the name - "YourWebApiProject.SwaggerExtensions.index.html". If you use "Swagger" as the root folder name for your custom assets, this will collide with the default route templates and the page will not be loaded correctly. - - - ## Transitioning to Swashbuckle 5.0 ## - - - This version of Swashbuckle makes the transition to Swagger 2.0. The 2.0 specification is significantly different to its predecessor (1.2) and forces several breaking changes to Swashbuckle's configuration API. If you're using Swashbuckle without any customizations, i.e. App_Start/SwaggerConfig.cs has never been modified, then you can overwrite it with the new version. The defaults are the same and so the swagger-ui should behave as before. - - - \* If you have consumers of the raw Swagger document, you should ensure they can accept Swagger 2.0 before making the upgrade. - - - If you're using the existing configuration API to customize the final Swagger document and/or swagger-ui, you will need to port the code manually. The static __Customize__ methods on SwaggerSpecConfig and SwaggerUiConfig have been replaced with extension methods on HttpConfiguration - __EnableSwagger__ and __EnableSwaggerUi__. All options from version 4.0 are made available through these methods, albeit with slightly different naming and syntax. Refer to the tables below for a summary of changes: - - - - | 4.0 | 5.0 Equivalent | Additional Notes | - - | --------------- | --------------- | ---------------- | - - | ResolveBasePathUsing | RootUrl | | - - | ResolveTargetVersionUsing | N/A | version is now implicit in the docs URL e.g. "swagger/docs/{apiVersion}" | - - | ApiVersion | SingleApiVersion| now supports additional metadata for the version | - - | SupportMultipleApiVersions | MultipleApiVersions | now supports additional metadata for each version | - - | Authorization | BasicAuth/ApiKey/OAuth2 | | - - | GroupDeclarationsBy | GroupActionsBy | | - - | SortDeclarationsBy | OrderActionGroupsBy | | - - | MapType | MapType | now accepts Func<Schema> instead of Func<DataType> | - - | ModelFilter | SchemaFilter | IModelFilter is now ISchemaFilter, DataTypeRegistry is now SchemaRegistry | - - | OperationFilter | OperationFilter | DataTypeRegistry is now SchemaRegistry | - - | PolymorphicType | N/A | not currently supported | - - | SupportHeaderParams | N/A | header params are implicitly supported | - - | SupportedSubmitMethods | N/A | all HTTP verbs are implicitly supported | - - | CustomRoute | CustomAsset |   | - - - ## Troubleshooting and FAQ's ## - - - 1. [Swagger-ui showing "Can't read swagger JSON from ..."](#swagger-ui-showing-cant-read-swagger-json-from) - - 2. [Page not found when accessing the UI](#page-not-found-when-accessing-the-ui) - - 3. [Swagger-ui broken by Visual Studio 2013](#swagger-ui-broken-by-visual-studio-2013) - - 4. [OWIN Hosted in IIS - Incorrect VirtualPathRoot Handling](#owin-hosted-in-iis---incorrect-virtualpathroot-handling) - - 5. [How to add vendor extensions](#how-to-add-vendor-extensions) - - 6. [FromUri Query string DataMember names are incorrect](#fromuri-query-string-datamember-names-are-incorrect) - - 7. [Remove Duplicate Path Parameters](#remove-duplicate-path-parameters) - - 8. [Deploying behind Load Balancer / Reverse Proxies](#deploying-behind-load-balancer--reverse-proxies) - - 9. [500 : {"Message":"An error has occurred."}](#500--messagean-error-has-occurred) - - - ### Swagger-ui showing "Can't read swagger JSON from ..." - - - If you see this message, it means the swagger-ui received an unexpected response when requesting the Swagger document. You can troubleshoot further by navigating directly to the discovery URL included in the error message. This should provide more details. - - - If the discovery URL returns a 404 Not Found response, it may be due to a full-stop in the version name (e.g. "1.0"). This will cause IIS to treat it as a static file (i.e. with an extension) and bypass the URL Routing Module and therefore, Web API. - - - To workaround, you can update the version name specified in SwaggerConfig.cs. For example, to "v1", "1-0" etc. Alternatively, you can change the route template being used for the swagger docs (as shown [here](#custom-routes)) so that the version parameter is not at the end of the route. - - - ### Page not found when accessing the UI ### - - - Swashbuckle serves an embedded version of the swagger-ui through the Web API pipeline. But, most of the URLs contain extensions (.html, .js, .css) and many IIS environments are configured to bypass the managed pipeline for paths containing extensions. - - - In previous versions of Swashbuckle, this was resolved by adding the following setting to your Web.config: - - - ```xml - - - - - - ``` - - - This is no longer neccessary in Swashbuckle 5.0 because it serves the swagger-ui through extensionless URL's. - - - However, if you're using the SingleApiVersion, MultipleApiVersions or CustomAsset configuration settings you could still get this error. Check to ensure you're not specifying a value that causes a URL with an extension to be referenced in the UI. For example a full-stop in a version number ... - - - ```csharp - - httpConfiguration - .EnableSwagger(c => c.SingleApiVersion("1.0", "A title for your API")) - .EnableSwaggerUi(); - ``` - - will result in a discovery URL like this "/swagger/docs/1.0" where the full-stop is treated as a file extension. - - - ### Swagger-ui broken by Visual Studio 2013 ### - - - VS 2013 ships with a new feature - Browser Link - that improves the web development workflow by setting up a channel between the IDE and pages being previewed in a local browser. It does this by dynamically injecting JavaScript into your files. - - - Although this JavaScript SHOULD have no affect on your production code, it appears to be breaking the swagger-ui. - - - I hope to find a permanent fix, but in the meantime, you'll need to workaround this issue by disabling the feature in your web.config: - - - ```xml - - - - - - ``` - - ### OWIN Hosted in IIS - Incorrect VirtualPathRoot Handling - - - When you host Web API 2 on top of OWIN/SystemWeb, Swashbuckle cannot correctly resolve VirtualPathRoot by default. - - - You must either explicitly set VirtualPathRoot in your HttpConfiguration at startup, or perform customization like this to fix automatic discovery: - - - ```csharp - - httpConfiguration.EnableSwagger(c => - - { - c.RootUrl(req => - req.RequestUri.GetLeftPart(UriPartial.Authority) + - req.GetRequestContext().VirtualPathRoot.TrimEnd('/')); - } - - ``` - - - ### How to add vendor extensions - - - Swagger 2.0 allows additional meta-data (aka vendor extensions) to be added at various points in the Swagger document. Swashbuckle supports this by including a "vendorExtensions" dictionary with each of the extensible Swagger types. Meta-data can be added to these dictionaries from custom Schema, Operation or Document filters. For example: - - - ```csharp - - public class ApplySchemaVendorExtensions : ISchemaFilter - - { - public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type) - { - schema.vendorExtensions.Add("x-foo", "bar"); - } - } - - ``` - - - As per the specification, all extension properties should be prefixed by "x-" - - - ### FromUri Query string DataMember names are incorrect - - - When using `FromUri` Model Binding, it is possible to override the querystring parameter name's using `DataMember`s. In this case you can add a custom operation filter to override the name. For example: - - - ```csharp - - public class ComplexTypeOperationFilter : IOperationFilter - - { - public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) - { - if (operation.parameters == null) - return; - - var parameters = apiDescription.ActionDescriptor.GetParameters(); - foreach (var parameter in parameters) - { - foreach (var property in parameter.ParameterType.GetProperties()) - { - var param = operation.parameters.FirstOrDefault(o => o.name.ToLowerInvariant().Contains(property.Name.ToLowerInvariant())); - - if (param == null) continue; - - var name = GetNameFromAttribute(property); - - if (string.IsNullOrEmpty(name)) - { - operation.parameters.Remove(param); - } - param.name = GetNameFromAttribute(property); - } - } - } - - private static string GetNameFromAttribute(PropertyInfo property) - { - var customAttributes = property.GetCustomAttributes(typeof(DataMemberAttribute), true); - if (customAttributes.Length > 0) - { - var attribute = customAttributes[0] as DataMemberAttribute; - if (attribute != null) return attribute.Name; - } - return string.Empty; - } - } - - ``` - - - ### Remove Duplicate Path Parameters - - - When using `FromUri` Model Binding, duplicate items can appear as items can be passed as URI parameters, or querystrings. In this case you can add a custom operation filter to remove the duplicates. For example: - - - ```csharp - - public class ComplexTypeOperationFilter : IOperationFilter - - { - public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) - { - if (operation.parameters == null) - return; - var complexParameters = operation.parameters.Where(x => x.@in == "query" && !string.IsNullOrWhiteSpace(x.name)).ToArray(); - - foreach (var parameter in complexParameters) - { - if (!parameter.name.Contains('.')) continue; - var name = parameter.name.Split('.')[1]; - - var opParams = operation.parameters.Where(x => x.name == name); - var parameters = opParams as Parameter[] ?? opParams.ToArray(); - - if (parameters.Length > 0) - { - operation.parameters.Remove(parameter); - } - } - } - } - - ``` - - - ### Deploying behind Load Balancer / Reverse Proxies - - - Swashbuckle attempts to populate the [Swagger "host"](http://swagger.io/specification/#swaggerObject) property from HTTP headers that are sent with the request for Swagger JSON. This may cause issues in load balancer / reverse proxy environments, particularly if non-standard headers are used to pass on the outer most host name. You can workaround this by providing your own function for determining your API's root URL based on vendor-specific headers. Checkout [issue 705](https://github.com/domaindrivendev/Swashbuckle/issues/705) for some potential implementations. - - - ### 500 : {"Message":"An error has occurred."} - - - If, on loading the Swagger UI page, you get an error: `500 : {"Message":"An error has occurred."} http:///swagger/docs/v1` ensure that the XML documentation output settings have been set in the project file in the solution, for both Debug and Release configurations. -gossi/swagger: >+ - # swagger - - - [![License](https://poser.pugx.org/gossi/swagger/license)](https://packagist.org/packages/gossi/swagger) - - [![Latest Stable Version](https://poser.pugx.org/gossi/swagger/v/stable)](https://packagist.org/packages/gossi/swagger) - - [![Total Downloads](https://poser.pugx.org/gossi/swagger/downloads)](https://packagist.org/packages/gossi/swagger)
- - [![HHVM Status](http://hhvm.h4cc.de/badge/gossi/swagger.svg?style=flat)](http://hhvm.h4cc.de/package/gossi/swagger) - - [![Build Status](https://travis-ci.org/gossi/swagger.svg?branch=master)](https://travis-ci.org/gossi/swagger) - - [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/gossi/swagger/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/gossi/swagger/?branch=master) - - [![Code Coverage](https://scrutinizer-ci.com/g/gossi/swagger/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/gossi/swagger/?branch=master) - - - - A php library to manipulate [swagger](http://swagger.io)/[Open API](https://openapis.org) specifications. - - - ## Installation - - - ``` - - composer require gossi/swagger - - ``` - - - ## Usage - - - Read an `api.json` file: - - - ```php - - $swagger = Swagger::fromFile('api.json'); - - - // or - - - $swagger = new Swagger($array); - - ``` - - - ### Collections - - - There are two major collections: `Paths` and `Definitions`. The API is similar for both: - - - ```php - - $paths = $swagger->getPaths(); - - $p = new Path('/user'); - - - // adding - - $paths->add($p); - - - // retrieving - - if ($paths->has('/user') || $paths->contains($p)) { - $path = $paths->get('/user'); - } - - - // removing - - $paths->remove('/user'); - - - // iterating - - foreach ($paths as $path) { - // do sth with $path - } - - ``` - - - Other collections are: `Headers`, `Parameters`, `Responses` and `SecurityDefinitions`. - - - ### Models - - - There are a lot of models, e.g. the mentioned `Path` above. The API is well written, so it works with the auto-completion of your IDE. It is straight forward and uses the same naming scheme as the OpenAPI specification. - - - - ## Contributing - - - Feel free to fork and submit a pull request (don't forget the tests) and I am happy to merge. - - -Maks3w/SwaggerAssertions: > - # Swagger Assertions - - - Test any API requests and responses match with the models described in the documentation. - - - This project is compatible with [Swagger 2](http://swagger.io/) spec definitions. - - - ## Installing via Composer - - - You can use [Composer](https://getcomposer.org) . - - - ```bash - - composer require fr3d/swagger-assertions - - ``` - - - ## Usage in PHPUnit - - - There are two traits for provide predefined helper functions for different assertions. - - - - [AssertsTrait](src/PhpUnit/AssertsTrait.php) For assert different parts of the response - - - [Psr7AssertsTrait](src/PhpUnit/Psr7AssertsTrait.php) For assert [PSR-7 compatible](http://www.php-fig.org/psr/psr-7/) responses. - - - [SymfonyAssertsTrait](src/PhpUnit/SymfonyAssertsTrait.php) For assert [Symfony HTTP Foundation](http://symfony.com/doc/current/components/http_foundation/index.html) responses. - - - See examples at [examples/PhpUnit](examples/PhpUnit) - - - ## FAQ - - -
-
Q: Can this library validate my Swagger definition?
-
A: No. This library validate your API requests and responses match your Swagger definition.
-
- - - ## License - - Code licensed under BSD 2 clauses terms & conditions. - - See [LICENSE.txt](LICENSE.txt) for more information. -metosin/compojure-api: > - # Compojure-api [![Build - Status](https://api.travis-ci.org/metosin/compojure-api.svg?branch=master)](https://travis-ci.org/metosin/compojure-api) - - - **Psst!** If you're starting a new project, why not try out [reitit](https://github.com/metosin/reitit)? - - - Stuff on top of [Compojure](https://github.com/weavejester/compojure) for making sweet web apis. - - - - [Schema](https://github.com/Prismatic/schema) & [clojure.spec](https://clojure.org/about/spec) (2.0.0) for input & output data coercion - - - [Swagger](http://swagger.io/) for api documentation, via [ring-swagger](https://github.com/metosin/ring-swagger) & [spec-tools](https://github.com/metosin/spec-tools) - - - [Async](https://github.com/metosin/compojure-api/wiki/Async) with async-ring, [manifold](https://github.com/ztellman/manifold) and [core.async](https://github.com/clojure/core.async) (2.0.0) - - - Client negotiable formats: [JSON](http://www.json.org/), [EDN](https://github.com/edn-format/edn) & [Transit](https://github.com/cognitect/transit-format), optionally [YAML](http://yaml.org/) and [MessagePack](http://msgpack.org/) - - - Data-driven [resources](https://github.com/metosin/compojure-api/wiki/Resources-and-Liberator) - - - [Bi-directional](https://github.com/metosin/compojure-api/wiki/Routing#bi-directional-routing) routing - - - Bundled middleware for common api behavior ([exception handling](https://github.com/metosin/compojure-api/wiki/Exception-handling), parameters & formats) - - - Extendable route DSL via [metadata handlers](https://github.com/metosin/compojure-api/wiki/Creating-your-own-metadata-handlers) - - - Route functions & macros for putting things together, including the [Swagger-UI](https://github.com/wordnik/swagger-ui) via [ring-swagger-ui](https://github.com/metosin/ring-swagger-ui) - - - Requires Clojure 1.9.0 & Java 1.8 - - - [API Docs](http://metosin.github.io/compojure-api/doc/) & [Wiki](https://github.com/metosin/compojure-api/wiki) - - - ## Latest version - - - [![Clojars Project](http://clojars.org/metosin/compojure-api/latest-version.svg)](http://clojars.org/metosin/compojure-api) - - - Latest non-alpha: `[metosin/compojure-api "1.1.13"]`. - - - See [CHANGELOG](https://github.com/metosin/compojure-api/blob/master/CHANGELOG.md) for details. - - - ## For information and help - - - ### [Read the Version 1.0 Blog Post](http://www.metosin.fi/blog/compojure-api-100/) - - - ### [Schema & Spec Coercion with 2.0.0](https://github.com/metosin/compojure-api/wiki/Coercion) - - - ### [Check wiki for documentation](https://github.com/metosin/compojure-api/wiki) - - - [Clojurians slack](https://clojurians.slack.com/) ([join](http://clojurians.net/)) has a channel [#ring-swagger](https://clojurians.slack.com/messages/ring-swagger/) for talk about any libraries using Ring-swagger. You can also ask questions about Compojure-api and Ring-swagger on other channels at Clojurians Slack or at #clojure on Freenode IRC (mention `compojure-api` or `ring-swagger` to highlight us). - - - ## Examples - - - ### Hello World Api - - - ```clj - - (require '[compojure.api.sweet :refer :all]) - - (require '[ring.util.http-response :refer :all]) - - - (def app - (api - (GET "/hello" [] - :query-params [name :- String] - (ok {:message (str "Hello, " name)})))) - ``` - - - ### Hello World, async - - - ```clj - - (require '[compojure.api.sweet :refer :all]) - - (require '[clojure.core.async :as a]) - - - (GET "/hello-async" [] - :query-params [name :- String] - (a/go - (a/* requires server to be run in [async mode](https://github.com/metosin/compojure-api/wiki/Async) - - - ### Hello World, async & data-driven - - - ```clj - - (require '[compojure.api.sweet :refer :all]) - - (require '[clojure.core.async :as a]) - - (require '[schema.core :as s]) - - - (context "/hello-async" [] - (resource - {:get - {:parameters {:query-params {:name String}} - :responses {200 {:schema {:message String}} - 404 {} - 500 {:schema s/Any}} - :handler (fn [{{:keys [name]} :query-params}] - (a/go - (a/* Note that empty body responses can be specified with `{}` or `{:schema s/Any}` - - - ### Hello World, async, data-driven & clojure.spec - - - ```clj - - (require '[compojure.api.sweet :refer :all]) - - (require '[clojure.core.async :as a]) - - (require '[clojure.spec.alpha :as s]) - - - (s/def ::name string?) - - (s/def ::message string?) - - - (context "/hello-async" [] - (resource - {:coercion :spec - :get {:parameters {:query-params (s/keys :req-un [::name])} - :responses {200 {:schema (s/keys :req-un [::message])}} - :handler (fn [{{:keys [name]} :query-params}] - (a/go - (a/+ - # AutoRest - - - - The **AutoRest** tool generates client libraries for accessing RESTful web services. Input to *AutoRest* is a spec that describes the REST API using the [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification) format. - - - - - - ## Support Policy - - AutoRest is an open source tool -- if you need assistance, first check the documentation. If you find a bug or need some help, feel free to submit an [issue](https://github.com/Azure/autorest/issues) - - - # Getting Started using AutoRest ![image](./docs/images/normal.png) - - - Start by reading the documentation for using AutoRest: - - - [Installing AutoRest](./docs/installing-autorest.md) - Shows how to install AutoRest. - - - [Understanding AutoRest Versions and Extensions](./docs/autorest-versioning.md) - AutoRest core and extension versioning - - - [Managing AutoRest](./docs/managing-autorest.md) - shows how to get new updates to AutoRest and choose which version to use for code generation. - - - [Generating a Client using AutoRest](./docs/examples/generating-a-client.md) - shows simple command line usage for generating a client library. - - - [Command Line Interface Documentation](./docs/user/command-line-interface.md) - explains common command line arguments. - - - [Examples](./Samples) - full, walkthrough-style scenarios for using AutoRest. - - - [Recent Updates](./changelog.md) - notes on recent updates . - - - # New! AutoRest Version 3.0 - - AutoRest 3.0 introduces a large number of internal changes to support new scenarios. - - - ## Features - - - ### OpenAPI3 support! - - AutoRest 3.0 finally supports OpenAPI3 files as an input format, with the following caveats: - - - existing AutoRest v2 generators may not support all features from OpenAPI3. (see next section) - - - `anyOf`, `oneOf` are not currently supported - - - other OpenAPI3 specific features may not be entirely supported. - - - ### Generators - - - A new set of language generator plugins are being written that adopt the lighter-weight patterns for Azure Core libraries.
- - Existing V2 generators will default to processing with the AutoRest 2 pipeline.
- - If you want to force it to use the v3 (to get support for OpenAPI3 ) add `--v3` to the command line: - - > `autorest --v3 --csharp ...` - - - | Generator | Command | Notes | - - |----|---|---| - - |PowerShell| `autorest --powershell ...` |Fully V3 Supported - use to generate powershell modules | - - |CSharp|`autorest --csharp ...` |v2 generator, may use OpenAPI3 with `--v3` switch (may be some differences) - v3 generator in progress | - - |Python|`autorest --python ...` |v2 generator, may use OpenAPI3 with `--v3` switch (may be some differences) - v3 generator in progress| - - |Java|`autorest --java ...` |v2 generator, may use OpenAPI3 with `--v3` switch (may be some differences) - v3 generator in progress | - - |TypeScript|`autorest --typescript ...` |v2 generator, may use OpenAPI3 with `--v3` switch (may be some differences) - v3 generator in progress | - - |Go|`autorest --go ...` |v2 generator, may use OpenAPI3 with `--v3` switch (may be some differences) - v3 generator in progress | - - |Ruby|`autorest --ruby ...` |v2 generator - does not support v3 feature, no OpenAPI3 support | - - - #### New V3 Pipeline - - - In AutoRest v3, the pipeline has been drastically rebuilt, which allows support for: - - - OpenAPI3 inputs - - - Supporting merging multiple API versions - - - Model Deduplication and Subset reduction across multiple API versions - - - Azure Profile support (v3 generator required) - - - Some related information: - - - [Validation Rules & Linting](https://github.com/Azure/azure-openapi-validator/blob/master/docs/readme.md) - about the validation rules in AutoRest - - - [Client Runtimes](./docs/developer/architecture/Autorest-and-Clientruntimes.md) - information about the client runtimes required for using code generated by AutoRest - - - - - ### Supported Platforms - - - While AutoRest itself runs on NodeJS, some generators use the .NET Core 2.0 runtime, which is the most limiting factor. - - See [dotnet/core/release-notes/2.0/2.0-supported-os.md](https://github.com/dotnet/core/blob/master/release-notes/2.0/2.0-supported-os.md) for a list of supported platforms. - - - --- - - - ### Code of Conduct - - This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. - -subeeshcbabu/swagmock: > - # swagmock - - Mock data generator for swagger api - - - *Note: Swagmock version `1.0.0` onwards requires `Node.js v6+` (`"engines": {"node": ">=6.x"}`). Please use `v0.0.x` (say `0.0.5`), if you want to run this module on any previous node.js versions.* - - - ## Install - - - ``` - - npm install swagmock - - ``` - - - ## Usage - - - ```javascript - let Swagmock = require('swagmock'); - let Mockgen = Swagmock(api, options); - // api Can be one of the following. - // 1) A relative or absolute path to the Swagger api document. - // 2) A swagger api Object. - // 3) A promise (or a `thenable`) that resolves to the swagger api Object. - // Set the `validated` : `true` in `options`, if the api Object is already validated - // and dereferenced ($ref are resolved ). - ``` - - - Promise response: - - - ```javascript - let responseMock = Mockgen.responses({}); //returns a promise that resolves to response mock - responseMock.then(mock => { - //Use mock here - }).catch(error => { - Assert.ifError(error); - }); - ``` - - - Callback style: - - - ```javascript - - Mockgen.responses({ path: '/somepath'}, (error, mock) => { - Assert.ifError(error); - //Use mock here - }); - ``` - - - Check the [API](README.md#api) for more details. - - - ## Example - - - Initialize the mock generator - - - ```javascript - const apiPath = 'http://petstore.swagger.io/v2/swagger.json'; - let Assert = require('assert'); - let Swagmock = require('swagmock'); - let Mockgen = Swagmock(apiPath); - ``` - - - Response mock generation: - - - ```javascript - mockgen.responses({ - path: '/pet/findByStatus', - operation: 'get', - response: 200 - }).then(mock => { - console.log(mock); // This would print: - // { - // "responses": [{ - // "id": 2530624032210944, - // "category": { - // "id": 8200505595527168, - // "name": "r($vA&" - // }, - // "name": "doggie", - // "photoUrls": ["p0x1", "6O)3*kO"], - // "tags": [{ - // "id": 4590764340281344, - // "name": "WCTA6f!" - // }, { - // "id": -4614156653166592, - // "name": "e" - // }], - // "status": "pending" - // }] - // } - }).catch(error => { - Assert.ifError(error); - }); - ``` - - - Parameters mock generation: - - - ```javascript - - mockgen.parameters({ - path: '/pet/findByStatus', - operation: 'get' - }).then(mock => { - console.log(mock);//This would print: - // { - // "parameters": { - // "query": [{ - // "name": "status", - // "value": [ 'available', 'pending' ], - // "separator": "multi" - // }] - // } - // } - }).catch(error => { - Assert.ifError(error); - }) - - ``` - - - Check [Examples](docs/EXAMPLES.md) for more details on mock generators. - - - ## API - - - `Swagmock(api, [options])` - - - * `api` - (*Object*) or (*String*) or (*Promise*) - (required) - api can be one of the following. - - A relative or absolute path to the Swagger api document. - - A URL of the Swagger api document. - - The swagger api Object - - A promise (or a `thenable`) that resolves to the swagger api Object - - * `options` - (*Object*) - (optional) - Additional options to create the mock generator. - - `validated` - Set this property to `true` if the api is already validated against swagger schema and already dereferenced all the `$ref`. This is really useful to generate mocks for parsed api specs. Default value for this is `false` and the api will be validated using [swagger-parser validate](https://github.com/BigstickCarpet/swagger-parser/blob/master/docs/swagger-parser.md#validateapi-options-callback). - - ## responses - - - `mockgen.responses(options, [callback])` - - - This generates the mock response objects based on the `options` - - - * `options` - (*Object*) - (required) - Options to control the mock generation. - - - * `callback` - (*Function*) - (optional) - `function (error, mock)`. If a callback is not provided a `Promise` will be returned. - - - ### options - - - * `path` - (*String*) - (optional) - The path for which the response mock need to be generated. For example `/pet/findByStatus`, `/pet` etc. If a `path` is not specified, mock response will be generated for all the paths defined by the swagger api. - - - * `operation` - (*String*) - (optional) - The operation for which the response mock need to be generated. For example `get`, `post` etc. If `operation` is not specified, mock response will be generated for all the operations defined by the swagger api. - - - * `response` - (*String*) - (optional) - The response for which the response mock need to be generated. For example `200`, `400`, `default` etc. If `response` is not specified, mock response will be generated for all the responses defined by the swagger api. - - - * `useExamples` - (*Boolean*)- (optional) - Should the generated mock make use of example values defined in your swagger.json. Note: invalid example values will create invalid mockdata! - - - ## parameters - - - `mockgen.parameters(options, [callback])` - - - This generates the mock parameters objects based on the `options` - - - * `options` - (*Object*) - (required) - Options to control the mock generation. - - - * `callback` - (*Function*) - (optional) - `function (error, mock)`. If a callback is not provided a `Promise` will be returned. - - - ### options - - - * `path` - (*String*) - (optional) - The path for which the parameters mock need to be generated. For example `/pet/findByStatus`, `/pet` etc. If a `path` is not specified, mock parameters will be generated for all the paths defined by the swagger api. - - - * `operation` - (*String*) - (optional) - The operation for which the parameters mock need to be generated. For example `get`, `post` etc. If `operation` is not specified, mock parameters will be generated for all the operations defined by the swagger api. - - - - ## requests - - - `mockgen.requests(options, [callback])` - - - This generates the mock request object based on the `options`. `requests` API resolves the `parameters` mock data to generate the `request` mock object useful for unit tests. - - - * `options` - (*Object*) - (required) - Options to control the mock generation. - - - * `callback` - (*Function*) - (optional) - `function (error, mock)`. If a callback is not provided a `Promise` will be returned. - - - ### options - - - * `path` - (*String*) - (optional) - The path for which the parameters mock need to be generated. For example `/pet/findByStatus`, `/pet` etc. If a `path` is not specified, mock parameters will be generated for all the paths defined by the swagger api. - - - * `operation` - (*String*) - (optional) - The operation for which the parameters mock need to be generated. For example `get`, `post` etc. If `operation` is not specified, mock parameters will be generated for all the operations defined by the swagger api. - - - ### data - - - `request` Object will have following possible properties `query`, `header`, `pathname`, `path`, `formData` or `body` based on the `parameters` defined for the path and operation. - - - Mock request [Path templates](http://swagger.io/specification/#pathTemplating) are resolved using path parameters. - - - ```javascript - mockgen.requests({ - path: '/pet/findByStatus', - operation: 'get' - }, function (error, mock) { - assert.ifError(error); - - console.log(mock); - //This would print: - // { - // "request": { - // "query": "status=available&status=pending" - // } - // } - }); - ``` - - ## Examples - - - ### API - - [Usage](docs/EXAMPLES.md) - - - ### Unit test request mocks - - - [github api express app](https://github.com/subeeshcbabu/swaggerize-examples/tree/master/express/github-express/tests) - - - [slack api hapi app](https://github.com/subeeshcbabu/swaggerize-examples/tree/master/hapi/slack/tests) - - - ### Mock response data providers - - - [spotify api hapi app](https://github.com/subeeshcbabu/swaggerize-examples/tree/master/hapi/spotify/data) - - - [glugbot api express app](https://github.com/subeeshcbabu/swaggerize-examples/tree/master/express/glugbot-express/tests/api) -zalando/friboo: > - # friboo - - - ![Maven Central](https://img.shields.io/maven-central/v/org.zalando.stups/friboo.svg) - - [![Build Status](https://travis-ci.org/zalando/friboo.svg?branch=master)](https://travis-ci.org/zalando/friboo) - - [![codecov](https://codecov.io/gh/zalando/friboo/branch/master/graph/badge.svg)](https://codecov.io/gh/zalando/friboo) - - - **Friboo** is a lightweight utility library for writing microservices in Clojure. It provides several components that you can use with Stuart Sierra's [Component lifecycle framework](https://github.com/stuartsierra/component). - - - Friboo encourages an "API First" approach based on the [Swagger specification](http://swagger.io/). As such, the REST API is defined as YAML. - - - ## Leiningen dependency - - [org.zalando.stups/friboo 2.0.0] - - ## Why Friboo? - - - - Friboo allows you to first define your API in a portable, language-agnostic format, and then implement it (with the help of [swagger1st](https://github.com/sarnowski/swagger1st)). - - - It contains ready-made components/building blocks for your applications: An HTTP server, DB access layer, metrics registry, Hystrix dashboard (in case you have compliance requirements to follow), and more. See [Components](#components). - - - Pluggable support for all authentication mechanisms (basic, OAuth 2.0, API keys). - - - It contains the "glue code" for you, and there is already a recommended way of doing things. - - - ## Development Status - - - In our production we use an extension library that is based on Friboo: [friboo-ext-zalando](https://github.com/zalando-incubator/friboo-ext-zalando). - - See the list at the end of this page. - - However, there is always room for improvement, so we're very much open to contributions. For more details, see our [contribution guidelines](CONTRIBUTING.md) and check the Issues Tracker for ways you can help. - - - ## Getting Started - - - ### Requirements - - - * [Leiningen](http://leiningen.org/) - - - ### Starting a New Project - - - To start a new project based on Friboo, use the Leiningen template: - - $ lein new friboo com.example/friboo-is-awesome - - This will generate a sample project containing some "foobar" logic that can serve as a starting point in your experiments. - - - A new directory with name `friboo-is-awesome` will be created in the current directory, containing the following files: - - - ``` - - friboo-is-awesome - - ├── README.md - - ├── dev - - │   └── user.clj - - ├── dev-config.edn - - ├── project.clj - - ├── resources - - │   └── api - - │   └── api.yaml - - ├── src - - │   └── com - - │   └── example - - │   └── friboo_is_awesome - - │   ├── api.clj - - │   └── core.clj - - └── test - └── com - └── example - └── friboo_is_awesome - ├── api_test.clj - └── core_test.clj - ``` - - - * `README.md` contains some pregenerated development tips for the new project. - - * `dev/user.clj` contains functions for [Reloaded Workflow](http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded). - - * `dev-config.edn` contains environment variables that will be used during reloaded workflow (instead of putting them into `profiles.clj`). - - * `project.clj` contains the project definition with all dependencies and some additional plugins. - - * `resources/api.yaml` contains the [Swagger API definition](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) in .yaml format. - - * `src` directory contains these files: - * `core.clj` is the [system](https://github.com/stuartsierra/component#systems) definition. - * `api.clj` contains API endpoint handlers. - * the `test` directory contains unit test examples using both `clojure.test` and [Midje](https://github.com/marick/Midje). - - - ## How Friboo works - - - There are two core parts in any Friboo application: - - - - loading configuration by aggregating many sources - - - starting the [system](https://github.com/stuartsierra/component#systems) - - - Both these parts are taken care of in `core.clj` in `run` function. The name "run" is not fixed, it can be anything. - - - Let's put configuration aside for now. A minimal `run` function might look like this: - - - ```clojure - - (require '[com.stuartsierra.component :as component] - '[org.zalando.stups.friboo.system.http :as http] - '[org.zalando.stups.friboo.system :as system]) - - (defn run [] - (let [system (component/map->SystemMap - {:http (http/make-http "api.yaml" {})})] - (system/run {} system))) - ``` - - - Here we declare a system that has just one component created by `make-http` function. When started, this component will expose a RESTful API - - where requests are routed according to the Swagger definition in `api.yaml`, which is taken from the classpath (usually `resources/api.yaml`). - - - Then we call `run` from `-main`: - - - ```clojure - - (defn -main [& args] - (try - (run) - (catch Exception e - (println "Could not start the system because of" (str e)) - (System/exit 1)))) - ``` - - - `run` function does not block, it immediately returns the started system that can later be stopped (as reloaded workflow suggests). - - - This already works, but it's not too flexible. - - - ### Parsing configuration options - - - According to https://12factor.net/config, configuration should be provided via environment variables. - - However, with REPL-driven [reloaded workflow](http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded) you would have to restart the JVM - - every time you need to change a configuration value. That's less than perfect. - - - Friboo supports several sources of configuration: - - - - environment variables: `HTTP_PORT=8081` - - - JVM properties: `http.port=8081` - - - development configuration from `dev-config.edn`: `{:http-port 8081}` - - - default configurations per component (hardcoded) - - - Another challenge is — how to give components only the configuration they need? What if more than one component would like to use `PORT` variable? - - Friboo solves this with namespacing of configuration parameters. Namespace in this case is just a known prefix: `HTTP_`, `API_`, `ENGINE_` etc. - - - Configuration is in loaded inside `run` by `load-config` function before defining the system: - - - ```clojure - - (defn run [args-config] - (let [config (config/load-config - (merge default-http-config - args-config) - [:http]) - system (component/map->SystemMap - {:http (http/make-http "api.yaml" (:http config))})] - (system/run config system))) - ``` - - - Here we make `run` accept a configuration map as an argument, it acts as an additional source of configuration (and it is used by Reloaded Workflow to inject reloadable configuration, see `dev/user.clj`). - - - `load-config` takes 2 arguments: - - - - map of default configuration that looks like this: - - - ```clojure - - {:http-port 8081 - :db-password "1q2w3e4r5t" - :foo-bar "foobar" - ``` - - - - list of namespaces, which are known prefixes configuration variables that we expect: - - - ```clojure - - [:http :db] - - ``` - - - Configuration parameters' names are normalized in the following way (this is actually done by [environ](https://github.com/weavejester/environ)): - - - - `HTTP_PORT` becomes `:http-port` - - - `http.port` becomes `:http-port` - - - `load-config` normalizes names in all configuration sources, merges them (real environment overrules the default config), filters the parameters by known prefixes and returns a nested map: - - - ```clojure - - {:http {:port 8081} - :db {:password "1q2w3e4r5t"}} - ``` - - - Note that `:foo-bar` parameter did not make it into the output, because it does not start with `:http-` nor `:db-`. - - - After we have this configuration loaded, it's very straightforward to give each component its part: - - - ```clojure - - {:http (http/make-http "api.yaml" (:http config)) - :db (db/make-db (:db config))} - ``` - - - `system/run` also takes the entire configuration as the first argument and uses the `:system` part of it. - - - ## Components - - - ### HTTP Component - - - HTTP component starts a HTTP server and routes the requests based on the Swagger API definition. It lives in `org.zalando.stups.friboo.system.http` namespace. - - - It has an optional dependency `:controller` that is given to all - - API handlers as first argument. The use case is to make it contain some configuration - - and dependencies that the handlers should have access to. - - - ```yaml - - paths: - '/hello/{name}': - get: - operationId: "com.example.myapp.api/get-hello" - responses: {} - ``` - - - Part of system map (we make `:api` component to be a simple map, it's not necessary - - for every component to implement `com.stuartsierra.component/Lifecycle` protocol): - - - ```clojure - - :http (component/using - (http/make-http "api.yaml" (:http config)) - {:controller :api}) - :api {:configuration (:api config)} - - ``` - - - `{:controller :api}` means that `:api` component will be available to `:http` under the name `:controller`, that's what it expects. - - - In `com.example.myapp.api` namespace: - - - ```clojure - - (defn get-hello [{:keys [configuration]} {:keys [name]} request] - (response {:message (str "Hello " name)})) - ``` - - - `get-hello` (and every other API handler function) is called with 3 arguments: - - - - `:controller` (`:api` component in our example) - - - merged parameters map from path, query and body parameters - - - raw request map - - - Every handler function is expected to return a map representing a HTTP response: - - - ```clojure - - {:body {:message "Hello Michael"} - :headers {} - :status 200 - ``` - - - In our example we use `ring.util.response/response` to create a HTTP 200. - - - #### Configuration Options - - - * There are all the [configuration options](https://ring-clojure.github.io/ring/ring.adapter.jetty.html) that Jetty supports, for example: - - - ```clojure - - {:port 8081 - :cors-origin "*.zalando.de"} - ``` - - - ### DB Component - - - DB component encapsulates JDBC connection pool and provides [Flyway](https://flywaydb.org/) to support schema migrations. - - - When the component starts, it will have additional `:datasource` key that contains an implementation of `javax.sql.DataSource`. You can use it as you like. - - - One of the examples is in friboo-ext-zalando: - - $ lein new friboo-ext-zalando db-example - - Take a look at the following files: - - - ``` - - example - - ├── resources - - │   └── db - - │   ├── migration - - │   │   └── V1__initial_schema.sql - - │   └── queries.sql - - └── src -    └── db_example -    ├── api.clj -    ├── core.clj -    └── sql.clj - ``` - - - #### Configuration Options - - - For available options please refer to `org.zalando.stups.friboo.system.db/start-component` - - - ### Metrics Component - - - The metrics component initializes a [Dropwizard MetricsRegistry](http://metrics.dropwizard.io) to measure - - frequency and performance of the Swagger API endpoints; see [HTTP component](#http-component). - - - ### Management HTTP component - - - This component starts another embedded Jetty at a different port (default 7979) and exposes endpoints used to monitor and manage the application: - - - * `/metrics`: A JSON document containing all metrics, gathered by the metrics component - - * `/hystrix.stream`: The [Hystrix](https://github.com/Netflix/Hystrix) stream (can be aggregated by [Turbine](https://github.com/Netflix/Turbine)) - - * `/monitor/monitor.html`: The Hystrix dashboard - - - #### Configuration Options - - - All [Jetty configuration options](https://ring-clojure.github.io/ring/ring.adapter.jetty.html). - - - ## Real-World Usage - - - There are multiple examples of real-world usages of Friboo, including among Zalando's STUPS components: - - - * [Pier One Docker registry](https://github.com/zalando-stups/pierone) (REST service with DB and S3 backend) - - * [Kio application registry](https://github.com/zalando-stups/kio) (REST service with DB) - - * [Even SSH access granting service](https://github.com/zalando-stups/even) (REST service with DB) - - * [Essentials](https://github.com/zalando-stups/essentials) (REST service with DB) - - - TODO HINT: set java.util.logging.manager= org.apache.logging.log4j.jul.LogManager to have proper JUL logging. - - - ## License - - - Copyright © 2016 Zalando SE - - - Licensed under the Apache License, Version 2.0 (the "License"); - - you may not use this file except in compliance with the License. - - You may obtain a copy of the License at - - [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) - - Unless required by applicable law or agreed to in writing, software - - distributed under the License is distributed on an "AS IS" BASIS, - - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - - See the License for the specific language governing permissions and - - limitations under the License. -krakenjs/generator-swaggerize: > - # generator-swaggerize - - - [![Build Status](https://travis-ci.org/krakenjs/generator-swaggerize.svg?branch=master)](https://travis-ci.org/krakenjs/generator-swaggerize) - - [![NPM version](https://badge.fury.io/js/generator-swaggerize.png)](http://badge.fury.io/js/generator-swaggerize) - - - - Yeoman generator for swagger application with `swaggerize` tools. - - - Generates projects for: - - - Express - - - Hapi - - - Restify - - - See also: - - - [swaggerize-express](https://github.com/krakenjs/swaggerize-express) - - - [hapi-openapi](https://github.com/krakenjs/hapi-openapi) (formerly `swaggerize-hapi`) - - - ### Usage - - - Install yeoman's `yo` if you haven't already: - - - ``` - - $ npm install -g yo - - ``` - - - Install `generator-swaggerize`: - - - ``` - - $ npm install -g generator-swaggerize - - ``` - - - Create a project: - - - ``` - - $ yo swaggerize - - ``` - - - ### Generators - - - - `yo swaggerize` - - - Generates a new swaggerize application - - - ``` - - $ yo swaggerize - - Swaggerize Generator - Tell us a bit about your application - ? Path (or URL) to swagger document: http://petstore.swagger.io/v2/swagger.json - ? Framework: express - ? What would you like to call this project: myapp - ? Your name: Lorem Ipsum - ? Your github user name: loremipsum - ? Your email: loremipsum@awesome.com - create .eslintrc - create .gitignore - create .npmignore - create package.json - create README.md - . - . - . - ``` - - - If you want to generate (or regenerate) only a specific component, you can use `swaggerize` sub generators. - - - - `yo swaggerize:data` - - - Generates `data` providers based on `paths` and `responses` in swagger api document. - - This also generates the `config/swagger.json` (A copy of the swagger api document file input) and `security` authorize handlers based on `securityDefinitions`. - - - - `yo swaggerize:handler` - - - Generates `handlers` based on `paths` in swagger api document. (`data` providers are also generated as a pre step) - - - - `yo swaggerize:test` - - - Generates unit `tests` based on `paths`, `parameters` and `responses` in swagger api document. (`handlers` and `data` providers are also generated as a pre step) - - - #### Project structure - - - - `/config` - A copy of the swagger api document file input, will be generated at `/config/swagger.json`. - - - `/data` - Data providers for paths(routes). - - - `/security` - Authorize handlers for security schemes declared by `securityDefinitions`. - - - `/handlers` - Application paths (routes) based on swagger api `paths`. - - - `/tests` - Unit tests for paths(routes). - - - Example: - - - ``` - ├── README.md - ├── .eslintrc - ├── .gitignore - ├── .npmignore - ├── config - │ └── swagger.json - ├── data - │ ├── mockgen.js - │ └── hellopath - │ └── {id}.js - ├── handlers - │ └── hellopath - │ └── {id}.js - ├── package.json - ├── security - │ ├── hello_Oauth2.js - │ └── hello_api_key.js - ├── server.js - └── tests - └── hellopath - └── {id}.js - ``` - - - ##### Handlers - - - A handler file will be generated corresponding to every a `path` definition of the swagger api (`paths`). - - - More details or handlers and routing: - - - [swaggerize-express handlers](https://github.com/krakenjs/swaggerize-express#handlers-directory) - - - [swaggerize-hapi handlers](https://github.com/krakenjs/swaggerize-hapi#handlers-directory) - - - ##### Data providers - - - A data file will be generated corresponding to every a `path` definition of the swagger api (`paths`). - - - By default [Response Mock generator](https://github.com/subeeshcbabu/swagmock#responses) is used to provide the data based on the `responses` definition of swagger api. - - Developers should replace these default mock data generators with actual data feeds, based on the functionality. - - - ##### Security authorize handlers - - - A security authorize handler file will be generated corresponding to the declaration of the security schemes `securityDefinitions`. - - - ##### Unit tests - - - A unit test file will be generated corresponding to every a `path` definition of the swagger api (`paths`). - - - By default [Request Mock generator](https://github.com/subeeshcbabu/swagmock#requests) is used to generator api requests based on the `parameters` definition of swagger api. - - - #### CLI Options - - - - `--framework` - specify the framework (`hapi`, `express`, or `restify`). - - - `--apiPath` - specify the path to the swagger document. - - - `--handlerPath` - specify the path to generate the handler files. By default `handlers` directory. - - - `--dataPath` - specify the path to generate the data files. By default `data` directory. - - - `--securityPath` - specify the path to generate the security authorize files. By default `security` directory. - - - `--testPath` - specify the path to generate the unit test files. By default `tests` directory. - - - `--skip-npm-install` - To skip the default `npm install` on the generated project. - - - #### Prompts - - - - `apiPath` - Path (or URL) to swagger document - - - The path to the swagger api document. This path could be a local or remote URL. - - - If there is no CLI option `--apiPath` specified, the generator will prompt for `apiPath`. The swagger api will be validated against the swagger schema and spec before proceeding with scaffolding process. - - - - `framework` - The choice of framework to generate the application. - - - There are three options - `express`, `hapi` and `restify`. If there is no CLI option `--framework` specified, the generator will prompt for `framework`. - - - Also, generator checks the working directory for `package.json` dependencies, to find out whether the application already depends on, one of the framework options. If a match is found, that framework will be used as an option without prompting for the value. - - - - `appName` - The name of the application - - - By default the yeoman project root will be used as the name of the application, however, the prompt lets developers change this default. - - - - `creatorName`, `githubUser` and `email` - Creator details to build the `package.json`. -ninenines/cowboy: | - = Cowboy - - Cowboy is a small, fast and modern HTTP server for Erlang/OTP. - - == Goals - - Cowboy aims to provide a *complete* HTTP stack in a *small* code base. - It is optimized for *low latency* and *low memory usage*, in part - because it uses *binary strings*. - - Cowboy provides *routing* capabilities, selectively dispatching requests - to handlers written in Erlang. - - Because it uses Ranch for managing connections, Cowboy can easily be - *embedded* in any other application. - - Cowboy is *clean* and *well tested* Erlang code. - - == Online documentation - - * https://ninenines.eu/docs/en/cowboy/2.6/guide[User guide] - * https://ninenines.eu/docs/en/cowboy/2.6/manual[Function reference] - - == Offline documentation - - * While still online, run `make docs` - * User guide available in `doc/` in PDF and HTML formats - * Function reference man pages available in `doc/man3/` and `doc/man7/` - * Run `make install-docs` to install man pages on your system - * Full documentation in Asciidoc available in `doc/src/` - * Examples available in `examples/` - - == Getting help - - * Official IRC Channel: #ninenines on irc.freenode.net - * https://github.com/ninenines/cowboy/issues[Issues tracker] - * https://ninenines.eu/services[Commercial Support] - * https://github.com/sponsors/essen[Sponsor me!] -BlueOakJS/blueoak-server: >+ - ![BlueOak - Logo](https://github.com/BlueOakJS/blueoak-server/wiki/images/blueoak.png) - - ====== - - - BlueOak Server is a NodeJS framework for building RESTful APIs. - - - [![Build Status](https://travis-ci.org/BlueOakJS/blueoak-server.svg?branch=master)](https://travis-ci.org/BlueOakJS/blueoak-server) - - [![npm version](https://img.shields.io/npm/v/blueoak-server.svg)](https://www.npmjs.com/package/blueoak-server) - - - BlueOak Server is _swagger-matic_, that is, it maximizes the value of your Swagger API (now OpenAPI, but really this supports only V2) by using it to drive runtime behavior. - - BlueOak Server loads your Swagger API, connects the paths it defines to your implementation code, exposes that API to the network, and validates that every request is well-formed per that API. - - - Check out the documentation on our wiki: - - - ### Overview - - - BlueOak Server combines some of the best Node libraries into a single tool for building RESTful APIs. It uses Express under the covers, but adds many additional features: - - - - Swagger integration - - - Easy configuration - - - Clustering - - - Logging - - - Dependency injection - - - Projects use the following directory structure. - - - ``` - - ├── [your_project_name]/ - - │ ├── index.js <-- optional Main script - - │ ├── package.json - - | ├── config/ - - | | └── default.json - - │ ├── handlers/ - - │ ├── services/ - - │ ├── middleware/ - - │ ├── swagger/ - - ``` - - - #### Handlers - - [Handlers](https://github.com/BlueOakJS/blueoak-server/wiki/Handlers) contain Express route-handling functions. They can either be directly wired to routes on the Express _app_, or defined using Swagger. - - - To use the _app_ directly, simply create a js file in the handlers directory that exports an `init` function. - - The `init` function is called during server startup and injected with the the _app_ automatically. - - - ```js - - exports.init = function(app) { - app.get('/', function(req, res) { - res.json({}); - }); - } - - - ``` - - - #### Services - - [Services](https://github.com/BlueOakJS/blueoak-server/wiki/Services) do most of the heavy lifting. Like handlers, services contain init functions that are called during server startup. However, services can export other functions, and those functions can be invoked from handlers. - - - Here's an example of a fizzbuzz service (services/fizzbuzz.js). You'll notice it has an init method with two parameters, _logger_ and _callback_. The _logger_ is a [built-in service](https://github.com/BlueOakJS/blueoak-server/wiki/Logging-Service) for logging. The _callback_ is an optional parameter used for cases where services need to perform asynchronous operations during startup. The service also exports a _getResult_ function. Any service or handler with a dependency on _fizzbuzz_ can invoke `fizzbuzz.getResult`. - - - ```js - - exports.init = function(logger, callback) { - logger.info("Starting FizzBuzz service"); - callback(); - } - - - exports.getResult = function(num) { - if (num % 15 === 0) { - return "FizzBuzz"; - } else if (num % 3 === 0) { - return "Fizz"; - } else if (num % 5 === 0) { - return "Buzz"; - } else { - return num; - } - }; - - ``` - - - We want to use that service from our handler, so we include `fizzbuzz` as a parameter of the `init` function. - - The server will ensure that the fizzbuzz service is initialized during server startup and passed to the handler. - - - ```js - - exports.init = function(app, fizzbuzz) { - - app.get('/fizzbuzz/:num', function(req, res) { - var num = req.params.num; - res.json({ - result: fizzbuzz.getResult(num) - }); - }); - - - } - - ``` - - #### Third-party Services - - Services can be published as npm modules and pulled into projects through the `npm install` command. - - - For example, the bos-couchdb service adds the ability to connect to a CouchDB database. - - It can be installed to a blueoak-server project using - - - ```bash - - $ npm install bos-couchdb --save - - ``` - - - Once installed, it can be used in any service or handler through the dependency-injected `bosCouchdb` parameter. - - - ```js - - exports.init = function(config, logger, bosCouchdb) { - var myDb = bosCouchdb.get('mydb'); - } - - - ``` - - - * [bos-couchdb](https://github.com/BlueOakJS/bos-couchdb) - service for connecting to CouchDB databases - - - #### Config - - [Configuration](https://github.com/BlueOakJS/blueoak-server/wiki/Services#config) is stored in json files in the _config_ directory. Values can be accessed through the `config` service in handers and services. Configuration also supports layering on environment-specific config as well as encrypted values. - - - ```js - - exports.init = function(config) { - var myServiceConfig = config.get('myService'); - } - - ``` - - - #### Middleware - - [Middleware](https://github.com/BlueOakJS/blueoak-server/wiki/Middleware) are similar to services but used to wire up Express middleware. The _express_ section of the config determines which middleware is loaded and in which order. - - - ```json - - { - "express": { - "middleware": ["csrf", "cors", "session", "body-parser"] - } - } - - ``` - - - #### Swagger (OpenAPI) - - - [Swagger](https://github.com/BlueOakJS/blueoak-server/wiki/Handlers#swagger) files in the _swagger_ directory are read during server startup and automatically wired up to handlers. Swagger files can be in either json or yaml formats. - - - We've really focused on making API development with Swagger and BlueOak Server to be excellent. - - - At a high-level, BlueOak Server's Swagger support provides the following: - - * Automatic app routing from the API method to the function as defined in the Swagger - - * Request parameter validation, including the body model, based on your method definion - - * Reponse model validation based on your method definitions during development - - * JSON `$ref`s to external Swagger documents on the file system - - * Multiple top-level Swagger API definitions supporting delivery of multiple API base paths - - * Publishing of the fully compiled Swagger spec for input to by tools such as [`Swagger-UI`](http://swagger.io/swagger-ui/) and [`swagger-commander`](https://www.npmjs.com/package/swagger-commander) - - - ### Installation - - - ```bash - - $ npm install -g blueoak-server - - ``` - - - -or- - - - ```bash - - $ npm install --save blueoak-server - - ``` - - - ### Usage - - - If installed globally, run _blueoak-server_ from within your project's directory. - - e.g.: - - ```bash - - $ blueoak-server - - ``` - - - If installed at a package level, call _blueoak-server_ in the `npm start` script. - - e.g.: - - ```json - "scripts": { - "start": "blueoak-server" - } - ``` - - - Alternatively, it can be launched programmatically from your own js script. - - - - ```js - - var server = require('blueoak-server'); - - - server.init(function(err) { - if (err) { - console.warn(err); - } else { - console.log('started'); - } - }); - - ``` - - - The programmatic approach works well during development with tools like nodemon, - - which monitor for file changes and automatically restart the server. - - - ### Next steps - - - Read through the [docs](https://github.com/BlueOakJS/blueoak-server/wiki) and look at the our [examples](/examples). - - - When you're ready to try it out, start from the [template](https://github.com/BlueOakJS/blueoak-server-template). - -Trax-air/swagger-aggregator: > - .. image:: - https://travis-ci.org/Trax-air/swagger-aggregator.svg?branch=master - :alt: Travis status - .. image:: https://badges.gitter.im/Trax-air/swagger-aggregator.svg - :alt: Join the chat at https://gitter.im/Trax-air/swagger-aggregator - :target: https://gitter.im/Trax-air/swagger-aggregator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - .. image:: https://img.shields.io/pypi/v/swagger-aggregator.svg - :target: https://pypi.python.org/pypi/swagger-aggregator/ - - swagger-aggregator - - ================== - - - Swagger-aggregator allow you to create a swagger REST API from several other swagger REST APIs. - - - This can be really useful if you want to make an API Gateway accessing some of your internal APIs. - - You can also filter which path you want to deliver, and which properties of your definitions you don't want to show. - - - Related Libraries - - ----------------- - - You may find related libraries to this one: - - - * https://github.com/Trax-air/swagger-tester: Auto-test your swagger API in your unit tests. All test calls are generated by your swagger file. - - * https://github.com/Trax-air/swagger-stub: A stub you can use in your client's unit tests. All the HTTP calls to your swagger API are mocked by default. You can also add your own mocked_calls in your test functions. - - * https://github.com/Trax-air/swagger-parser: A helper that parses swagger specs. You can access the HTTP actions / paths and some example data - - - Example Usage - - ------------- - - - Here is an example of an aggregate configuration. - - - .. code:: yaml - - args: pet_url - - info: - version: "0.1" - title: "API Gateway" - - basePath: /v2 - - apis: - pet: http://pet_url/v2 - - exclude_paths: - - DELETE /pets/{petId} - - exclude_fields: - petPet: - - id - - This is not the most useful aggregation, as it only aggregate one API. - - The first part, `args`, define that the first parameter we will send to the aggregate will be pet_url. Then pet_url will be replaced by the given value everywhere in the config. - - The two next part, `info` and `basePath`, are the same as the ones you can find in every swagger API. - - `apis`, define the different APIs you want to aggregate. A name is associated with it URL. - - Then `exclude_paths` allow you to not deliver some path. In this case we don't want the user to delete a pet. - - - Finally, `exclude_fields` define the attributes of the definitions we do not want to show. - - The value of the keys is the name of the API followed by the name of the definition. The value of each key will be a list of all properties to exclude. - - - Then use this command to generate the aggregated swagger file: - - - .. code:: python - - from traxit_aggregator import SwaggerAggregator - - SwaggerAggregator('config.yaml', 'pet.com') - - Documentation - - ------------- - - - More documentation is available at https://swagger-aggregator.readthedocs.org/en/latest/. - - - Setup - - ----- - - - `make install` or `pip install swagger-aggregator` - - - License - - ------- - - - swagger-aggregator is licensed under http://opensource.org/licenses/MIT. -Reckon-Limited/serverless_swagger: > - # Serverless Swagger # - - - Maps swagger configuration to serverless handlers. - - - ## Installation ## - - - If you don't have a serverless project, create one now: - - - ``` - - sls create -t aws-nodejs --path MyService - - cd MyService - - - ``` - - then - - ``` - - yarn init - - ``` - - or - - ``` - - npm init - - ``` - - - Inside your serverless project directory: - - - ``` - - yarn add serverless_swagger - - ``` - - or - - ``` - - npm install serverless_swagger - - ``` - - - Add the following to serverless.yml: - - - ``` - - plugins: - - serverless_swagger - ``` - - - ## Configuration ## - - - The plugin looks for a `swagger.yml` in your serverless project. - - You can provide a different name by specifying a custom variable: - - - ``` - - custom: - swagger_file: swagger.yml - ``` - - - ## Generation ## - - - A complete set of JS handlers and the appropriate serverless.yml configuration can be generated - - - ``` - - sls swagger - - ``` - - Existing files should not be overwritten, meaning that the swagger can be updated and new functions generated without losing customisations. - - - Generated files can be output to a specified directory using the `--output` flag and a destination directory (which must exist). - - - ``` - - sls swagger --output output - - ``` - - - ## Mapping ## - - - At deploy, each function will be mapped to API Gateway events based on the swagger specification. - - - Functions are mapped by parsing the path and method in the swagger spec to a function name in serverless.yml. - - - For example, given the following `serverless.yml` and `swagger.yml` definitions - - ``` - - functions: - getClientById: - handler: getClientById/handler.main - getClientByName: - handler: getClientByName/handler.main - ``` - - - ``` - paths: - /client/{id}: - get: - summary: "Get client id" - /blah - get: - summary: "Get blah" - ``` - - - The *getClientById* function will be mapped to an API gateway event in the form: - - - ``` - - events: - - http: - method: get - path: /client/{id} - ``` - - - The *getClientByName* does not match any summary information and will not have an event -capitalone/oas-nodegen: > - # Due to changes in the priorities, this project is - currently not being supported. The project is archived as of 9/17/21 and will - be available in a read-only state. Please note, since archival, the project is - not maintained or reviewed. # - - - - - - # oas-nodegen - - - A library for generating completely customizable code from the [Open API Specification](https://openapis.org/specification "Link to OAS") (FKA Swagger) RESTful API documentation using the scripting power of Node.js. - - - ## Installation - - Install oas-nodegen through npm - - ```bash - - $ npm install oas-nodegen - - ``` - - - ## Overview - - - This library is used to compose scripts that produce customizable output using the simple components depicted below. Most of the customization occurs in the various callbacks that the library exposes. **Phase callbacks** are used to modify the specification data prior to being sent to templates. The **Write callbacks** are used to route processed portions of the specification to their target template and location in the filesystem. - - - ![Components of oas-nodegen](https://raw.githubusercontent.com/capitalone/oas-nodegen/master/docs/oas-nodegen-components.png) - - - ### Features: - - - - 100% scriptable and customizable code generation. - - - `Loader` handles loading the API specification as well as any referenced external specification. - - - `Modules` registers and loads out of the box or custom code generation modules. - - - `Templates` registers new template engines and compiles template source into functions. - - The included engines are: - - [Handlebars.js](http://handlebarsjs.com/) - - [Hogan.js](http://twitter.github.io/hogan.js/) - - [Jade / Pug](http://jade-lang.com/) - - [Underscore.js](http://underscorejs.org/) - - Template files can be overridden by adding a template directory with overlapping template file names. - - `Generator` takes a "composition over inheritance" approach that allows you to register any number of modules for model decoration. - - - `Writer` handles cleaning the target directory, recursively creating directories, and writing files with content that is usually generated by templates. - - - ## Usage - - Require the module before using - - ```js - - var nodgen = require('oas-nodegen'); - - - var loader = nodegen.createLoader(); - - var modules = nodegen.createModules(); - - var templates = nodegen.createTemplates(); - - var writer = nodegen.createWriter(baseDir); - - var generator = nodegen.createGenerator(config); - - var utils = nodegen.Utilities; - - ``` - - - ## Roadmap - - - Currently, this library contains several modules for generating Java-based producers and consumers. We'll likely add modules for other popular and emerging languages (e.g. Scala and Golang). That doesn't stop you from creating a module for your favorite language or framework now! The Java module is a good starting point for understanding the handling type translation and language features such as annotations, etc. If you think it would help the community, please contribute it back! - - - ## API - - - ### Loader - - - > [View the JSDoc](docs/loader.md) - - - - load( pathOrUri ).then( function onSuccess ).fail( function onFailure ); - - - ### Modules - - - > [View the JSDoc](docs/modules.md) - - - - registerLibrary( library ); - - - registerModuleDirectory( [ path ] ); - - - registerModule( path ); - - - get( [ names ] ); - - - ### Templates - - - > [View the JSDoc](docs/templates.md) - - - - setDefaultOptions( defaultOptions ); - - - registerLibrary( library ); - - - registerEngineDirectory( path ); - - - registerEngine( pathOrObject ); - - - registerTemplateDirectory( path ) - - - compileFromSource( engineName, source, options ); - - - compileFromFile( templateFile, options ); - - - ### Writer - - - > [View the JSDoc](docs/writer.md) - - - - setLeadingFileComments( comments ); - - - setTrailingFileComments( comments ); - - - preventDeletionOf( pathNames... ); - - - clean(); - - - write( [ path ], filename, content ); - - - ### Generator - - - > [View the JSDoc](docs/generator.md) - - - - configure( config ); - - - addIgnoredOperations( operationNames ); - - - addIgnoredParameters( parameterNames ); - - - setModules( parameters ); - - - use( moduleNamesOrObjects ); - - - emit( phase, event, data ); - - - on( phase, event, data ); - - - onPrepare( event, listener ); - - - onDecorate( event, listener ); - - - onFinalize( event, listener ); - - - write( event, data ); - - - onWrite( event, listener ); - - - process( spec, references ); - - - groupOperation( operation ); - - - groupSort( group ); - - - operationSort( operation ); - - - ### Utilities - - - > [View the JSDoc](docs/utilities.md) - - - - getSuccessResponse( operation ); - - - translate( obj, spec, references ); - - - resolveReference( obj, spec, references ); - - - getReferenceName( $ref ); - - - extractModelName( $ref ); - - - getMimeType( array ); - - - sortKeys( object ); - - - capitalize( string ); - - - uncapitalize( string ); - - - random( low, high ); - - - ## Modules - - - The modules below are designed to enrich the API specification with information to be used by templates. The best approach is to try to keep templates as generic and simple as possible and let the addition of modules change the generated output. For example, most of the Java-based modules below deal with annotations. The provided templates simply render the list of annotations and the modules handle the heavy lifting. - - - ### Helpers - - - - Operations: - - `fullPath` - Concatenated base path and operation path - - `accepts` - Most preferred mime type for the Accepts header - - `contentType` - Most preferred mime type for the ContentType header - - `operationId` - If null, set based on HTTP method and path (however, its recommended to explicitly specify operationId in the specification) - - `resolvedConsumes` - Resolved consumes mimetypes for this operation or base specification - - `resolvedProduces` - Resolved produces mimetypes for this operation or base specification - - Response helpers: - - `successResponse` - Property that reflects the 200 or 201 response - - `hasReturn` - Boolean flag that denotes of a response body is returned - - `parameters` - Updates the parameters array for filter out ignored parameters - - `isQuery` - Boolean flag that denotes if the query string parameters comprise are all optional (e.g. collection query) - - Parameter grouping by type: - - `bodyParam` - The body parameter, if applicable - - `pathParams` - List of path parameters - - `queryParams` - List of query parameters - - `headerParams` - List of header parameters - - `formParams` - List of form parameters - - `requiredParams` - List of all required parameters - - - Models: - - `name` - The model name pulled from the definitions map key - - `references` - The list of models that this model references - - `referencedBy` - The list of models this model is referenced by - - `recursiveReferencedBy` - The recursive list of models this model is referenced by - - `required` - Updated with a materialized list from other entities refereced by $allOf - - `properties` - Updated with a materialized map from other entities refereced by $allOf - - `vars` - The model's properties represented as a list instead of a map - - Materialized information from other models that reference this model - - `allReferences` - A recursive list of models referenced by this model - - `allProperties` - All `properties` from this model and models that reference this model - - `allRequired` - All `required` property names from this model and models that reference this model - - `allVars` - All `vars` from this model and models that reference this model - - - Properties: - - `name` - The property name pull from the properties map key - - `required` - Boolean flag indicated if the property is required - pulled from the model's required list - - ### Java - - - - General: - - `annotations`: - - List of annotations for operations, parameters, models, and properties - - Added by `generator.addAnnotation(annotation, operation|parameter|model|property);` - - `imports` - - List of imports for resources and models - - Added by `generator.addImport(className, resource|model);` - - Generator utility methods: - - `addKnownImports(imports...)` - Adds a known import that can be added via a simple class name - - `findImport(simpleName)` - Finds an import using its simple name - - `classname` - Java-friendly class name for resources and models - - Type translation methods: - - `translateType(schema, resource|model, spec, references)` - Converts a schema into a Java type - - `addTypeTranslator(function(schema, resource|model))` - Adds a hook used by `translateType` to allow for custom types - - `overrideModelPackage($ref, model)` - Hook method that can be replaced in order to override model package name (returning `null` defaults to `config.modelPackage`) - - `variableName(value)` - Produces a Java-friendly variable name from a string value - - Other utility / helper methods: - - `escapeJavaString(value)` - Converts a value into a Java string literal - - `joinStrings(values)` - Escapes and joins a set of values - useful for declaring arrays - - Operations: - - `methodName` - Java-friendle method name - - `returnType` - The class name of the return type - - `returnDescription` - The description from the success response - - Parameters: - - `varname` - Java-friendly variable name - - `dataType` - The data type of the parameter - can be a generic collection - - `itemType` - The item type if the data type is a collection - - `method` - The method to use to set the parameter from a client's perspective - - Models: - - `allImports` - Materialized list of imports from the model and property scopes - - `parent` - The class name of the parent which is based on the first reference under $allOf - - `serialVersionUID` - The long value to use for serialVersionUID for implementing Serializable - - Properties: - - `varname` - Java-friendly variable name - - `dataType` - The data type of the property - can be a generic collection - - `getter` - The getter accessor method name - - `setter` - The setter accessor method name - - `defaultValue` - The property's default value expression - - ### Java8 - - - - Properties: - - `dataType` - - Uses java.util.Optional* types when fields are not required - - Replaces Integer, Long, and Double with OptionalInt, OptionalLong, and OptionalDouble respectively - - Wraps other classes with Optional - - `empty` - The expression to create an empty optional instance - - `assign` - The expression to convert and assign a value to an optional instance - - ### JavaBeanValidation - - - - Parameters & Properties: - - Adds @Min/DecimalMin, @Max/DecimalMax, @Size, @Pattern, @Valid and @NotNull - - ### JaxB - - - - Models: - - Adds @XmlRootElement, @XmlType, @XmlAccessorType, @XmlSeeAlso - - Properties: - - Adds @XmlElementWrapper, @XmlElement based on defined `xml` objects - - ### JaxRS - - - - Resources: - - Adds @Path, @Consumes, @Produces - - Operations: - - Adds @Path, @Consumes, @Produces - - Adds @GET, @POST, @PUT, @DELETE, @HttpMethod("PATCH") - - Parameters: - - Adds @PathParam, @QueryParam, @HeaderParam, @FormParam, @DefaultValue - - ## Example - - To try an example, use the commands below to build and run a Java/Spring Boot API (assumes MongoDB is running and listening on 27017 - authentication disabled): - - ```bash - - $ git clone https://github.com/capitalone/oas-nodegen-example.git - - $ cd oas-nodegen-example - - $ gradle bootRun - - ``` - - - ## Tests - - To run the test suite, first install the dependencies, then run `npm test`: - - ```bash - - $ npm install - - $ npm test - - ``` - - - ## Contributors - - - We welcome your interest in Capital One’s Open Source Projects (the “Project”). Any Contributor to the project must accept and sign a CLA indicating agreement to the license terms. Except for the license granted in this CLA to Capital One and to recipients of software distributed by Capital One, you reserve all right, title, and interest in and to your contributions; this CLA does not impact your rights to use your own contributions for any other purpose. - - - [Link to CLA](https://docs.google.com/forms/d/19LpBBjykHPox18vrZvBbZUcK6gQTj7qv1O5hCduAZFU/viewform "Capital One Individual and Corporate Contributor License Agreement") - - - This project adheres to the [Open Source Code of Conduct](http://www.capitalone.io/codeofconduct/ "Code of Conduct"). By participating, you are expected to honor this code. -calcinai/strut: > - # Strut - - Yet another OpenAPI/Swagger manipulation library! - - - This library is almost 100% generated code by [Gendarme](https://github.com/calcinai/gendarme). The reasoning behind this is that all the information required to manipulate a schema outlined in the specification. - - - ## Installation - - via composer - - ``` - - composer require calcinai/strut - - ``` - - - ## Usage - - The test case for this is the OpenAPI petstore. - - - The library will deserialize an OpenAPI specification into native PHP objects, then serialize it back into its original form, with the only differences (sometimes) being the order of properties in objects (which is of no consequence). - - - ### Loading documents - - - ```php - - $schema = json_decode(file_get_contents('http://petstore.swagger.io/v2/swagger.json')); - - $openapi = \Calcinai\Strut\OpenAPI::create($schema); - - print_r($swagger); - - ``` - - - This will produce (snipped): - - - ``` - - Calcinai\Strut\OpenAPI Object - - ( - [data:protected] => Array - ( - [openapi] => 3.0 - [info] => Calcinai\Strut\Definitions\Info Object - ( - [data:protected] => Array - ( - [version] => 1.0.0 - [title] => OpenAPI Petstore - [license] => Calcinai\Strut\Definitions\License Object - ( - [data:protected] => Array - ( - [name] => MIT - ) - - ) - - ) - - ) - - [servers] => Array - ( - [0] => Calcinai\Strut\Definitions\Server Object - ( - [data:protected] => Array - ( - [url] => https://petstore.openapis.org/v1 - [description] => Development server - ) - - ) - - ) - - [paths] => Calcinai\Strut\Definitions\Paths Object - ( - [data:protected] => Array - ( - [/pets] => Calcinai\Strut\Definitions\PathItem Object - ( - [data:protected] => Array - ( - [get] => Calcinai\Strut\Definitions\Operation Object - ( - [data:protected] => Array - ( - [summary] => List all pets - [operationId] => listPets - [tags] => Array - ( - [0] => pets - ) - - [parameters] => Array - ( - [0] => Calcinai\Strut\Definitions\Parameter Object - ( - [data:protected] => Array - ( - [name] => limit - [in] => query - [description] => How many items to return at one time (max 100) - [required] => - [schema] => Calcinai\Strut\Definitions\Schema Object - ( - [data:protected] => Array - ( - [type] => integer - [format] => int32 - ) - - ) - - ) - - ) - - ) - - [responses] => Calcinai\Strut\Definitions\Responses Object - ( - [data:protected] => Array - ( - [200] => Calcinai\Strut\Definitions\Response Object - ( - [data:protected] => Array - ( - [description] => An paged array of pets - [headers] => Calcinai\Strut\Definitions\HeadersOrReferences Object - ( - [data:protected] => Array - ( - [x-next] => Calcinai\Strut\Definitions\Header Object - ( - [data:protected] => Array - ( - [schema] => Calcinai\Strut\Definitions\Schema Object - ( - [data:protected] => Array - ( - [type] => string - ) - - ) - - [description] => A link to the next page of responses - ) - - ) - - ) - - ) - - [content] => Calcinai\Strut\Definitions\MediaTypes Object - ( - [data:protected] => Array - ( - [application/json] => Calcinai\Strut\Definitions\MediaType Object - ( - [data:protected] => Array - ( - [schema] => Calcinai\Strut\Definitions\Reference Object - ( - [data:protected] => Array - ( - [$ref] => #/components/schemas/Pets - ) - - ) - - ) - - ) - - ) - - ) - - ) - - ) - - ... - - ``` - - - - ### Creating and modifying documents - - - The following is an example of how that schema would be programatically generated: - - - ```php - - $pet = Schema::create() - ->addRequired('id') - ->addRequired('name') - ->setProperties(Properties::create() - ->set('id', Schema::create() - ->setType('integer') - ->setFormat('int64') - ) - ->set('name', Schema::create() - ->setType('string') - ) - ->set('tag', Schema::create() - ->setType('string') - ) - ); - - $pets = Schema::create() - ->setType('array') - ->setItems($pet); - - - $error = Schema::create() - ->addRequired('code') - ->addRequired('message') - ->setProperties(Properties::create() - ->set('code', Schema::create() - ->setType('integer') - ->setFormat('int32') - ) - ->set('error', Schema::create() - ->setType('string') - ) - ); - - - $schema = OpenAPI::create() - ->setInfo( - Info::create() - ->setTitle('Swagger Petstore') - ->setVersion('1.0.0') - ->setLicense( - License::create() - ->setName('MIT') - ) - ) - ->addServer(\Calcinai\Strut\Definitions\Server::create()->setUrl('petstore.swagger.io')) - ->setPaths(Paths::create() - ->set('/pets', PathItem::create() - ->setGet(Operation::create() - ->setSummary('List all pets') - ->setOperationId('listPets') - ->addTag('pets') - ->setResponses(Responses::create() - ->set('200', Response::create() - ->setDescription('A paged array of pets') - ) - ->set('default', Response::create() - ->setDescription('Unexpected error') - ) - ) - ) - ) - ) - ->setComponents(\Calcinai\Strut\Definitions\Components::create() - ->setSchemas(\Calcinai\Strut\Definitions\SchemasOrReferences::create() - ->set('Pet', $pet) - ->set('Pets', $pets) - ->set('Error', $error) - ) - ); - - echo json_encode($schema, JSON_PRETTY_PRINT); - - ``` - - - This will output: - - - ```json - - { - "info": { - "title": "Swagger Petstore", - "version": "1.0.0", - "license": { - "name": "MIT" - } - }, - "servers": [ - { - "url": "petstore.swagger.io" - } - ], - "paths": { - "\/pets": { - "get": { - "summary": "List all pets", - "operationId": "listPets", - "tags": [ - "pets" - ], - "responses": { - "200": { - "description": "A paged array of pets" - }, - "default": { - "description": "Unexpected error" - } - } - } - } - }, - "components": { - "schemas": { - "Pet": { - "required": [ - "id", - "name" - ], - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "name": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - }, - "Pets": { - "type": "array", - "items": { - "required": [ - "id", - "name" - ], - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "name": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - } - }, - "Error": { - "required": [ - "code", - "message" - ], - "properties": { - "code": { - "type": "integer", - "format": "int32" - }, - "error": { - "type": "string" - } - } - } - } - } - } - - ``` - - - This isn't the full example, but it gives an idea of the structure. - - - ## Contributing - - I'd love feedback and/or contributions, but they will probably need to target the generation library. Head to [Gendarme](https://github.com/calcinai/gendarme) if this sounds like you. Basic command for generating this library is - - - ``` - - ./bin/gendarme generate --namespace "Calcinai\Strut" --root-class Swagger ../strut/lib/schema.json ../strut/src/ - - ``` -pingf/falsy: > - # falsy - - - FAL.S.Y - - - ### description - - it's an api framework. - using falcon, swagger, yaml together! - - - ### license - - MIT and Apache v2 - - - ### showtime - - - ![ScreenShot](https://raw.githubusercontent.com/pingf/falsy/master/demo.gif) - - - - ### how to install it - - - `pip install falsy` - - ### how to use it - - - 0. create the dir for static - - `mkdir static` - - 1. writting the server code(main.py) - - ```python - from falsy.falsy import FALSY - - f = FALSY() #you need create the dir called static before you run - f.swagger('test.yml', ui=True, theme='impress') #impress theme is the responsive swagger ui, or you can use 'normal' here - api = f.api - ``` - - 2. writting the yml file - - ``` - swagger: '2.0' - info: - title: FALSY SIMPLE DEMO API - version: "0.1" - consumes: - - application/json - produces: - - application/json - basePath: "/v1" - paths: - '/hello': - get: - tags: [Method] - operationId: demo.get_it - summary: testing - parameters: - - name: name - in: query - type: string - default: 'john' - responses: - 200: - description: Return response - ``` - - - 3. writting the operation handler(demo.py) - - ```python - def get_it(name): - return { - 'get': name - } - ``` - - - 4. run it - - `gunicorn -b 0.0.0.0:8001 main:api --reload -w 1 --threads 1` - - - 5. visit the ui page - - `http://0.0.0.0:8001/v1/ui/` - make sure it ends with '/' - - - ### video demo - - - ![ScreenShot](https://raw.githubusercontent.com/pingf/falsy/master/falsy.gif) - - ### extensions - - there some improvements compare to standard swagger, - you can define `operationId` for handler, 'beforeId' and 'afterId' for aop hooks, - and 'validationId' for validator, see the files in demo dir for details. -gangverk/flask-swagger: > - # flask-swagger - - A Swagger 2.0 spec extractor for Flask - - - You can now specify base path for yml files: - - ```python - - app = Flask(__name__) - - - @app.route("/spec") - - def spec(): - base_path = os.path.join(app.root_path, 'docs') - return jsonify(swagger(app), from_file_keyword="swagger_from_file", base_path=base_path) - ``` - - and use relative paths: - - ```python - - @app.route('/test', methods=['POST']) - - def login(): - """ - swagger_from_file: test.yml - """ - ``` - - - Install: - - - ```shell - - pip install flask-swagger - - ``` - - Flask-swagger provides a method (swagger) that inspects the Flask app for endpoints that contain YAML docstrings with Swagger 2.0 [Operation](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#operation-object) objects. - - - ```python - - class UserAPI(MethodView): - - def post(self): - """ - Create a new user - --- - tags: - - users - definitions: - - schema: - id: Group - properties: - name: - type: string - description: the group's name - parameters: - - in: body - name: body - schema: - id: User - required: - - email - - name - properties: - email: - type: string - description: email for user - name: - type: string - description: name for user - address: - description: address for user - schema: - id: Address - properties: - street: - type: string - state: - type: string - country: - type: string - postalcode: - type: string - groups: - type: array - description: list of groups - items: - $ref: "#/definitions/Group" - responses: - 201: - description: User created - """ - return {} - ``` - - Flask-swagger supports docstrings in methods of MethodView classes (à la [Flask-RESTful](https://github.com/flask-restful/flask-restful)) and regular Flask view functions. - - - Following YAML conventions, flask-swagger searches for `---`, everything preceding is provided as `summary` (first line) and `description` (following lines) for the endpoint while everything after is parsed as a swagger [Operation](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#operation-object) object. - - - In order to support inline definition of [Schema ](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schemaObject) objects in [Parameter](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#parameterObject) and [Response](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#responsesObject) objects, flask-swagger veers a little off from the standard. We require an `id` field for the inline Schema which is then used to correctly place the [Schema](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schemaObject) object in the [Definitions](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#definitionsObject) object. - - - - [Schema ](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schemaObject) objects can be defined in a definitions section within the docstrings (see group object above) or within responses or parameters (see user object above). We also support schema objects nested within the properties of other [Schema ](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schemaObject) objects. An example is shown above with the address property of User. - - - If you don't like to put YAML on docstrings you can put the same content in an external file. - - - #### file.yml - - ```yaml - - Create a new user - - --- - - tags: - - users - definitions: - - schema: - id: Group - properties: - name: - type: string - description: the group's name - parameters: - - in: body - name: body - schema: - id: User - required: - - email - - name - properties: - email: - type: string - description: email for user - name: - type: string - description: name for user - address: - description: address for user - schema: - id: Address - properties: - street: - type: string - state: - type: string - country: - type: string - postalcode: - type: string - groups: - type: array - description: list of groups - items: - $ref: "#/definitions/Group" - responses: - 201: - description: User created - ``` - - - and point to it in your docstring. - - - ```python - - class UserAPI(MethodView): - - def post(self): - """ - Create a new user - - blah blah - - swagger_from_file: path/to/file.yml - - blah blah - """ - return {} - ``` - - - Note that you can replace `swagger_from_file` by another keyword. Supply your chosen keyword as an argument to swagger. - - - - To expose your Swagger specification to the world you provide a Flask route that does something along these lines - - - ```python - - from flask import Flask, jsonify - - from flask_swagger import swagger - - - app = Flask(__name__) - - - @app.route("/spec") - - def spec(): - return jsonify(swagger(app)) - ``` - - - Note that the Swagger specification returned by `swagger(app)` is as minimal as it can be. It's your job to override and add to the specification as you see fit. - - - ```python - - @app.route("/spec") - - def spec(): - swag = swagger(app) - swag['info']['version'] = "1.0" - swag['info']['title'] = "My API" - return jsonify(swag) - ``` - - - - [Swagger-UI](https://github.com/swagger-api/swagger-ui) - - - Swagger-UI is the reason we embarked on this mission to begin with, flask-swagger does not however include Swagger-UI. Simply follow the awesome documentation over at https://github.com/swagger-api/swagger-ui and point your [swaggerUi.url](https://github.com/swagger-api/swagger-ui#swaggerui) to your new flask-swagger endpoint and enjoy. - - - ## flaskswagger Command - - This package now comes with a very simple command line interface: flaskswagger. This command can be used to build and update swagger specs for your flask apps from the command line or at build time. - - - ```shell - - flaskswagger -h - - ``` - - - ``` - - usage: flaskswagger [-h] [--template TEMPLATE] [--out-dir OUT_DIR] - [--definitions DEFINITIONS] [--host HOST] - [--base-path BASE_PATH] [--version VERSION] - app - - positional arguments: - app the flask app to swaggerify - - optional arguments: - -h, --help show this help message and exit - --template TEMPLATE template spec to start with, before any other options - or processing - --out-dir OUT_DIR the directory to output to - --definitions DEFINITIONS - json definitions file - --host HOST - --base-path BASE_PATH - --version VERSION Specify a spec version - - ``` - - - For example, this can be used to build a swagger spec which can be served from your static directory. In the example below, we use the manually created swagger.json.manual as a template, and output to the `static/` directory. - - - ```shell - - flaskswagger server:app --template static/swagger.json.manual --out-dir static/ - - ``` - - Also, you can ask flaskswagger to add host and basePath to your swagger spec: - - - ```shell - - flaskswagger server:app --host localhost:5000 --base-path /v1 - - ``` - - - Acknowledgements - - - Flask-swagger builds on ideas and code from [flask-sillywalk](https://github.com/hobbeswalsh/flask-sillywalk) and [flask-restful-swagger](https://github.com/rantav/flask-restful-swagger) - - - Notable forks - - - [Flasgger](https://github.com/rochacbruno/flasgger) -Yelp/swagger_spec_validator: > - # swagger_spec_validator - - [![Build Status](https://github.com/Yelp/swagger_spec_validator/workflows/build/badge.svg?branch=master)](https://github.com/Yelp/swagger_spec_validator/actions?query=workflow%3Abuild) - - [![Coverage Status](https://coveralls.io/repos/Yelp/swagger_spec_validator/badge.svg)](https://coveralls.io/r/Yelp/swagger_spec_validator) - - [![Latest Version](https://img.shields.io/pypi/v/swagger_spec_validator.svg)](https://pypi.python.org/pypi/swagger_spec_validator/) - - - ## About - - - Swagger Spec Validator is a Python library that validates Swagger Specs against the [Swagger 1.2](https://github.com/swagger-api/swagger-spec/blob/master/versions/1.2.md) or [Swagger 2.0](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md) specification. The validator aims to check for full compliance with the Specification. - - - ## Example Usage - - - Validate a spec from a url: - - - ```python - - - from swagger_spec_validator import validate_spec_url - - - # example for swagger spec v1.2 - - validate_spec_url('http://petstore.swagger.io/api/api-docs') - - - # example for swagger spec v2.0 - - validate_spec_url('http://petstore.swagger.io/v2/swagger.json') - - ``` - - - ## Documentation - - - More documentation is available at http://swagger_spec_validator.readthedocs.org - - - ## Installation - - $ pip install swagger_spec_validator - - ## Contributing - - - 1. Fork it ( http://github.com/Yelp/swagger_spec_validator/fork ) - - 2. Create your feature branch (`git checkout -b my-new-feature`) - - 3. Commit your changes (`git commit -am 'Add some feature'`) - - 4. Push to the branch (`git push origin my-new-feature`) - - 5. Create new Pull Request - - - ## License - - - Copyright (c) 2015, Yelp, Inc. All rights reserved. - - Apache v2 -tminglei/binder-swagger-java: > - # binder-swagger-java - - - [![Build Status](https://travis-ci.org/tminglei/binder-swagger-java.svg?branch=master)](https://travis-ci.org/tminglei/binder-swagger-java) - - - `binder-swagger-java` is a simple api management solution, which let api maintainence and dev based on api easily. - - - - ## Features - - - lightweight, less than 3000 line codes (framework + built-in route/fake data generating) - - - based on `form-binder-java`, allowing dynamic objects in operation's parameter/response definitions - - - directly integrate with `swagger-models`, allowing to operate swagger object when necessary - - - can generate mock response w/ fake data on demand for unimplemented api operations - - - high customizable, you can replace almost all of the core components - - - - ## How it works - - You define the api meta data in classes' static code blocks, then it was collected to a static global swagger object when class scan/loading, so when requested, the program can serve it right now. - - _With swagger.json, the swagger-ui can render the API menu in the browser. Then you can browse, fill parameters and send to/receive from service impls (p.s. the service urls were included in swagger.json)._ - - - ![binder-swagger description](https://raw.githubusercontent.com/tminglei/binder-swagger-java/master/binder-swagger-java.png) - - - > _p.s. based on [`form-binder-java`](https://github.com/tminglei/form-binder-java) and [`swagger-models`](https://github.com/swagger-api/swagger-core), `binder-swagger-java` enable you to define dynamic data structures and operate the swagger object directly when necessary, so it's more expressive in theory._ - - - - ## How to use it - - #### 0) add the dependency to your project: - - ```xml - - - com.github.tminglei - binder-swagger-java - 0.8.0 - - - ``` - - #### 1) define and register your api operations: - - ```java - - // in `PetResource.java` - - static Mapping petStatus = $(text(oneOf(Arrays.asList("available", "pending", "sold")))) - .desc("pet status in the store").example("available").$$; - static Mapping pet = $(mapping( - field("id", $(vLong()).desc("pet id").example(gen("petId").or(gen(() -> faker.number().randomNumber()))).$$), - field("name", $(text(required())).desc("pet name").$$), - field("category", attach(required()).to($(mapping( - field("id", vLong(required())), - field("name", text(required())) - )).refName("category").desc("category belonged to").$$)), - field("photoUrls", $(list(text())).desc("pet's photo urls").example(Arrays.asList("http://example.com/photo1")).$$), - field("tags", $(list(text())).desc("tags for the pet").example(Arrays.asList("tag1", "tag2")).$$), - field("status", petStatus) - )).refName("pet").desc("pet info").$$; - - - static SharingHolder sharing = sharing().pathPrefix("/pet").tag("pet"); - - - static { - sharing.operation(GET, "/{petId}") - .summary("get pet by id") - .parameter(param(longv()).in("path").name("petId").example(1l)) - .response(200, response(pet)) - .response(404, response().description("pet not found")) - .notImplemented() // MARK IT `notImplemented`, THEN `binder-swagger-java` WILL GENERATE MOCK RESPONSE FOR YOU - ; - } - - @GET - - @Path("/{petId}") - - public Response getPetById(@PathParam("petId") String petId) throws NotFoundException, SQLException { - - ... - - ``` - - #### 2) supplement your other swagger info: - - ```java - - // in `Bootstrap.java` - - static { // for swagger - swagger().info(info() - .title("Swagger Sample App") - .description("This is a sample server Petstore server. You can find out more about Swagger " + - "at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, " + - "you can use the api key `special-key` to test the authorization filters.") - .termsOfService("http://swagger.io/terms/") - .contact(contact().email("apiteam@swagger.io")) - .license(license().name("Apache 2.0") - .url("http://www.apache.org/licenses/LICENSE-2.0.html") - ) - ).host("localhost:8002") - .basePath("/api") - .consumes("application/json") - .produces("application/json") - .securityDefinition("api_key", apiKeyAuth("api_key", In.HEADER)) - .securityDefinition("petstore_auth", oAuth2() - .implicit("http://petstore.swagger.io/api/oauth/dialog") - .scope("read:pets", "read your pets") - .scope("write:pets", "modify pets in your account") - ).tag(tag("pet").description("Everything about your Pets") - .externalDocs(externalDocs().description("Find out more").url("http://swagger.io")) - ).tag(tag("store").description("Access to Petstore orders") - ).tag(tag("user").description("Operations about user") - .externalDocs(externalDocs().description("Find out more about our store").url("http://swagger.io")) - ); - } - - ``` - - #### 3) configure the filter, which will serv the `swagger.json`: - - ```xml - - // in `web.xml` - - - SwaggerFilter - com.github.tminglei.swagger.SwaggerFilter - - - - - scan-packages-and-classes - com.example.resource; com.example.Bootstrap - - - - - - - - - - - - - - - SwaggerFilter - /api/* - - - ... - - ``` - - - - ##### That's all. Enjoy it! - - - - > For more usage details, pls check the example project [here](https://github.com/tminglei/binder-swagger-java/tree/master/example/java-jaxrs). - - - - ## Q & A - - **Q:** Why use static code blocks to associate/register operation meta info instead of annotations? - - **A:** Well, because we can't use annotations here. Annotation requires static defined data types, but we didn't define java beans in our project. - - _(p.s. because of this, we can't also use existing frameworks, like `springfox`.)_ - - - - ## License - - The BSD License, Minglei Tu <tmlneu@gmail.com> -thebignet/swagger-codegen-gradle-plugin: > - swagger-codegen-gradle-plugin - - ============================ - - - [![Build Status](https://travis-ci.org/thebignet/swagger-codegen-gradle-plugin.svg?branch=master)](https://travis-ci.org/thebignet/swagger-codegen-gradle-plugin) - - - A Gradle plugin to support the [swagger](http://swagger.io) code generation project - - - - [DEPRECATED] !!! - - ------------ - - - see the [swagger-codegen-gradle-plugin-example](https://github.com/thebignet/swagger-codegen-gradle-plugin-example) for creating a Gradle task to generate code with Swagger Codegen. - - - - Usage - - ============================ - - - see the [swagger-codegen-gradle-plugin-example](https://github.com/thebignet/swagger-codegen-gradle-plugin-example), or: - - - Here is an example of how to use the plugin in a `build.gradle` file - - ```groovy - - plugins { - id 'org.detoeuf.swagger-codegen' version '1.7.4' - id 'java' - } - - - apply plugin: 'org.detoeuf.swagger-codegen' - - - repositories { - mavenCentral() - jcenter() - } - - - swagger { - inputSpec = 'http://petstore.swagger.io/v2/swagger.json' - outputDir = file('build/swagger') - lang = 'java' - - additionalProperties = [ - 'invokerPackage' : 'io.swagger.petstore.client', - 'modelPackage' : 'io.swagger.petstore.client.model', - 'apiPackage' : 'io.swagger.petstore.client.api', - 'dateLibrary' : 'java8' - ] - importMappings = [ - 'Dog': 'io.swagger.petstore.client.model.Dog' - ] - } - - - sourceSets { - swagger { - java { - srcDir file("${project.buildDir.path}/swagger/src/main/java") - } - } - } - - - classes.dependsOn('swagger') - - - ext { - spring_boot_version = '1.5.6.RELEASE' - jackson_version = '2.4.2' - jersey_version = '1.18' - jodatime_version = '2.3' - junit_version = '4.8.1' - } - - - dependencies { - swaggerCompile "org.springframework.boot:spring-boot-starter-web:$spring_boot_version" - swaggerCompile 'io.swagger:swagger-annotations:1.5.16' - swaggerCompile 'com.squareup.okhttp:okhttp:2.7.5' - swaggerCompile 'com.squareup.okhttp:logging-interceptor:2.7.5' - swaggerCompile 'com.google.code.gson:gson:2.8.1' - - compile sourceSets.swagger.output - - compile "com.sun.jersey:jersey-client:$jersey_version" - compile "com.sun.jersey.contribs:jersey-multipart:$jersey_version" - compile "com.fasterxml.jackson.core:jackson-core:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version" - compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version" - compile "com.fasterxml.jackson.datatype:jackson-datatype-joda:2.1.5" - compile "joda-time:joda-time:$jodatime_version" - compile 'io.swagger:swagger-codegen:2.2.3' - - testCompile "junit:junit:$junit_version" - - runtime 'com.squareup.okhttp:okhttp:2.7.5' - runtime 'com.squareup.okhttp:logging-interceptor:2.7.5' - runtime 'com.google.code.gson:gson:2.8.1' - } - - ``` - - - Launch with: - - - ``` - - gradle swagger - - ``` - - - ### Configuration parameters - - the `swagger {}` configuration is passed to [CodegenConfigurator.java](https://github.com/swagger-api/swagger-codegen/blob/v2.2.1/modules/swagger-codegen/src/main/java/io/swagger/codegen/config/CodegenConfigurator.java) - - - #### Dynamic properties - - Some Swagger codegen configurations will contain extra properties that are not part of the io.swagger.codegen.CodegenConfig interface. For example there is the `sourceFolder` property that is only applicable if using jaxrs-spec as the value of the `lang` property. In order to set such properties, we should use the `dynamicProperty` method inside the `swagger {}` configuration as shown below. - - - ``` - - swagger { - lang = 'jaxrs-spec' - - addDynamicProperty 'sourceFolder', 'src/swagger/java' - - additionalProperties = [ - ... - ] - systemProperties = [ - ... - ] - } - - ``` - - - … to be documented … - - - ### deprecation warning - - the old behaviour had a custom plugin for this swagger config as seen below - - - `inputSpec` - :check: - - - `outputDir` - was: `output` - - - `lang` - was: `language` - - - `additionalProperties` - sets additional properties that can be referenced by the mustache templates in the format of name=value,name=value. See [Customizing the generator](https://github.com/swagger-api/swagger-codegen/#customizing-the-generator) for list of parameters - - - #### new settings possible - - - `systemProperties` - see [selective generation](https://github.com/swagger-api/swagger-codegen/#selective-generation) - - - #### no longer included - - - `models` - have a look at the systemProperties section - - - `apis` - [selective generation](https://github.com/swagger-api/swagger-codegen/#selective-generation) of apis. Leave blank to generate apis only - - - `supportingFiles` - [selective generation](https://github.com/swagger-api/swagger-codegen/#selective-generation) of supporting files. Leave blank to generate supporting files only - - - no substituion for: - - - `cleanOutputDir` - now, configured by configuring the task directly: - ```groovy - tasks.getByName("swagger") { - cleanOutputDir = false - } - ``` -striglia/pyramid_swagger: > - :PyPI: https://pypi.python.org/pypi/pyramid_swagger - - :Documentation: http://pyramid-swagger.readthedocs.org/en/latest/ - - :Source: https://github.com/striglia/pyramid_swagger - - :License: Copyright © 2014 Scott Triglia under the `BSD 3-clause `_ - - :Build status: - .. image:: https://travis-ci.org/striglia/pyramid_swagger.png?branch=master - :target: https://travis-ci.org/striglia/pyramid_swagger?branch=master - :alt: Travis CI - .. image:: https://ci.appveyor.com/api/projects/status/ufmlmpwy1vj3yjgk/branch/master?svg=true - :target: https://ci.appveyor.com/project/striglia/pyramid-swagger - :alt: Appveyor (Windows CI) - :Current coverage on master: - .. image:: https://coveralls.io/repos/striglia/pyramid_swagger/badge.png - :target: https://coveralls.io/r/striglia/pyramid_swagger - :Persistent chat for questions: - .. image:: https://badges.gitter.im/Join%20Chat.svg - :alt: Join the chat at https://gitter.im/striglia/pyramid_swagger - :target: https://gitter.im/striglia/pyramid_swagger?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - - - pyramid_swagger - - =============== - - - This project offers convenient tools for using Swagger to define and validate - - your interfaces in a Pyramid webapp. - - - Full documentation is available at http://pyramid-swagger.readthedocs.org/. - - - - How to contribute - - ----------------- - - - #. Fork this repository on Github: https://help.github.com/articles/fork-a-repo/ - - #. Clone your forked repository: https://help.github.com/articles/cloning-a-repository/ - - #. Make a feature branch for your changes: - - :: - - git remote add upstream https://github.com/striglia/pyramid_swagger.git - git fetch upstream - git checkout upstream/master -b my-feature-branch - - #. Create and activate the virtual environment, this will provide you with all the - libraries and tools necessary for pyramid_swagger development: - - :: - - make - source .activate.sh - - #. Make sure the test suite works before you start: - - :: - - tox -e py27 # Note: use py35 for Python 3.5, see tox.ini for possible values - - #. Commit patches: http://gitref.org/basic/ - - #. Push to github: ``git pull && git push origin`` - - #. Send a pull request: https://help.github.com/articles/creating-a-pull-request/ - - - - Running a single test - - ********************* - - - Make sure you have activated the virtual environment (see above). - - - :: - - py.test -vvv tests/tween_test.py::test_response_properties -kaizhu256/node-swagger-mongodb: > - swagger-mongodb - - =============== - - lightweight swagger-ui crud-middleware backed by mongodb - - - [![NPM](https://img.shields.io/npm/v/swagger-mongodb.svg?style=flat-square)](https://www.npmjs.org/package/swagger-mongodb) - - - - - # live test-server - - [![heroku.com test-server](https://kaizhu256.github.io/node-swagger-mongodb/build/screen-capture.herokuDeploy.slimerjs..png)](https://hrku01-swagger-mongodb-beta.herokuapp.com) - - - - - # build-status [![travis-ci.org build-status](https://api.travis-ci.org/kaizhu256/node-swagger-mongodb.svg)](https://travis-ci.org/kaizhu256/node-swagger-mongodb) - - [![build commit status](https://kaizhu256.github.io/node-swagger-mongodb/build/build.badge.svg)](https://travis-ci.org/kaizhu256/node-swagger-mongodb) - - - | git-branch : | [master](https://github.com/kaizhu256/node-swagger-mongodb/tree/master) | [beta](https://github.com/kaizhu256/node-swagger-mongodb/tree/beta) | [alpha](https://github.com/kaizhu256/node-swagger-mongodb/tree/alpha)| - - |--:|:--|:--|:--| - - | test-server : | [![heroku.com test-server](https://kaizhu256.github.io/node-swagger-mongodb/heroku-logo.75x25.png)](https://hrku01-swagger-mongodb-master.herokuapp.com) | [![heroku.com test-server](https://kaizhu256.github.io/node-swagger-mongodb/heroku-logo.75x25.png)](https://hrku01-swagger-mongodb-beta.herokuapp.com) | [![heroku.com test-server](https://kaizhu256.github.io/node-swagger-mongodb/heroku-logo.75x25.png)](https://hrku01-swagger-mongodb-alpha.herokuapp.com)| - - | test-report : | [![test-report](https://kaizhu256.github.io/node-swagger-mongodb/build..master..travis-ci.org/test-report.badge.svg)](https://kaizhu256.github.io/node-swagger-mongodb/build..master..travis-ci.org/test-report.html) | [![test-report](https://kaizhu256.github.io/node-swagger-mongodb/build..beta..travis-ci.org/test-report.badge.svg)](https://kaizhu256.github.io/node-swagger-mongodb/build..beta..travis-ci.org/test-report.html) | [![test-report](https://kaizhu256.github.io/node-swagger-mongodb/build..alpha..travis-ci.org/test-report.badge.svg)](https://kaizhu256.github.io/node-swagger-mongodb/build..alpha..travis-ci.org/test-report.html)| - - | coverage : | [![istanbul-lite coverage](https://kaizhu256.github.io/node-swagger-mongodb/build..master..travis-ci.org/coverage.badge.svg)](https://kaizhu256.github.io/node-swagger-mongodb/build..master..travis-ci.org/coverage.html/index.html) | [![istanbul-lite coverage](https://kaizhu256.github.io/node-swagger-mongodb/build..beta..travis-ci.org/coverage.badge.svg)](https://kaizhu256.github.io/node-swagger-mongodb/build..beta..travis-ci.org/coverage.html/index.html) | [![istanbul-lite coverage](https://kaizhu256.github.io/node-swagger-mongodb/build..alpha..travis-ci.org/coverage.badge.svg)](https://kaizhu256.github.io/node-swagger-mongodb/build..alpha..travis-ci.org/coverage.html/index.html)| - - | build-artifacts : | [![build-artifacts](https://kaizhu256.github.io/node-swagger-mongodb/glyphicons_144_folder_open.png)](https://github.com/kaizhu256/node-swagger-mongodb/tree/gh-pages/build..master..travis-ci.org) | [![build-artifacts](https://kaizhu256.github.io/node-swagger-mongodb/glyphicons_144_folder_open.png)](https://github.com/kaizhu256/node-swagger-mongodb/tree/gh-pages/build..beta..travis-ci.org) | [![build-artifacts](https://kaizhu256.github.io/node-swagger-mongodb/glyphicons_144_folder_open.png)](https://github.com/kaizhu256/node-swagger-mongodb/tree/gh-pages/build..alpha..travis-ci.org)| - - - #### master branch - - - stable branch - - - HEAD should be tagged, npm-published package - - - #### beta branch - - - semi-stable branch - - - HEAD should be latest, npm-published package - - - #### alpha branch - - - unstable branch - - - HEAD is arbitrary - - - commit history may be rewritten - - - - - # documentation - - #### this package requires - - - darwin or linux os - - - mongodb 2.6 or higher - - - #### [api-doc](https://kaizhu256.github.io/node-swagger-mongodb/build/doc.api.html) - - [![api-doc](https://kaizhu256.github.io/node-swagger-mongodb/build/screen-capture.docApiCreate.slimerjs._2Fhome_2Ftravis_2Fbuild_2Fkaizhu256_2Fnode-swagger-mongodb_2Ftmp_2Fbuild_2Fdoc.api.html.png)](https://kaizhu256.github.io/node-swagger-mongodb/build/doc.api.html) - - - - - # quickstart web example - - #### to run this example, follow the instruction in the script below - - - example.js - - - ```javascript - - /* - - example.js - - - this node script will serve a lightweight swagger-ui crud-api backed by mongodb - - - instruction - 1. save this script as example.js - 2. run the shell command: - $ npm install swagger-mongodb && npm_config_server_port=1337 node example.js - 3. open a browser to http://localhost:1337 - 4. interact with the swagger-ui crud-api - */ - - - /*jslint - browser: true, - maxerr: 8, - maxlen: 96, - node: true, - nomen: true, - regexp: true, - stupid: true - */ - - - (function (local) { - 'use strict'; - switch (local.modeJs) { - - - - // run node js-env code - case 'node': - // export local - module.exports = local; - // init assets - local.utility2.cacheDict.assets['/'] = '\n' + - /* jslint-ignore-begin */ - - '\n' + - - '\n' + - - ' \n' + - - ' \n' + - - ' {{envDict.npm_package_name}} [{{envDict.npm_package_version}}]\n' + - - ' \n' + - - ' \n' + - - ' \n' + - - ' {{envDict.npm_config_html_head_extra}}\n' + - - '\n' + - - '\n' + - - ' \n' + - - '

{{envDict.npm_package_name}} [{{envDict.npm_package_version}}]

\n' + - - '

{{envDict.npm_package_description}}

\n' + - - '
\n' + - - ' \n' + - - ' \n' + - - ' \n' + - - ' \n' + - - ' \n' + - - ' \n' + - - ' \n' + - - ' \n' + - - ' {{envDict.npm_config_html_body_extra}}\n' + - - '\n' + - - /* jslint-ignore-end */ - '\n'; - local.utility2.cacheDict.assets['/'] = local.utility2.stringFormat( - local.utility2.cacheDict.assets['/'], - { envDict: local.utility2.envDict }, - '' - ); - local.utility2.cacheDict.assets['/assets/example.js'] = - local.utility2.istanbul_lite.instrumentSync( - local.fs.readFileSync(__dirname + '/example.js', 'utf8'), - __dirname + '/example.js' - ); - local.utility2.cacheDict.assets['/test/test.js'] = - local.utility2.istanbul_lite.instrumentInPackage( - local.fs.readFileSync(local.swmg.__dirname + '/test.js', 'utf8'), - local.swmg.__dirname + '/test.js', - 'swagger-mongodb' - ); - // init mongodb-client - local.utility2.onReady.counter += 1; - local.utility2.taskRunOrSubscribe({ - key: 'swagger-mongodb.mongodbConnect', - onTask: function (onError) { - local.mongodb.MongoClient.connect( - local.utility2.envDict.npm_config_mongodb_url || - 'mongodb://localhost:27017/test', - function (error, db) { - // validate no error occurred - local.utility2.assert(!error, error); - local.swmg.db = db; - onError(); - local.utility2.onReady(); - } - ); - } - }); - // init middleware - local.middleware = local.utility2.middlewareGroupCreate([ - // init pre-middleware - local.utility2.middlewareInit, - // init cached-assets middleware - local.utility2.middlewareAssetsCached, - // init http-body-get middleware - local.utility2.middlewareBodyGet, - // init http-body-parse-upload middleware - function (request, response, nextMiddleware) { - var boundary, bodyText; - // jslint-hack - local.utility2.nop(response); - local.utility2.testTryCatch(function () { - if ((request.headers['content-type'] || '') - .indexOf('multipart/form-data') !== 0) { - nextMiddleware(); - return; - } - boundary = - '--' + (/boundary=(.*)/).exec(request.headers['content-type'])[1]; - request.swmgBodyParsed = {}; - bodyText = String(request.bodyRaw); - bodyText.split(boundary).slice(1, -1).forEach(function (part) { - request.swmgBodyParsed[ - (/\bname="([^"]*)/).exec(part)[1] - ] = part.split('\r\n\r\n').slice(1).join('\r\n\r\n').slice(0, -2); - }); - // set file - bodyText.replace('\r\n\r\n', function (match0, ii) { - // jslint-hack - local.utility2.nop(match0); - request.swmgBodyParsed.file = request.bodyRaw - .slice(ii + 4, -(boundary.length + 6)) - .toString('base64'); - }); - request.swmgBodyParsed.file = request.bodyRaw - .slice(bodyText.lastIndexOf('\r\n\r\n') + 4, -(boundary.length + 6)) - .toString('base64'); - // set filename - request.swmgBodyParsed.filename = (/\bfilename="([^"]+)/).exec(bodyText); - request.swmgBodyParsed.filename = - request.swmgBodyParsed.filename && - request.swmgBodyParsed.filename[1]; - nextMiddleware(); - }, nextMiddleware); - }, - // init http-body-parse middleware - local.swmg.middlewareBodyParse, - // init swagger pre-middleware - function (request, response, nextMiddleware) { - // jslint-hack - local.utility2.nop(request); - // enable cors - // http://en.wikipedia.org/wiki/Cross-origin_resource_sharing - response.setHeader( - 'Access-Control-Allow-Methods', - 'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT' - ); - response.setHeader('Access-Control-Allow-Origin', '*'); - // init content-type - response.setHeader('Content-Type', 'application/json; charset=UTF-8'); - nextMiddleware(); - }, - // init swagger middleware - local.swmg.middlewareSwagger - ]); - // init error-middleware - local.middlewareError = local.swmg.middlewareError; - // init petstore-api - (function () { - var methodPath, options, schema; - options = local.utility2.jsonCopy(require(local.swmg.local - .swagger_ui_lite.__dirname + '/swagger.json')); - options = { - definitions: options.definitions, - paths: options.paths, - tags: options.tags - }; - // remove unused properties - delete options.definitions.ApiResponse; - // init schema - Object.keys(options.definitions).forEach(function (schemaName) { - schema = options.definitions[schemaName]; - // init id - schema.properties.id = { type: 'string' }; - schema['x-inheritList'] = [{ $ref: '#/definitions/JsonapiResource' }]; - }); - local.utility2.objectSetOverride(options, { - definitions: { - // init Pet schema - Pet: { - // drop collection on init - _collectionDrop: true, - // upsert fixtures - _collectionFixtureList: [{ - id: 'pet0', - name: 'birdie', - photoUrls: [], - status: 'available', - tags: [{ name: 'bird'}] - }, { - id: 'pet1', - name: 'kittie', - status: 'pending', - photoUrls: [], - tags: [{ name: 'cat'}] - }, { - id: 'pet2', - name: 'doggie', - photoUrls: [], - status: 'sold', - tags: [{ name: 'dog'}] - }], - _collectionName: 'SwmgPet' - }, - // init Order schema - Order: { - // create index - _collectionCreateIndexList: [{ - key: { status: 1 }, - name: 'status_1' - }], - // drop collection on init - _collectionDrop: true, - // upsert fixtures - _collectionFixtureList: [{ - id: 'order0', - status: 'available' - }, { - id: 'order1', - status: 'pending' - }, { - id: 'order2', - status: 'sold' - }], - _collectionName: 'SwmgOrder', - properties: { - petId: { type: 'string' } - } - }, - // init User schema - User: { - // create index - _collectionCreateIndexList: [{ - key: { username: 1 }, - name: 'username_1', - unique: true - }], - // drop collection on init - _collectionDrop: true, - // upsert fixtures - _collectionFixtureList: [{ - email: 'john@doe.com', - firstName: 'john', - id: 'user0', - lastName: 'doe', - password: 'hello', - phone: '1234-5678', - username: 'john.doe' - }, { - email: 'jane@doe.com', - firstName: 'jane', - id: 'user1', - lastName: 'doe', - password: 'bye', - phone: '8765-4321', - username: 'jane.doe' - }], - _collectionName: 'SwmgUser' - } - }, - // init crud-api - paths: { - '/pet/crudGetByQueryMany': { get: { - _collectionName: 'SwmgPet', - _crudApi: 'pet', - _schemaName: 'Pet', - operationId: 'crudGetByQueryMany', - tags: ['pet'] - } }, - '/store/crudGetByQueryMany': { get: { - _collectionName: 'SwmgOrder', - _crudApi: 'store', - _schemaName: 'Order', - operationId: 'crudGetByQueryMany', - tags: ['store'] - } }, - '/user/crudGetByQueryMany': { get: { - _collectionName: 'SwmgUser', - _crudApi: 'user', - _schemaName: 'User', - operationId: 'crudGetByQueryMany', - tags: ['user'] - } } - } - }, 4); - // transform petstore-api to swagger-mongodb's crud-api - Object.keys(options.paths).forEach(function (path) { - Object.keys(options.paths[path]).forEach(function (method) { - methodPath = options.paths[path][method]; - // init methodPath._schemaName - switch (path.split('/')[1]) { - case 'pet': - methodPath._schemaName = 'Pet'; - break; - case 'store': - methodPath._schemaName = 'Order'; - break; - case 'user': - methodPath._schemaName = 'User'; - break; - } - methodPath._collectionName = 'Swmg' + methodPath._schemaName; - delete methodPath.produces; - delete methodPath.responses; - delete methodPath.security; - // init jsonapi response - local.utility2.objectSetDefault(methodPath, { responses: { - 200: { - description: '200 ok - http://jsonapi.org/format' + - '/#document-structure-top-level', - schema: { $ref: '#/definitions/JsonapiResponse{{_schemaName}}' } - } - } }, 2); - // init crudCreateMany / crudCreateOne / crudDeleteByIdOne / crudGetByIdOne - switch (methodPath.operationId) { - case 'addPet': - case 'createUser': - case 'placeOrder': - methodPath.operationId = 'crudCreateOne'; - break; - case 'createUsersWithArrayInput': - case 'createUsersWithListInput': - methodPath.operationId = 'crudCreateMany'; - break; - case 'deleteOrder': - case 'deletePet': - case 'deleteUser': - methodPath.operationId = 'crudDeleteByIdOne'; - break; - case 'getOrderById': - case 'getPetById': - case 'getUserByName': - methodPath.operationId = 'crudGetByIdOne'; - break; - } - // init id - (methodPath.parameters || []).forEach(function (paramDef) { - switch (paramDef.name) { - case 'orderId': - case 'petId': - delete paramDef.format; - paramDef.type = 'string'; - break; - } - }); - }); - }); - local.swmg.apiUpdate(options); - }()); - // init petstore-middleware - local.middleware.middlewareList.push(function (request, response, nextMiddleware) { - var modeNext, onNext, options; - modeNext = 0; - onNext = function (error, data) { - local.utility2.testTryCatch(function () { - modeNext = error - ? Infinity - : modeNext + 1; - switch (modeNext) { - case 1: - // init id - ((request.swmgMethodPath && request.swmgMethodPath.parameters) || [ - ]).forEach(function (paramDef) { - switch (paramDef.name) { - case 'orderId': - case 'petId': - request.swmgParamDict.id = request.swmgParamDict[paramDef.name]; - break; - } - }); - // init options - if (request.swmgMethodPath) { - options = { - collectionName: request.swmgMethodPath._collectionName, - data: request.swmgParamDict, - operationId: request.swmgMethodPath.operationId, - paramDefList: request.swmgMethodPath.parameters, - schemaName: request.swmgMethodPath._schemaName - }; - } - switch (request.swmgPathname) { - // handle pet request - case 'DELETE /pet/': - case 'GET /pet/': - case 'POST /pet': - local.swmg._crudApi(options, onNext); - break; - case 'GET /pet/findByStatus': - options.operationId = 'crudGetByQueryMany'; - options.data.fields = '{}'; - options.data.hint = '{}'; - options.data.limit = 100; - options.data.query = '{"status":{"$in":' + - JSON.stringify(options.data.status) + '}}'; - options.data.skip = 0; - options.data.sort = '{"_timeModified":-1}'; - local.swmg._crudApi(options, onNext); - break; - case 'GET /pet/findByTags': - options.operationId = 'crudGetByQueryMany'; - options.data.fields = '{}'; - options.data.hint = '{}'; - options.data.limit = 100; - options.data.query = '{"status":{"$in":' + - JSON.stringify(options.data.tags) + '}}'; - options.data.skip = 0; - options.data.sort = '{"_timeModified":-1}'; - options.paramDefList[0].default = 'bird,cat,dog'; - local.swmg._crudApi(options, onNext); - break; - case 'POST /pet/': - options.data.upsert = true; - options.data.body = { - id: options.data.id, - name: options.data.name, - status: options.data.status - }; - options.operationId = 'crudUpdateOne'; - local.swmg._crudApi(options, onNext); - break; - case 'POST /pet//': - options.data.body = { - additionalMetadata: options.data.additionalMetadata, - file: options.data.file, - filename: - request.swmgBodyParsed && request.swmgBodyParsed.filename, - id: options.id - }; - options.data.upsert = true; - options.operationId = 'crudUpdateOne'; - local.swmg._crudApi(options, onNext); - break; - case 'PUT /pet': - options.data.upsert = true; - options.operationId = 'crudReplaceOne'; - local.swmg._crudApi(options, onNext); - break; - // handle store request - case 'DELETE /store/order/': - case 'GET /store/order/': - case 'POST /store/order': - local.swmg._crudApi(options, onNext); - break; - case 'GET /store/inventory': - options.data = { body: [{ - $group: { _id: '$status', total: { $sum: 1} } - }, { - $project: { _id: 0, status: '$_id', total: '$total' } - }]}; - options.operationId = 'crudAggregateMany'; - local.swmg._crudApi(options, onNext); - break; - // handle user request - case 'DELETE /user/': - case 'GET /user/': - case 'POST /user/createWithArray': - case 'POST /user/createWithList': - options.optionsId = { username: request.swmgParamDict.username}; - local.swmg._crudApi(options, onNext); - break; - case 'POST /user': - options.data.username = options.data.body.username; - options.optionsId = { username: request.swmgParamDict.username}; - local.swmg._crudApi(options, onNext); - break; - case 'PUT /user/': - options.data.body.username = options.data.username; - options.data.upsert = true; - options.operationId = 'crudReplaceOne'; - options.optionsId = { username: request.swmgParamDict.username}; - local.swmg._crudApi(options, onNext); - break; - default: - nextMiddleware(); - } - break; - default: - // validate no error occurred - local.utility2.assert(!error, error); - // respond with json-object - response.end(JSON.stringify(data)); - } - }, nextMiddleware); - }; - onNext(); - }); - // run server-test - local.utility2.testRunServer(local); - break; - } - }((function () { - 'use strict'; - var local; - - - - // run shared js-env code - (function () { - // init local - local = {}; - // init js-env - local.modeJs = (function () { - try { - return module.exports && - typeof process.versions.node === 'string' && - typeof require('http').createServer === 'function' && - 'node'; - } catch (errorCaughtNode) { - return typeof navigator.userAgent === 'string' && - typeof document.querySelector('body') === 'object' && - 'browser'; - } - }()); - // init global - local.global = local.modeJs === 'browser' - ? window - : global; - // export local - local.global.local = local; - // init swagger-mongodb - local.swmg = local.modeJs === 'browser' - ? window.swmg - : require('swagger-mongodb'); - // import swmg.local - Object.keys(local.swmg.local).forEach(function (key) { - local[key] = local[key] || local.swmg.local[key]; - }); - // init utility2 - local.utility2 = local.swmg.local.utility2; - // init onReady - local.utility2.onReadyInit(); - }()); - return local; - }()))); - - ``` - - - #### output from shell - - [![screen-capture](https://kaizhu256.github.io/node-swagger-mongodb/build/screen-capture.testExampleJs.svg)](https://travis-ci.org/kaizhu256/node-swagger-mongodb) - - - #### output from phantomjs-lite - - [![screen-capture](https://kaizhu256.github.io/node-swagger-mongodb/build/screen-capture.testExampleJs.slimerjs..png)](https://hrku01-swagger-mongodb-beta.herokuapp.com) - - - - - # npm-dependencies - - - [mongodb-minimal](https://www.npmjs.com/package/mongodb-minimal) - - - [swagger-ui-lite](https://www.npmjs.com/package/swagger-ui-lite) - - - [utility2](https://www.npmjs.com/package/utility2) - - - - - # package-listing - - [![screen-capture](https://kaizhu256.github.io/node-swagger-mongodb/build/screen-capture.gitLsTree.svg)](https://github.com/kaizhu256/node-swagger-mongodb) - - - - - # package.json - - ```json - - { - "author": "kai zhu ", - "bin": { "swagger-mongodb": "index.js" }, - "dependencies": { - "mongodb-minimal": "2015.8.1", - "swagger-ui-lite": "2015.6.2", - "utility2": "~2015.8.5" - }, - "description": "lightweight swagger-ui crud-middleware backed by mongodb", - "devDependencies": { - "phantomjs-lite": "2015.7.1" - }, - "engines": { "node": ">=0.10 <=0.12" }, - "keywords": [ - "api", - "browser", - "cms", "crud", - "mongo", "mongodb", - "swagger", "swagger-ui", - "web" - ], - "license": "MIT", - "name": "swagger-mongodb", - "os": ["darwin", "linux"], - "repository" : { - "type" : "git", - "url" : "https://github.com/kaizhu256/node-swagger-mongodb.git" - }, - "scripts": { - "build-ci": "node_modules/.bin/utility2 shRun shReadmeBuild", - "build-doc": "node_modules/.bin/utility2 shRun shReadmeExportPackageJson && \ - node_modules/.bin/utility2 shRun shDocApiCreate \"{ \ - - exampleFileList:['example.js','test.js','index.js'], \ - - moduleDict:{'swagger-mongodb':{aliasList:['swmg'],exports:require('./index.js')}} \ - - }\"", - "start": "npm_config_mode_auto_restart=1 node_modules/.bin/utility2 shRun node test.js", - "test": "node_modules/.bin/utility2 shRun shReadmeExportPackageJson && \ - node_modules/.bin/utility2 test test.js" - }, - "version": "2015.8.3" - } - - ``` - - - - - # todo - - - add logging feature - - - rename delete to remove for naming consistency - - - migrate to travis-ci docker container build - - - add cached param for crudGetByQueryMany - - - add SwmgUserLoginTokenCapped - - - re-enable user login/logout - - - test /user/login and /user/logout - - - add max / min validation - - - none - - - - - # change since af87c5b9 - - - npm publish 2015.8.3 - - - lockdown npm dependencies - - - none - - - - - # changelog of last 50 commits - - [![screen-capture](https://kaizhu256.github.io/node-swagger-mongodb/build/screen-capture.gitLog.svg)](https://github.com/kaizhu256/node-swagger-mongodb/commits) - - - - - # internal build-script - - - build.sh - - - ```shell - - # build.sh - - - # this shell script will run the build for this package - - - shBuild() { - # this function will run the main build - local TEST_URL || return $? - - # init env - export npm_config_mode_slimerjs=1 || return $? - . node_modules/.bin/utility2 && shInit || return $? - - # run npm-test on published package - shRun shNpmTestPublished || return $? - - # test example js script - export npm_config_timeout_exit=10000 || return $? - MODE_BUILD=testExampleJs shRunScreenCapture shReadmeTestJs example.js || return $? - unset npm_config_timeout_exit || return $? - - # run npm-test - MODE_BUILD=npmTest shRunScreenCapture npm test || return $? - - # create api-doc - npm run-script build-doc || return $? - - # if running legacy-node, then do not continue - [ "$(node --version)" \< "v0.12" ] && return - - # deploy app to heroku - shRun shHerokuDeploy hrku01-$npm_package_name-$CI_BRANCH || return $? - - # test deployed app to heroku - if [ "$CI_BRANCH" = alpha ] || - [ "$CI_BRANCH" = beta ] || - [ "$CI_BRANCH" = master ] - then - TEST_URL="https://hrku01-$npm_package_name-$CI_BRANCH.herokuapp.com" || return $? - TEST_URL="$TEST_URL?modeTest=phantom&timeExit={{timeExit}}" || return $? - MODE_BUILD=herokuTest shPhantomTest "$TEST_URL" || return $? - fi - } - - shBuild - - - # save exit-code - - EXIT_CODE=$? - - # create package-listing - - MODE_BUILD=gitLsTree shRunScreenCapture shGitLsTree || exit $? - - # create recent changelog of last 50 commits - - MODE_BUILD=gitLog shRunScreenCapture git log -50 --pretty="%ai\u000a%B" || exit $? - - # if running legacy-node, then do not continue - - [ "$(node --version)" \< "v0.12" ] && exit $EXIT_CODE - - # upload build-artifacts to github, and if number of commits > 16, then squash older commits - - COMMIT_LIMIT=16 shBuildGithubUpload || exit $? - - exit $EXIT_CODE - - ``` -krakenjs/swaggerize-express: > - # swaggerize-express - - - [![Build Status](https://travis-ci.org/krakenjs/swaggerize-express.svg?branch=master)](https://travis-ci.org/krakenjs/swaggerize-express) - - [![NPM version](https://badge.fury.io/js/swaggerize-express.png)](http://badge.fury.io/js/swaggerize-express) - - - `swaggerize-express` is a design-driven approach to building RESTful apis with [Swagger](http://swagger.io) and [Express](http://expressjs.com). - - - `swaggerize-express` provides the following features: - - - - API schema validation. - - - Routes based on the Swagger document. - - - API documentation route. - - - Input validation. - - - See also: - - - [swaggerize-routes](https://github.com/krakenjs/swaggerize-routes) - - - [swaggerize-hapi](https://github.com/krakenjs/swaggerize-hapi) - - - [generator-swaggerize](https://www.npmjs.org/package/generator-swaggerize) - - - ### Why "Design Driven" - - - There are already a number of modules that help build RESTful APIs for node with swagger. However, - - these modules tend to focus on building the documentation or specification as a side effect of writing - - the application business logic. - - - `swaggerize-express` begins with the swagger document first. This facilitates writing APIs that are easier to design, review, and test. - - - ### Quick Start with a Generator - - - This guide will let you go from an `api.json` to a service project in no time flat. - - - First install `generator-swaggerize` (and `yo` if you haven't already): - - - ```bash - - $ npm install -g yo - - $ npm install -g generator-swaggerize - - ``` - - - Now run the generator. - - - ```bash - - $ mkdir petstore && cd $_ - - $ yo swaggerize - - ``` - - - Follow the prompts (note: make sure to choose `express` as your framework choice). - - - When asked for a swagger document, you can try this one: - - - ``` - - https://raw.githubusercontent.com/wordnik/swagger-spec/master/examples/v2.0/json/petstore.json - - ``` - - - You now have a working api and can use something like [Swagger UI](https://github.com/wordnik/swagger-ui) to explore it. - - - ### Manual Usage - - - ```javascript - - var swaggerize = require('swaggerize-express'); - - - app.use(swaggerize({ - api: require('./api.json'), - docspath: '/api-docs', - handlers: './handlers' - })); - - ``` - - - Options: - - - - `api` - a valid Swagger 2.0 document. - - - `docspath` - the path to expose api docs for swagger-ui, etc. Defaults to `/`. - - - `handlers` - either a directory structure for route handlers or a premade object (see *Handlers Object* below). - - - `express` - express settings overrides. - - - After using this middleware, a new property will be available on the `app` called `swagger`, containing the following properties: - - - - `api` - the api document. - - - `routes` - the route definitions based on the api document. - - - Example: - - - ```javascript - - var http = require('http'); - - var express = require('express'); - - var swaggerize = require('swaggerize-express'); - - - app = express(); - - - var server = http.createServer(app); - - - app.use(swaggerize({ - api: require('./api.json'), - docspath: '/api-docs', - handlers: './handlers' - })); - - - server.listen(port, 'localhost', function () { - app.swagger.api.host = server.address().address + ':' + server.address().port; - }); - - ``` - - - ### Mount Path - - - Api `path` values will be prefixed with the swagger document's `basePath` value. - - - ### Handlers Directory - - - The `options.handlers` option specifies a directory to scan for handlers. These handlers are bound to the api `paths` defined in the swagger document. - - - ``` - - handlers - |--foo - | |--bar.js - |--foo.js - |--baz.js - ``` - - - Will route as: - - - ``` - - foo.js => /foo - - foo/bar.js => /foo/bar - - baz.js => /baz - - ``` - - - ### Path Parameters - - - The file and directory names in the handlers directory can also represent path parameters. - - - For example, to represent the path `/users/{id}`: - - - ```shell - - handlers - |--users - | |--{id}.js - ``` - - - This works with directory names as well: - - - ```shell - - handlers - |--users - | |--{id}.js - | |--{id} - | |--foo.js - ``` - - - To represent `/users/{id}/foo`. - - - ### Handlers File - - - Each provided javascript file should export an object containing functions with HTTP verbs as keys. - - - Example: - - - ```javascript - - module.exports = { - get: function (req, res) { ... }, - put: function (req, res) { ... }, - ... - } - - ``` - - - ### Handler Middleware - - - Handlers can also specify middleware chains by providing an array of handler functions under the verb: - - - ```javascript - - module.exports = { - get: [ - function m1(req, res, next) { ... }, - function m2(req, res, next) { ... }, - function handler(req, res) { ... } - ], - ... - } - - ``` - - - ### Handlers Object - - - The directory generation will yield this object, but it can be provided directly as `options.handlers`. - - - Note that if you are programatically constructing a handlers obj this way, you must namespace HTTP verbs with `$` to - - avoid conflicts with path names. These keys should also be *lowercase*. - - - Example: - - - ```javascript - - { - 'foo': { - '$get': function (req, res) { ... }, - 'bar': { - '$get': function (req, res) { ... }, - '$post': function (req, res) { ... } - } - } - ... - } - - ``` - - - Handler keys in files do *not* have to be namespaced in this way. - - - ### Security Middleware - - - If a security definition exists for a path in the swagger API definition, and an appropriate authorize function exists (defined using - - `x-authorize` in the `securityDefinitions` as per [swaggerize-routes](https://github.com/krakenjs/swaggerize-routes#security-object)), - - then it will be used as middleware for that path. - - - In addition, a `requiredScopes` property will be injected onto the `request` object to check against. - - - For example: - - - Swagger API definition: - - - ```json - . - . - . - - //A route with security object. - "security": [ - { - "petstore_auth": [ - "write_pets", - "read_pets" - ] - } - ] - . - . - . - //securityDefinitions - "securityDefinitions": { - "petstore_auth": { - "x-authorize": "lib/auth_oauth.js", // This path has to be relative to the project root. - "scopes": { - "write_pets": "modify pets in your account", - "read_pets": "read your pets" - } - } - }, - ``` - - - Sample `x-authorize` code - lib/auth_oauth.js : - - - ```javascript - - //x-authorize: auth_oauth.js - - function authorize(req, res, next) { - validate(req, function (error, availablescopes) { - /* - * `req.requiredScopes` is set by the `swaggerize-express` module to help - * with the scope and security validation. - * - */ - if (!error) { - for (var i = 0; i < req.requiredScopes.length; i++) { - if (availablescopes.indexOf(req.requiredScopes[i]) > -1) { - next(); - return; - } - } - - error = new Error('Do not have the required scopes.'); - error.status = 403; - - next(error); - return; - } - - next(error); - }); - } - - ``` - - - The context for `authorize` will be bound to the security definition, such that: - - - ```javascript - - function authorize(req, res, next) { - this.authorizationUrl; //from securityDefinition for this route's type. - //... - } - - ``` -khrt/Raisin: > - # NAME - - - Raisin - A REST API microframework for Perl. - - - # VERSION - - - version 0.94 - - - # SYNOPSIS - - use HTTP::Status qw(:constants); - use List::Util qw(max); - use Raisin::API; - use Types::Standard qw(HashRef Any Int Str); - - my %USERS = ( - 1 => { - first_name => 'Darth', - last_name => 'Wader', - password => 'deathstar', - email => 'darth@deathstar.com', - }, - 2 => { - first_name => 'Luke', - last_name => 'Skywalker', - password => 'qwerty', - email => 'l.skywalker@jedi.com', - }, - ); - - plugin 'Logger', fallback => 1; - app->log( debug => 'Starting Raisin...' ); - - middleware 'CrossOrigin', - origins => '*', - methods => [qw/DELETE GET HEAD OPTIONS PATCH POST PUT/], - headers => [qw/accept authorization content-type api_key_token/]; - - plugin 'Swagger'; - - swagger_setup( - title => 'A POD synopsis API', - description => 'An example of API documentation.', - #terms_of_service => '', - - contact => { - name => 'Artur Khabibullin', - url => 'http://github.com/khrt', - email => 'rtkh@cpan.org', - }, - - license => { - name => 'Perl license', - url => 'http://dev.perl.org/licenses/', - }, - ); - - desc 'Users API'; - resource users => sub { - summary 'List users'; - params( - optional('start', type => Int, default => 0, desc => 'Pager (start)'), - optional('count', type => Int, default => 10, desc => 'Pager (count)'), - ); - get sub { - my $params = shift; - - my @users - = map { { id => $_, %{ $USERS{$_} } } } - sort { $a <=> $b } keys %USERS; - - my $max_count = scalar(@users) - 1; - my $start = $params->{start} > $max_count ? $max_count : $params->{start}; - my $end = $params->{count} > $max_count ? $max_count : $params->{count}; - - my @slice = @users[$start .. $end]; - { data => \@slice } - }; - - summary 'List all users at once'; - get 'all' => sub { - my @users - = map { { id => $_, %{ $USERS{$_} } } } - sort { $a <=> $b } keys %USERS; - { data => \@users } - }; - - summary 'Create new user'; - params( - requires('user', type => HashRef, desc => 'User object', group { - requires('first_name', type => Str, desc => 'First name'), - requires('last_name', type => Str, desc => 'Last name'), - requires('password', type => Str, desc => 'User password'), - optional('email', type => Str, default => undef, regex => qr/.+\@.+/, desc => 'User email'), - }), - ); - post sub { - my $params = shift; - - my $id = max(keys %USERS) + 1; - $USERS{$id} = $params->{user}; - - res->status(HTTP_CREATED); - { success => 1 } - }; - - desc 'Actions on the user'; - params requires('id', type => Int, desc => 'User ID'); - route_param 'id' => sub { - summary 'Show user'; - get sub { - my $params = shift; - $USERS{ $params->{id} }; - }; - - summary 'Delete user'; - del sub { - my $params = shift; - delete $USERS{ $params->{id} }; - res->status(HTTP_NO_CONTENT); - undef; - }; - }; - }; - - run; - - # DESCRIPTION - - - Raisin is a REST API microframework for Perl. - - It's designed to run on Plack, providing a simple DSL to develop RESTful APIs easily. - - It was inspired by [Grape](https://github.com/intridea/grape). - - - # FUNCTIONS - - - ## API DESCRIPTION - - - ### app - - - Returns the `Raisin` app. Seldom needed, because most `Raisin::API` methods - - invoke the app directly. - - - ### resource - - - Adds a route to an application. `namespace` is a synonym for `resource`. - - resource user => sub { ... }; - - ### route\_param - - - Defines a route parameter as a resource `id` which can be anything if type - - isn't specified for it. - - route_param id => sub { ... }; - - Raisin allows you to nest `route_param`: - - params requires => { name => 'id', type => Int }; - route_param id => sub { - get sub { ... }; - - params requires => { name => 'sub_id', type => Int }; - route_param sub_id => sub { - ... - }; - }; - - ### produces - - - Specifies the content types produced by `resource`. - - produces ['text', 'json']; - - The argument is an array reference of strings corresponding to the - - keys used by `register_encoder`. This array is compared with the - - Accept header of the request to decide what content-type will - - actually be returned from a given invocation of `resource`. - - - ### del, get, patch, post, put, head, options - - - Shortcuts to add a `route` restricted to the corresponding HTTP method. - - get sub { 'GET' }; - - del 'all' => sub { 'OK' }; - - params( - requires('id', type => Int), - optional('key', type => Str), - ); - get sub { 'GET' }; - - desc 'Put data'; - params( - required('id', type => Int), - optional('name', type => Str), - ); - put 'all' => sub { - 'PUT' - }; - - ### desc - - - Adds a description to `resource` or any of the HTTP methods. - - Useful for OpenAPI as it's shown there as a description of an action. - - desc 'Some long explanation about an action'; - put sub { ... }; - - desc 'Some exaplanation about a group of actions', - resource => 'user' => sub { ... } - - ### summary - - - Same as ["desc"](#desc) but shorter. - - summary 'Some summary'; - put sub { ... }; - - ### tags - - - Tags can be used for logical grouping of operations by resources - - or any other qualifier. Using in API description. - - tags 'delete', 'user'; - delete sub { ... }; - - By default tags are added automatically based on it's namespace but you always - - can overwrite it using the function. - - - ### entity - - - Describes response object which will be used to generate OpenAPI description. - - entity 'MusicApp::Entity::Album'; - get { - my $albums = $schema->resultset('Album'); - present data => $albums, with => 'MusicApp::Entity::Album'; - }; - - ### params - - - Defines validations and coercion options for your parameters. - - Can be applied to any HTTP method and/or ["route\_param"](#route_param) to describe parameters. - - params( - requires('name', type => Str), - optional('start', type => Int, default => 0), - optional('count', type => Int, default => 10), - ); - get sub { ... }; - - params( - requires('id', type => Int, desc => 'User ID'), - ); - route_param 'id' => sub { ... }; - - For more see ["Validation-and-coercion" in Raisin](https://metacpan.org/pod/Raisin#Validation-and-coercion). - - - ### api\_default\_format - - - Specifies default API format mode when formatter isn't specified by API user. - - E.g. if URI is asked without an extension (`json`, `yaml`) or `Accept` header - - isn't specified the default format will be used. - - - Default value: `YAML`. - - api_default_format 'json'; - - See also ["API-FORMATS" in Raisin](https://metacpan.org/pod/Raisin#API-FORMATS). - - - ### api\_format - - - Restricts API to use only specified formatter to serialize and deserialize data. - - - Already exists [Raisin::Encoder::JSON](https://metacpan.org/pod/Raisin%3A%3AEncoder%3A%3AJSON), [Raisin::Encoder::YAML](https://metacpan.org/pod/Raisin%3A%3AEncoder%3A%3AYAML), - - and [Raisin::Encoder::Text](https://metacpan.org/pod/Raisin%3A%3AEncoder%3A%3AText), but you can always register your own - - using ["register\_encoder"](#register_encoder). - - api_format 'json'; - - See also ["API-FORMATS" in Raisin](https://metacpan.org/pod/Raisin#API-FORMATS). - - - ### api\_version - - - Sets up an API version header. - - api_version 1.23; - - ### plugin - - - Loads a Raisin module. A module options may be specified after the module name. - - Compatible with [Kelp](https://metacpan.org/pod/Kelp) modules. - - plugin 'Swagger'; - - ### middleware - - - Adds a middleware to your application. - - middleware '+Plack::Middleware::Session' => { store => 'File' }; - middleware '+Plack::Middleware::ContentLength'; - middleware 'Runtime'; # will be loaded Plack::Middleware::Runtime - - ### mount - - - Mounts multiple API implementations inside another one. - - These don't have to be different versions, but may be components of the same API. - - - In `RaisinApp.pm`: - - package RaisinApp; - - use Raisin::API; - - api_format 'json'; - - mount 'RaisinApp::User'; - mount 'RaisinApp::Host'; - - 1; - - ### register\_decoder - - - Registers a third-party parser (decoder). - - register_decoder(xml => 'My::Parser::XML'); - - See also [Raisin::Decoder](https://metacpan.org/pod/Raisin%3A%3ADecoder). - - - ### register\_encoder - - - Registers a third-party formatter (encoder). - - register_encoder(xml => 'My::Formatter::XML'); - - See also [Raisin::Encoder](https://metacpan.org/pod/Raisin%3A%3AEncoder). - - - ### run - - - Returns the `PSGI` application. - - - ## CONTROLLER - - - ### req - - - Provides quick access to the [Raisin::Request](https://metacpan.org/pod/Raisin%3A%3ARequest) object for the current route. - - - Use `req` to get access to request headers, params, env, etc. - - use DDP; - p req->headers; - p req->params; - p req->env; - - say req->header('X-Header'); - - See also [Plack::Request](https://metacpan.org/pod/Plack%3A%3ARequest). - - - ### res - - - Provides quick access to the [Raisin::Response](https://metacpan.org/pod/Raisin%3A%3AResponse) object for the current route. - - - Use `res` to set up response parameters. - - res->status(403); - res->headers(['X-Application' => 'Raisin Application']); - - See also [Plack::Response](https://metacpan.org/pod/Plack%3A%3AResponse). - - - ### param - - - Returns request parameters. - - Without an argument will return an array of all input parameters. - - Otherwise it will return the value of the requested parameter. - - - Returns [Hash::MultiValue](https://metacpan.org/pod/Hash%3A%3AMultiValue) object. - - say param('key'); # -> value - say param(); # -> { key => 'value', foo => 'bar' } - - ### include\_missing - - - Returns all declared parameters even if there is no value for a param. - - - See ["Declared-parameters" in Raisin](https://metacpan.org/pod/Raisin#Declared-parameters). - - - ### session - - - Returns `psgix.session` hash. When it exists, you can retrieve and store - - per-session data. - - # store param - session->{hello} = 'World!'; - - # read param - say session->{name}; - - ### present - - - Raisin hash a built-in `present` method, which accepts two arguments: an - - object to be presented and an options associated with it. The options hash may - - include `with` key, which is defined the entity to expose. See [Raisin::Entity](https://metacpan.org/pod/Raisin%3A%3AEntity). - - my $artists = $schema->resultset('Artist'); - - present data => $artists, with => 'MusicApp::Entity::Artist'; - present count => $artists->count; - - [Raisin::Entity](https://metacpan.org/pod/Raisin%3A%3AEntity) supports [DBIx::Class](https://metacpan.org/pod/DBIx%3A%3AClass) and [Rose::DB::Object](https://metacpan.org/pod/Rose%3A%3ADB%3A%3AObject). - - - For details see examples in _examples/music-app_ and [Raisin::Entity](https://metacpan.org/pod/Raisin%3A%3AEntity). - - - # ALLOWED METHODS - - - When you add a route for a resource, a route for the OPTIONS method will also be - - added. The response to an OPTIONS request will include an "Allow" header listing - - the supported methods. - - get 'count' => sub { - { count => $count }; - }; - - params( - requires('num', type => Int, desc => 'Value to add to the count.'), - ); - put 'count' => sub { - my $params = shift; - $count += $params->{num}; - { count: $count }; - }; - - - curl -v -X OPTIONS http://localhost:5000/count - - > OPTIONS /count HTTP/1.1 - > Host: localhost:5000 - > - * HTTP 1.0, assume close after body - < HTTP/1.1 204 No Content - < Allow: GET, OPTIONS, PUT - - If a request for a resource is made with an unsupported HTTP method, an HTTP 405 - - (Method Not Allowed) response will be returned. - - curl -X DELETE -v http://localhost:3000/count - - > DELETE /count HTTP/1.1 - > Host: localhost:5000 - > - * HTTP 1.0, assume close after body - < HTTP/1.1 405 Method Not Allowed - < Allow: OPTIONS, GET, PUT - - # PARAMETERS - - - Request parameters are available through the `params` `HASH`. This includes - - GET, POST and PUT parameters, along with any named parameters you specify in - - your route strings. - - - Parameters are automatically populated from the request body - - on `POST` and `PUT` for form input, `JSON` and `YAML` content-types. - - - The request: - - curl localhost:5000/data -H Content-Type:application/json -d '{"id": "14"}' - - The Raisin endpoint: - - post data => sub { param('id') }; - - Multipart `POST`s and `PUT`s are supported as well. - - - In the case of conflict between either of: - - - - path parameters; - - - GET, POST and PUT parameters; - - - contents of request body on POST and PUT; - - - Path parameters have precedence. - - - Query string and body parameters will be merged (see ["parameters" in Plack::Request](https://metacpan.org/pod/Plack%3A%3ARequest#parameters)) - - - ## Declared parameters - - - Raisin allows you to access only the parameters that have been declared by you in - - ["params" in Raisin](https://metacpan.org/pod/Raisin#params) block. - - - By default you can get all declared parameter as a first argument passed to your - - route subroutine. - - - Application: - - api_format 'json'; - - post data => sub { - my $params = shift; - { data => $params }; - }; - - Request: - - curl -X POST -H "Content-Type: application/json" localhost:5000/signup -d '{"id": 42}' - - Response: - - { "data": nil } - - Once we add parameters block, Raisin will start return only the declared parameters. - - - Application: - - api_format 'json'; - - params( - requires('id', type => Int), - optional('email', type => Str) - ); - post data => sub { - my $params = shift; - { data => $params }; - }; - - Request: - - curl -X POST -H "Content-Type: application/json" localhost:5000/signup -d '{"id": 42, "key": "value"}' - - Response: - - { "data": { "id": 42 } } - - By default declared parameters don't contain parameters which have no value. - - If you want to return all parameters you can use the `include_missing` function. - - - Application: - - api_format 'json'; - - params( - requires('id', type => Int), - optional('email', type => Str) - ); - post data => sub { - my $params = shift; - { data => include_missing($params) }; - }; - - Request: - - curl -X POST -H "Content-Type: application/json" localhost:5000/signup -d '{"id": 42, "key": "value"}' - - Response: - - { "data": { "id": 42, "email": null } } - - ## Validation and coercion - - - You can define validations and coercion options for your parameters using a - - ["params" in Raisin](https://metacpan.org/pod/Raisin#params) block. - - - Parameters can `requires` value or can be `optional`. - - `optional` parameters can have default value. - - params( - requires('name', type => Str), - optional('count', type => Int, default => 10), - ); - get sub { - my $params = shift; - "$params->{count}: $params->{name}"; - }; - - Note that default values will NOT be passed through to any validation options - - specified. - - - Available arguments: - - - - name - - - type - - - default - - - desc - - - regex - - - in - - - ## Nested Parameters - - - ### Hash - - - Use a keyword `group` to define a group of parameters which is enclosed to - - the parent `HashRef` parameter. - - params( - requires('name', type => HashRef, group { - requires('first_name', type => Str), - requires('last_name', type => Str), - }) - ) - - ### Array - - - Use `ArrayRef[*]` types from your compatible type library to define arrays. - - requires('list', type => ArrayRef[Int], desc => 'List of integers') - - ## Types - - - Raisin supports Moo(se)-compatible type constraint so you can use any of the - - [Moose](https://metacpan.org/pod/Moose), [Moo](https://metacpan.org/pod/Moo) or [Type::Tiny](https://metacpan.org/pod/Type%3A%3ATiny) type constraints. - - - By default [Raisin](https://metacpan.org/pod/Raisin) depends on [Type::Tiny](https://metacpan.org/pod/Type%3A%3ATiny) and it's [Types::Standard](https://metacpan.org/pod/Types%3A%3AStandard) type - - contraint library. - - - You can create your own types as well. - - See [Type::Tiny::Manual](https://metacpan.org/pod/Type%3A%3ATiny%3A%3AManual) and [Moose::Manual::Types](https://metacpan.org/pod/Moose%3A%3AManual%3A%3ATypes). - - - # HOOKS - - - Those blocks can be executed before or/and after every API call, using - - `before`, `after`, `before_validation` and `after_validation`. - - - Callbacks execute in the following order: - - - - before - - - before\_validation - - - after\_validation - - - after - - - The block applies to every API call - - before sub { - my $self = shift; - say $self->req->method . "\t" . $self->req->path; - }; - - after_validation sub { - my $self = shift; - say $self->res->body; - }; - - Steps `after_validation` and `after` are executed only if validation succeeds. - - - Every callback has only one argument as an input parameter which is [Raisin](https://metacpan.org/pod/Raisin) - - object. For more information of available methods see ["CONTROLLER" in Raisin](https://metacpan.org/pod/Raisin#CONTROLLER). - - - # API FORMATS - - - By default, Raisin supports `YAML`, `JSON`, and `TEXT` content types. - - Default format is `YAML`. - - - Response format can be determined by `Accept header` or `route extension`. - - - Serialization takes place automatically. So, you do not have to call - - `encode_json` in each `JSON` API implementation. - - - The response format (and thus the automatic serialization) is determined in the following order: - - - - Use the file extension, if specified. If the file is .json, choose the JSON format. - - - Attempt to find an acceptable format from the Accept header. - - - Use the default format, if specified by the `default_format` option. - - - Default to `YAML`. - - - Your API can declare to support only one serializator by using ["api\_format" in Raisin](https://metacpan.org/pod/Raisin#api_format). - - - Custom formatters for existing and additional types can be defined with a - - [Raisin::Encoder](https://metacpan.org/pod/Raisin%3A%3AEncoder)/[Raisin::Decoder](https://metacpan.org/pod/Raisin%3A%3ADecoder). - - - - JSON - - Call `JSON::encode_json` and `JSON::decode_json`. - - - YAML - - Call `YAML::Dump` and `YAML::Load`. - - - Text - - Call `Data::Dumper->Dump` if output data is not a string. - - The order for choosing the format is the following. - - - - Use the route extension. - - - Use the value of the `Accept` header. - - - Fallback to default. - - - # LOGGING - - - Raisin has a built-in logger and supports for `Log::Dispatch`. - - You can enable it by: - - plugin 'Logger', outputs => [['Screen', min_level => 'debug']]; - - Or use [Raisin::Logger](https://metacpan.org/pod/Raisin%3A%3ALogger) with a `fallback` option: - - plugin 'Logger', fallback => 1; - - The plugin registers a `log` subroutine to [Raisin](https://metacpan.org/pod/Raisin). Below are examples of - - how to use it. - - app->log(debug => 'Debug!'); - app->log(warn => 'Warn!'); - app->log(error => 'Error!'); - - `app` is a [Raisin](https://metacpan.org/pod/Raisin) instance, so you can use `$self` instead of `app` where - - it is possible. - - - See [Raisin::Plugin::Logger](https://metacpan.org/pod/Raisin%3A%3APlugin%3A%3ALogger). - - - # API DOCUMENTATION - - - ## Raisin script - - - You can see application routes with the following command: - - $ raisin examples/pod-synopsis-app/darth.pl - GET /user - GET /user/all - POST /user - GET /user/:id - DELETE /user/:id - PUT /user/:id - GET /echo - - Including parameters: - - $ raisin --params examples/pod-synopsis-app/darth.pl - GET /user - start Int{0} - count Int{10} - GET /user/all - POST /user - *name Str - *password Str - email Str - GET /user/:id - *id Int - DELETE /user/:id - *id Int - PUT /user/:id - *id Int - GET /echo - *data Any{ёй} - - ## OpenAPI/Swagger - - - [Swagger](http://swagger.io) compatible API documentations. - - plugin 'Swagger'; - - Documentation will be available on `http:///swagger.json` URL. - - So you can use this URL in Swagger UI. - - - See [Raisin::Plugin::Swagger](https://metacpan.org/pod/Raisin%3A%3APlugin%3A%3ASwagger). - - - # MIDDLEWARE - - - You can easily add any [Plack](https://metacpan.org/pod/Plack) middleware to your application using - - `middleware` keyword. See ["middleware" in Raisin](https://metacpan.org/pod/Raisin#middleware). - - - # PLUGINS - - - Raisin can be extended using custom _modules_. Each new module must be a subclass - - of the `Raisin::Plugin` namespace. Modules' job is to initialize and register new - - methods into the web application class. - - - For more see ["plugin" in Raisin](https://metacpan.org/pod/Raisin#plugin) and [Raisin::Plugin](https://metacpan.org/pod/Raisin%3A%3APlugin). - - - # TESTING - - - See [Plack::Test](https://metacpan.org/pod/Plack%3A%3ATest), [Test::More](https://metacpan.org/pod/Test%3A%3AMore) and etc. - - my $app = Plack::Util::load_psgi("$Bin/../script/raisinapp.pl"); - - test_psgi $app, sub { - my $cb = shift; - my $res = $cb->(GET '/user'); - - subtest 'GET /user' => sub { - if (!is $res->code, 200) { - diag $res->content; - BAIL_OUT 'FAILED!'; - } - my $got = Load($res->content); - isdeeply $got, $expected, 'Data!'; - }; - }; - - # DEPLOYING - - - Deploying a Raisin application is done the same way any other Plack - - application is deployed: - - $ plackup -E deployment -s Starman app.psgi - - ## Kelp - - use Plack::Builder; - use RaisinApp; - use KelpApp; - - builder { - mount '/' => KelpApp->new->run; - mount '/api/rest' => RaisinApp->new; - }; - - ## Dancer - - use Plack::Builder; - use Dancer ':syntax'; - use Dancer::Handler; - use RaisinApp; - - my $dancer = sub { - setting appdir => '/home/dotcloud/current'; - load_app 'My::App'; - Dancer::App->set_running_app('My::App'); - my $env = shift; - Dancer::Handler->init_request_headers($env); - my $req = Dancer::Request->new(env => $env); - Dancer->dance($req); - }; - - builder { - mount '/' => $dancer; - mount '/api/rest' => RaisinApp->new; - }; - - ## Mojolicious::Lite - - use Plack::Builder; - use RaisinApp; - - builder { - mount '/' => builder { - enable 'Deflater'; - require 'my_mojolicious-lite_app.pl'; - }; - - mount '/api/rest' => RaisinApp->new; - }; - - See also [Plack::Builder](https://metacpan.org/pod/Plack%3A%3ABuilder), [Plack::App::URLMap](https://metacpan.org/pod/Plack%3A%3AApp%3A%3AURLMap). - - - # EXAMPLES - - - Raisin comes with three instance in _example_ directory: - - - - pod-synopsis-app - - Basic example. - - - music-app - - Shows the possibility of using ["present" in Raisin](https://metacpan.org/pod/Raisin#present) with [DBIx::Class](https://metacpan.org/pod/DBIx%3A%3AClass) - and [Rose::DB::Object](https://metacpan.org/pod/Rose%3A%3ADB%3A%3AObject). - - - sample-app - - Shows an example of complex application. - - # ROADMAP - - - - Versioning support; - - - Mount API's in any place of `resource` block; - - - # GITHUB - - - [https://github.com/khrt/Raisin](https://github.com/khrt/Raisin) - - - # ACKNOWLEDGEMENTS - - - This module was inspired both by Grape and [Kelp](https://metacpan.org/pod/Kelp), - - which was inspired by [Dancer](https://metacpan.org/pod/Dancer), which in its turn was inspired by Sinatra. - - - # AUTHOR - - - Artur Khabibullin - - - # COPYRIGHT AND LICENSE - - - This software is copyright (c) 2019 by Artur Khabibullin. - - - This is free software; you can redistribute it and/or modify it under - - the same terms as the Perl 5 programming language system itself. -mobilcom-debitel/pokemock: "# Pokemock\r - - \r - - A mock server generated from one or more arbitrary Swagger files.\r - - Supports seeding, timeouts, response picking,\r - - entity memory, semantic action inference, etc.\r - - \r - - \r - - ## Usage\r - - \r - - ```\r - - Syntax:\r - - \ pokemock ... [-h] [-v] [-w] [-p ]\r - - \r - - Options:\r - - \ -h, --help Show help\r - - \ -v, --version Show version\r - - \ -p, --port Set server port, default is 8000\r - - \ -w, --watch Watch mode: Restart on Swagger changes\r - - \ -k, --killable Publish /kill endpoint to stop the service\r - - \ --memory Enable memory module (experimental)\r - - ```\r - - \r - - \r - - ## Server\r - - \r - - The mock server listens to the specified port and\r - - mocks endpoints defined in the provided Swagger document.\r - - Additionally, it publishes a Swagger UI under `/ui`,\r - - the Swagger API under `/api-docs` and a `/kill` endpoint for shutdown.\r - - \r - - \r - - ## Request Headers\r - - \r - - Using optional headers, clients can control the server's behavior:\r - - \r - - - __X-Mock-Status__\r - - \ - Specifies the response status code\r - - \ - The correct response is inferred from the API if possible\r - - \ - Defaults to the first response code specified in the API\r - - - __X-Mock-Seed__\r - - \ - Specifies a seed for data generation\r - - \ - If omitted, a random seed is generated\r - - \ - The current seed is always returned in a X-Mock-Seed response header\r - - - __X-Mock-Time__\r - - \ - Specifies the minimum response time (milliseconds)\r - - - __X-Mock-Size__\r - - \ - Specifies array size(s) in the response\r - - \ - Must be a valid JSON object of\r - - \ `: ` pairs\r - - \ - If omitted, array sizes are randomly between 1 and 5\r - - - __X-Mock-Depth__\r - - \ - Specifies the maximum JSON data depth\r - - \ - Defaults to 5\r - - - __X-Mock-Override__\r - - \ - Specifies response data via [JSON - Path](https://github.com/dchester/jsonpath)\r - - \ - Must be a valid JSON object of `: ` pairs\r - - \ - `` is arbitrary JSON\r - - - __X-Mock-Replay__\r - - \ - Specifies the number of times the current X-Mock-* headers should be - replayed\r - - \ - The next N requests to the requested URL will replay the current - X-Mock-* headers\r - - - __X-Mock-Replay-Pattern__\r - - \ - Specifies a regular expression to match for X-Mock-Replay\r - - \ - If omitted, the exact path is used for replaying\r - - \r - - \r - - ## Memory (experimental)\r - - \r - - Use the `--memory` switch to enable the memory module.\r - - When enabled, entities containing an ID are remembered by the server.\r - - If the entity is requested again, the remembered data is returned.\r - - This also applies to sub-entities across endpoints.\r - - \r - - Additionally, the server tries to infer semantic actions from requests,\r - - such as:\r - - \r - - - Get by id\r - - - Delete by id\r - - - Update by id\r - - - Create new entity\r - - \r - - These actions are applied to known entities in memory.\r - - For example, requesting a deleted entity will result in a 404 response.\r - - \r - - \r - - ## Customization\r - - \r - - Pokemock provides a set of [Express](http://expressjs.com/de/) middlewares\r - - which you can use independently.\r - - The default app defined in `createDefaultApp.js` is an opinionated stack - of\r - - middlewares which you're encouraged to hack on.\r - - By re-arranging and adding middlewares (especially generators)\r - - you can tailor Pokemock to fit your APIs.\r\n" -fleekjs/fleek-validator: '{"message":"Not - Found","documentation_url":"https://docs.github.com/rest/reference/repos#get-a-repository-readme"}' -oatpp/oatpp-swagger: > - # oatpp-swagger [![oatpp build - status](https://dev.azure.com/lganzzzo/lganzzzo/_apis/build/status/oatpp.oatpp-swagger)](https://dev.azure.com/lganzzzo/lganzzzo/_build?definitionId=2) - - Swagger UI for oatpp services - - - Read more: - - - [About oatpp](https://oatpp.io/) - - - [What is Swagger UI](https://swagger.io/tools/swagger-ui/) - - - [Endpoint annotation and API documentation in oatpp](https://oatpp.io/docs/components/api-controller/#endpoint-annotation-and-api-documentation). - - - ## Example - - - For full example project see: [Example CRUD-API project with Swagger UI](https://github.com/oatpp/example-crud) - - - ## Brief - - - - Use ```oatpp::swagger::Controller``` with ```oatpp::web::server::HttpConnectionHandler``` - - - Use ```oatpp::swagger::AsyncController``` with ```oatpp::web::server::AsyncHttpConnectionHandler``` - - - - Swagger UI location - ```http://localhost:/swagger/ui``` - - - OpenApi 3.0.0 specification location - ```http://localhost:/api-docs/oas-3.0.0.json``` - - - If you are using ```oatpp::web::server::api::ApiController``` most parts of your endpoints are documented automatically like: - - - - Endpoint name - - - Parameters - - - Request Body - - - You may add more information to your endpoint like follows: - - - ```c++ - - ENDPOINT_INFO(createUser) { - info->summary = "Create new User"; - info->addConsumes("application/json"); - info->addResponse(Status::CODE_200, "application/json"); - info->addResponse(Status::CODE_500); - } - - ENDPOINT("POST", "demo/api/users", createUser, - BODY_DTO(UserDto, userDto)) { - return createDtoResponse(Status::CODE_200, m_database->createUser(userDto)); - } - - ``` - - - ### How to add Swagger UI to your project - - - 1) Add ```oatpp::swagger::DocumentInfo``` and ```oatpp::swagger::Resources``` components to your AppComponents: - - - ```c++ - - /** - * General API docs info - */ - OATPP_CREATE_COMPONENT(std::shared_ptr, swaggerDocumentInfo)([] { - - oatpp::swagger::DocumentInfo::Builder builder; - - builder - .setTitle("User entity service") - .setDescription("CRUD API Example project with swagger docs") - .setVersion("1.0") - .setContactName("Ivan Ovsyanochka") - .setContactUrl("https://oatpp.io/") - - .setLicenseName("Apache License, Version 2.0") - .setLicenseUrl("http://www.apache.org/licenses/LICENSE-2.0") - - .addServer("http://localhost:8000", "server on localhost"); - - // When you are using the AUTHENTICATION() Endpoint-Macro you must add an SecurityScheme object (https://swagger.io/specification/#securitySchemeObject) - // For basic-authentication you can use the default Basic-Authorization-Security-Scheme like this - // For more complex authentication schemes you can use the oatpp::swagger::DocumentInfo::SecuritySchemeBuilder builder - // Don't forget to add info->addSecurityRequirement("basic_auth") to your ENDPOINT_INFO() Macro! - .addSecurityScheme("basic_auth", oatpp::swagger::DocumentInfo::SecuritySchemeBuilder::DefaultBasicAuthorizationSecurityScheme()); - - return builder.build(); - - }()); - - - - /** - * Swagger-Ui Resources (/lib/oatpp-swagger/res) - */ - OATPP_CREATE_COMPONENT(std::shared_ptr, swaggerResources)([] { - // Make sure to specify correct full path to oatpp-swagger/res folder !!! - return oatpp::swagger::Resources::loadResources("/lib/oatpp-swagger/res"); - }()); - - - ``` - - - 2) Create ```oatpp::swagger::Controller``` with list of endpoints you whant to document and add it to router: - - - ```c++ - - auto swaggerController = oatpp::swagger::Controller::createShared(); - - swaggerController->addEndpointsToRouter(router); - - ``` - - - 3) cmake : - - - Add the following lines to your CMakeLists.txt project file - - ``` - - - find_package(oatpp 1.3.0 REQUIRED) - - if(oatpp_FOUND) - message(STATUS "Found oatpp version: ${oatpp_VERSION_STRING}") - else() - message(FATAL_ERROR "Could not find oatpp") - endif() - - - find_package(oatpp-swagger 1.3.0 REQUIRED) - - if(oatpp-swagger_FOUND) - message(STATUS "Found oatpp-swagger version: ${oatpp-swagger_VERSION_STRING}") - else() - message(FATAL_ERROR "Could not find oatpp-swagger") - endif() - - - include_directories(${oatpp_INCLUDE_DIRS}) - - include_directories(${oatpp-swagger_INCLUDE_DIRS}) - - - add_definitions( - -DOATPP_SWAGGER_RES_PATH="${OATPP_BASE_DIR}/bin/oatpp-swagger/res" - ) - - - target_link_libraries (project PUBLIC - // add_your libraries here - PUBLIC oatpp::oatpp - PUBLIC oatpp::oatpp-swagger - ) - - ``` - - - ### Customise Swagger UI Paths - - - To customise swagger UI endpoints paths add the following component: - - - ```c++ - /** - * Swagger Controller Paths - */ - OATPP_CREATE_COMPONENT(std::shared_ptr, controllerPaths)([] { - auto paths = std::make_shared(); - paths->apiJson = "custom/path/for/api.json"; // default is "api-docs/oas-3.0.0.json" - paths->ui = "my/custom/path/swagger-ui"; // default is "swagger/ui" - paths->uiResources = "my/custom/path/{filename}"; // default is "swagger/{filename}" - return paths; - }()); - ``` - - - **NOTE:** `paths->ui` and `paths->uiResources` MUST have the same base path - as shown above. - - - **Done!** -zaaack/koa-joi-swagger: > - # koa-joi-swagger - - - * Using joi schema to validate request & response, and generate swagger document to create beautiful API documents. - - - - [![Build Status](https://travis-ci.org/zaaack/koa-joi-swagger.svg?branch=master)](https://travis-ci.org/zaaack/koa-joi-swagger) [![npm](https://img.shields.io/npm/v/koa-joi-swagger.svg)](https://www.npmjs.com/package/koa-joi-swagger) [![npm](https://img.shields.io/npm/dm/koa-joi-swagger.svg)](https://www.npmjs.com/package/koa-joi-swagger) - - - ## Feature - - - * Router agnostic. - - * Using your favorite library for validation, and generate swagger document for develop. - - * Serving Swagger UI in your koa project. - - * ... - - - ## Install - - - ```sh - - npm i koa-joi-swagger - - - ``` - - - or - - - ```sh - - yarn add koa-joi-swagger - - ``` - - - for v3, install optional dependencies - - ```sh - - npm i swagger-ui-dist # or yarn add swagger-ui-dist - - ``` - - - - ## Example - - - ```sh - - git clone https://github.com/zaaack/koa-joi-swagger.git - - cd koa-joi-swagger - - yarn # or npm i - - SERVE=1 npx babel-node ./test/fixtures/server.js - - ``` - - - Now open ! - - - ## Demo - - - app.js - - ```js - - import { toSwaggerDoc, ui, mixedValidate } from '../../src' - - import mixedDoc from './mixed-doc' - - import Koa from 'koa' - - import DecRouter from 'koa-dec-router' - - import bodyparser from 'koa-bodyparser' - - - const app = new Koa() - - - const decRouter = DecRouter({ - controllersDir: `${__dirname}/controllers`, - }) - - - app.use(bodyparser()) - - - const swaggerDoc = toSwaggerDoc(mixedDoc) - - // mount swagger ui in `/swagger` - - app.use(ui(swaggerDoc, {pathRoot: '/swagger'})) - - - // handle validation errors - - app.use(async (ctx, next) => { - try { - await next() - } catch (e) { - if (e.name === 'RequestValidationError') { - ctx.status = 400 - ctx.body = { - code: 1, - message: e.message, - data: e.data, - } - } else if (e.name === 'ResponseValidationError') { - ctx.status = 500 - ctx.body = { - code: 1, - message: e.message, - data: e.data, - } - } - } - }) - - - // validate request and response by mixedDoc - - app.use(mixedValidate(mixedDoc, { - onError: e => console.log(e.details, e._object), - })) - - - // koa-dec-router - - app.use(decRouter.router.routes()) - - app.use(decRouter.router.allowedMethods()) - - - app.listen(3456) - - ``` - - - > "I see the api is simple, but how to write the joi schema and the swagger document?" - - - That's the point, you don't need to write a joi schema to validation and a swagger document to create API documents. - - - > "Oh, no, Should I learn a new schema?" - - - Of cause not, I hate new schemas, too, especially those made by someone or some company without long support, it's just a waste of time and my brain cell. - - - Therefore, to make this library simple and reliable, I just mixed joi and swagger document, and using [joi-to-json-schema](https://github.com/lightsofapollo/joi-to-json-schema/) to transform joi schema to swagger schema. You don't have to learn a new schema, just replace the JSON schema in your swagger document to joi schema, then let this library to do the rest. - - - I call it mixed document, here is an example. - - - ```js - - export default { - swagger: '2.0', - info: { - title: 'Test API', - description: 'Test API', - version: '1.0.0', - }, - // the domain of the service - // host: 127.0.0.1:3457 - // array of all schemes that your API supports - schemes: ['https', 'http'], - // will be prefixed to all paths - basePath: '/api/v1', - consumes: ['application/x-www-form-urlencoded'], - produces: ['application/json'], - paths: { - '/posts': { - get: { - summary: 'Some posts', - tags: ['Post'], - parameters: { - query: Joi.object().keys({ - type: Joi.string().valid(['news', 'article']), - }), - }, - responses: { - '200': { - x: 'Post list', - schema: Joi.object().keys({ - lists: Joi.array().items(Joi.object().keys({ - title: Joi.string().description('Post title'), - content: Joi.string().required().description('Post content'), - })) - }), - }, - 'default': { - description: 'Error happened', - schema: Joi.object().json().keys({ - code: Joi.number().integer(), - message: Joi.string(), - data: Joi.object(), - }), - }, - } - } - }, - }, - } - - ``` - - - You can see the differences between this and the real swagger document, just replace `parameters` and `responses` to joi schema instead of JSON schema, - - - [Here is the swagger document that generate from mixed document above](docs/swagger-doc-from-mixed-doc.json). - - - ## API - - - ```js - - import JoiSwagger, { - toSwaggerDoc, mixedValidate, joiValidate, ui - } from 'koa-joi-swagger' - - import Koa from 'koa' - - - const app = new Koa() - - /* - - - JoiSwagger = { - toSwaggerDoc, - mixedValidate, - joiValidate, - ui, - Joi, - } - */ - - const mixedDoc = require('./mixed-doc') - - - const swaggerDoc = toSwaggerDoc(mixedDoc) // parse mixed document to swagger document for swagger-ui - - - - // - - // const defaultResJoiOpts = { - - // stripUnknown: true, - - // convert: true, - - // } - - app.use(mixedValidate(mixedDoc, { - reqOpts: { - stripUnknown: false, - convert: true, - }, // optional, ctx.request joi validation options, here is default - resOpts: { // optional, ctx.response joi validation options, here is default - stripUnknown: true, // this would remove additional properties - convert: true, // this would convert field types - }, - onError: err => console.error(err), // Do something with the error, the error would throw anyway. - })) - - - app.use(ui(swaggerDoc, { - pathRoot: '/swagger', // optional, swagger path - skipPaths: [], // optional, skip paths - UIHtml: defaultUIHtml, // optional, get ui html - swaggerConfig: '', // optional, a json5 string, e.g. `{ : , .... }` to display in html for overriding swagger ui options. - sendConfig: { maxage: 3600 * 1000 * 24 * 30 }, // optional, config for koa-send, default maxage is 1 month. - v3: false, // optional, default is v2, you need to install optional dependencies `swagger-ui-dist` first. - - })) - - - // joiValidate // the internal joi validation function used by mixedValidate, in case you need one. - - // JoiSwagger.Joi // The joi used to validate, with some opinionated extension, you can override it or using it. - - - ``` - - - ## Q & A - - - #### 1. Why not using [ajv](https://github.com/epoberezkin/ajv) to validate by swagger document directly? - - - I have think it before, but hit some problems like validating javascript date object, remove additionalProperties, etc. And writing JSON schema is too verbose. Joi is the best validation library in NodeJS, we should take the advantage. - - - #### 2. Why not using YAML? - - - YAML is not easy to reuse, although JSON schema can reuse model, and how to reuse shared properties between models? I can't find a way. Pure javascrip can easily reuse or wrap model schema, and you can wrap each final schema with a function, don't feel pain when adding properties for each request schema in the future. - - - #### 3. You extended Joi, why? - - - Sorry, joi's philosophy is too strict for me, I really don't need to explicit declare the string could be empty, so I override the original `Joi.string()` to make `Joi.string().empty('')` is a default behavior. - - - Also, add a `.force()` method for string/number type, to coerce the field to string/number regardless of the original type, it's really useful when validating some bson type like Long, Deciaml or Custom object. - - - - Added a `Joi.object().json()` to coerce object with `toJSON` method to a plain JSON object. This would useful when validation some ORM/ODM's model object (like mongorito). - - - [See the code](src/joi.js) - - - And I highly recommend using this extended joi to write your schemas, and adding your extension if you need. - - - You can also using other version of Joi to validate. - - - ```js - - import JoiSwagger from 'koa-joi-swagger' - - import myJoi from './myJoi' - - - // using - - export const Joi = JoiSwagger.Joi - - - // override - - JoiSwagger.Joi = myJoi - - - ``` -ruby-grape/grape-swagger: > - [![Gem - Version](https://badge.fury.io/rb/grape-swagger.svg)](http://badge.fury.io/rb/grape-swagger) - - [![Build Status](https://travis-ci.org/ruby-grape/grape-swagger.svg?branch=master)](https://travis-ci.org/ruby-grape/grape-swagger) - - [![Coverage Status](https://coveralls.io/repos/github/ruby-grape/grape-swagger/badge.svg?branch=master)](https://coveralls.io/github/ruby-grape/grape-swagger?branch=master) - - [![Code Climate](https://codeclimate.com/github/ruby-grape/grape-swagger.svg)](https://codeclimate.com/github/ruby-grape/grape-swagger) - - - ##### Table of Contents - - - * [What is grape-swagger?](#what) - - * [Related Projects](#related) - - * [Compatibility](#version) - - * [Swagger-Spec](#swagger-spec) - - * [Installation](#install) - - * [Usage](#usage) - - * [Model Parsers](#model_parsers) - - * [Configure](#configure) - - * [Routes Configuration](#routes) - - * [Using Grape Entities](#grape-entity) - - * [Securing the Swagger UI](#oauth) - - * [Example](#example) - - * [Rake Tasks](#rake) - - - - ## What is grape-swagger? - - - The grape-swagger gem provides an autogenerated documentation for your [Grape](https://github.com/ruby-grape/grape) API. The generated documentation is Swagger-compliant, meaning it can easily be discovered in [Swagger UI](https://github.com/swagger-api/swagger-ui). You should be able to point [the petstore demo](http://petstore.swagger.io/) to your API. - - - ![Demo Screenshot](example/swagger-example.png) - - - This screenshot is based on the [Hussars](https://github.com/LeFnord/hussars) sample app. - - - - ## Related Projects - - - * [Grape](https://github.com/ruby-grape/grape) - - * [Grape Swagger Entity](https://github.com/ruby-grape/grape-swagger-entity) - * [Grape Entity](https://github.com/ruby-grape/grape-entity) - * [Grape Swagger Representable](https://github.com/ruby-grape/grape-swagger-representable) - - * [Swagger UI](https://github.com/swagger-api/swagger-ui) - - - - - ## Compatibility - - - The following versions of grape, grape-entity and grape-swagger can currently be used together. - - - | grape-swagger | swagger spec | grape | grape-entity | representable | - - | ------------- | ------------ | ----------------------- | ------------ | ------------- | - - | 0.10.5 | 1.2 | >= 0.10.0 ... <= 0.14.0 | < 0.5.0 | n/a | - - | 0.11.0 | 1.2 | >= 0.16.2 | < 0.5.0 | n/a | - - | 0.25.2 | 2.0 | >= 0.14.0 ... <= 0.18.0 | <= 0.6.0 | >= 2.4.1 | - - | 0.26.0 | 2.0 | >= 0.16.2 ... <= 1.1.0 | <= 0.6.1 | >= 2.4.1 | - - | 0.27.0 | 2.0 | >= 0.16.2 ... <= 1.1.0 | >= 0.5.0 | >= 2.4.1 | - - | 0.32.0 | 2.0 | >= 0.16.2 | >= 0.5.0 | >= 2.4.1 | - - | 0.34.0 | 2.0 | >= 0.16.2 ... < 1.3.0 | >= 0.5.0 | >= 2.4.1 | - - | >= 1.0.0 | 2.0 | >= 1.3.0 | >= 0.5.0 | >= 2.4.1 | - - - - ## Swagger-Spec - - - Grape-swagger generates documentation per [Swagger / OpenAPI Spec 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md). - - - - - - - ## Installation - - - Add to your Gemfile: - - - ```ruby - - gem 'grape-swagger' - - ``` - - - ## Upgrade - - - Please see [UPGRADING](UPGRADING.md) when upgrading from a previous version. - - - - - ## Usage - - - Mount all your different APIs (with `Grape::API` superclass) on a root node. In the root class definition, include `add_swagger_documentation`, this sets up the system and registers the documentation on '/swagger_doc'. See [example/config.ru](example/config.ru) for a simple demo. - - - - ```ruby - - require 'grape-swagger' - - - module API - class Root < Grape::API - format :json - mount API::Cats - mount API::Dogs - mount API::Pirates - add_swagger_documentation - end - end - - ``` - - - To explore your API, either download [Swagger UI](https://github.com/swagger-api/swagger-ui) and set it up yourself or go to the [online swagger demo](http://petstore.swagger.io/) and enter your localhost url documentation root in the url field (probably something in the line of http://localhost:3000/swagger_doc). - - - - - ## Model Parsers - - - Since 0.21.0, `Grape::Entity` is not a part of grape-swagger, you need to add `grape-swagger-entity` manually to your Gemfile. - - Also added support for [representable](https://github.com/trailblazer/representable) via `grape-swagger-representable`. - - - ```ruby - - # For Grape::Entity ( https://github.com/ruby-grape/grape-entity ) - - gem 'grape-swagger-entity', '~> 0.3' - - # For representable ( https://github.com/apotonick/representable ) - - gem 'grape-swagger-representable', '~> 0.2' - - ``` - - - If you are not using Rails, make sure to load the parser inside your application initialization logic, e.g., via `require 'grape-swagger/entity'` or `require 'grape-swagger/representable'`. - - - ### Custom Model Parsers - - - You can create your own model parser, for example for [roar](https://github.com/trailblazer/roar). - - - ```ruby - - module GrapeSwagger - module Roar - class Parser - attr_reader :model - attr_reader :endpoint - - def initialize(model, endpoint) - @model = model - @endpoint = endpoint - end - - def call - # Parse your model and return hash with model schema for swagger - end - end - end - end - - ``` - - - Then you should register your custom parser. - - - ```ruby - - GrapeSwagger.model_parsers.register(GrapeSwagger::Roar::Parser, Roar::Decorator) - - ``` - - - To control model parsers sequence, you can insert your parser before or after another parser. - - - #### insert_before - - - ```ruby - - GrapeSwagger.model_parsers.insert_before(GrapeSwagger::Representable::Parser, GrapeSwagger::Roar::Parser, Roar::Decorator) - - ``` - - - #### insert_after - - - ```ruby - - GrapeSwagger.model_parsers.insert_after(GrapeSwagger::Roar::Parser, GrapeSwagger::Representable::Parser, Representable::Decorator) - - ``` - - - As we know, `Roar::Decorator` uses `Representable::Decorator` as a superclass, this allows to avoid a problem when Roar objects are processed by `GrapeSwagger::Representable::Parser` instead of `GrapeSwagger::Roar::Parser`. - - - - ### CORS - - - If you use the online demo, make sure your API supports foreign requests by enabling CORS in Grape, otherwise you'll see the API description, but requests on the API won't return. Use [rack-cors](https://github.com/cyu/rack-cors) to enable CORS. - - - ```ruby - - require 'rack/cors' - - use Rack::Cors do - allow do - origins '*' - resource '*', headers: :any, methods: [ :get, :post, :put, :delete, :options ] - end - end - - ``` - - - Alternatively you can set CORS headers in a Grape `before` block. - - - ```ruby - - before do - header['Access-Control-Allow-Origin'] = '*' - header['Access-Control-Request-Method'] = '*' - end - - ``` - - - - - ## Configure - - - * [host](#host) - - * [base_path](#base_path) - - * [mount_path](#mount_path) - - * [add_base_path](#add_base_path) - - * [add_root](#add_root) - - * [add_version](#add_version) - - * [doc_version](#doc_version) - - * [endpoint_auth_wrapper](#endpoint_auth_wrapper) - - * [swagger_endpoint_guard](#swagger_endpoint_guard) - - * [token_owner](#token_owner) - - * [security_definitions](#security_definitions) - - * [security](#security) - - * [models](#models) - - * [tags](#tags) - - * [hide_documentation_path](#hide_documentation_path) - - * [info](#info) - - * [array_use_braces](#array_use_braces) - - * [api_documentation](#api_documentation) - - * [specific_api_documentation](#specific_api_documentation) - - * [consumes](#consumes) - - * [produces](#produces) - - - You can pass a hash with optional configuration settings to ```add_swagger_documentation```. - - The examples show the default value. - - - - The `host` and `base_path` options also accept a `proc` or a `lambda` to evaluate, which is passed a [request](http://www.rubydoc.info/github/rack/rack/Rack/Request) object: - - - ```ruby - - add_swagger_documentation \ - base_path: proc { |request| request.host =~ /^example/ ? '/api-example' : '/api' } - ``` - - - - #### host: - - Sets explicit the `host`, default would be taken from `request`. - - ```ruby - - add_swagger_documentation \ - host: 'www.example.com' - ``` - - - - #### base_path: - - Base path of the API that's being exposed, default would be taken from `request`. - - ```ruby - - add_swagger_documentation \ - base_path: nil - ``` - - - `host` and `base_path` are also accepting a `proc` or `lambda` - - - - #### mount_path: - - The path where the API documentation is loaded, default is: `/swagger_doc`. - - ```ruby - - add_swagger_documentation \ - mount_path: '/swagger_doc' - ``` - - - #### add_base_path: - - Add `basePath` key to the documented path keys, default is: `false`. - - ```ruby - - add_swagger_documentation \ - add_base_path: true # only if base_path given - ``` - - - #### add_root: - - Add root element to all the responses, default is: `false`. - - ```ruby - - add_swagger_documentation \ - add_root: true - ``` - - - #### add_version: - - - Add `version` key to the documented path keys, default is: `true`, - - here the version is the API version, specified by `grape` in [`path`](https://github.com/ruby-grape/grape/#path) - - - ```ruby - - add_swagger_documentation \ - add_version: true - ``` - - - - #### doc_version: - - - Specify the version of the documentation at [info section](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#info-object), default is: `'0.0.1'` - - ```ruby - - add_swagger_documentation \ - doc_version: '0.0.1' - ``` - - - - #### endpoint_auth_wrapper: - - - Specify the middleware to use for securing endpoints. - - - ```ruby - - add_swagger_documentation \ - endpoint_auth_wrapper: WineBouncer::OAuth2 - ``` - - - - #### swagger_endpoint_guard: - - Specify the method and auth scopes, used by the middleware for securing endpoints. - - - ```ruby - - add_swagger_documentation \ - swagger_endpoint_guard: 'oauth2 false' - ``` - - - - #### token_owner: - - Specify the token_owner method, provided by the middleware, which is typically named 'resource_owner'. - - - ```ruby - - add_swagger_documentation \ - token_owner: 'resource_owner' - ``` - - - - #### security_definitions: - - Specify the [Security Definitions Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#security-definitions-object) - - - _NOTE: [Swagger-UI is supporting only implicit flow yet](https://github.com/swagger-api/swagger-ui/issues/2406#issuecomment-248651879)_ - - - ```ruby - - add_swagger_documentation \ - security_definitions: { - api_key: { - type: "apiKey", - name: "api_key", - in: "header" - } - } - ``` - - - #### security: - - - Specify the [Security Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#securityRequirementObject) - - - ```ruby - - add_swagger_documentation \ - security: [ - { - api_key: [] - } - ] - ``` - - - - #### models: - - A list of entities to document. Combine with the [grape-entity](https://github.com/ruby-grape/grape-entity) gem. - - - These would be added to the definitions section of the swagger file. - - - ```ruby - - add_swagger_documentation \ - models: [ - TheApi::Entities::UseResponse, - TheApi::Entities::ApiError - ] - ``` - - - - #### tags: - - - A list of tags to document. By default tags are automatically generated - - for endpoints based on route names. - - - ```ruby - - add_swagger_documentation \ - tags: [ - { name: 'widgets', description: 'A description of widgets' } - ] - ``` - - - - #### hide_documentation_path: (default: `true`) - - - ```ruby - - add_swagger_documentation \ - hide_documentation_path: true - ``` - - - Don't show the `/swagger_doc` path in the generated swagger documentation. - - - - #### info: - - - ```ruby - - add_swagger_documentation \ - info: { - title: "The API title to be displayed on the API homepage.", - description: "A description of the API.", - contact_name: "Contact name", - contact_email: "Contact@email.com", - contact_url: "Contact URL", - license: "The name of the license.", - license_url: "www.The-URL-of-the-license.org", - terms_of_service_url: "www.The-URL-of-the-terms-and-service.com", - } - ``` - - - A hash merged into the `info` key of the JSON documentation. - - - #### array_use_braces: - - - ```ruby - - add_swagger_documentation \ - array_use_braces: true - ``` - This setting must be `true` in order for params defined as an `Array` type to submit each element properly. - ```ruby - params do - optional :metadata, type: Array[String] - end - - ``` - with `array_use_braces: true`: - ``` - - metadata[]: { "name": "Asset ID", "value": "12345" } - - metadata[]: { "name": "Asset Tag", "value": "654321"} - - ``` - with `array_use_braces: false`: - ``` - - metadata: {"name": "Asset ID", "value": "123456"} - - metadata: {"name": "Asset Tag", "value": "654321"} - - ``` - - - #### api_documentation - - - Customize the Swagger API documentation route, typically contains a `desc` field. The default description is "Swagger compatible API description". - - - ```ruby - - add_swagger_documentation \ - api_documentation: { desc: 'Reticulated splines API swagger-compatible documentation.' } - ``` - - - #### specific_api_documentation - - - Customize the Swagger API specific documentation route, typically contains a `desc` field. The default description is "Swagger compatible API description for specific API". - - - ```ruby - - add_swagger_documentation \ - specific_api_documentation: { desc: 'Reticulated splines API swagger-compatible endpoint documentation.' } - ``` - - - #### consumes - - - Customize the Swagger API default global `consumes` field value. - - - ```ruby - - add_swagger_documentation \ - consumes: ['application/json', 'application/x-www-form-urlencoded'] - ``` - - - #### produces - - - Customize the Swagger API default global `produces` field value. - - - ```ruby - - add_swagger_documentation \ - produces: ['text/plain'] - ``` - - - ## Routes Configuration - - - * [Swagger Header Parameters](#headers) - - * [Hiding an Endpoint](#hiding) - - * [Overriding Auto-Generated Nicknames](#overriding-auto-generated-nicknames) - - * [Specify endpoint details](#details) - - * [Overriding the route summary](#summary) - - * [Overriding the tags](#overriding_the_tags) - - * [Deprecating routes](#deprecating-routes) - - * [Overriding the name of the body parameter](#body-param) - - * [Defining an endpoint as an array](#array) - - * [Using an options hash](#options) - - * [Overriding parameter type](#overriding-param-type) - - * [Overriding data type of the parameter](#overriding-type-of-param) - - * [Multiple types](#multiple-types) - - * [Array of data type](#array-type) - - * [Collection Format](#collection-format) - - * [Hiding parameters](#hiding-parameters) - - * [Setting a Swagger default value](#default-value) - - * [Setting `additionalProperties` for `object`-type parameters](#additional-properties) - - * [Example parameter value](#param-example) - - * [Response documentation](#response) - - * [Changing default status codes](#change-status) - - * [File response](#file-response) - - * [Extensions](#extensions) - - * [Response examples documentation](#response-examples) - - * [Response headers documentation](#response-headers) - - * [Adding root element to responses](#response-root) - - * [Multiple present Response](#multiple-response) - - - #### Swagger Header Parameters - - - Swagger also supports the documentation of parameters passed in the header. Since grape's ```params[]``` doesn't return header parameters we can specify header parameters seperately in a block after the description. - - - ```ruby - - desc "Return super-secret information", { - headers: { - "XAuthToken" => { - description: "Valdates your identity", - required: true - }, - "XOptionalHeader" => { - description: "Not really needed", - required: false - } - } - } - - ``` - - - - #### Hiding an Endpoint - - - You can hide an endpoint by adding ```hidden: true``` in the description of the endpoint: - - - ```ruby - - desc 'Hide this endpoint', hidden: true - - ``` - - - Or by adding ```hidden: true``` on the verb method of the endpoint, such as `get`, `post` and `put`: - - - ```ruby - - get '/kittens', hidden: true do - - ``` - - - Or by using a route setting: - - - ```ruby - - route_setting :swagger, { hidden: true } - - get '/kittens' do - - ``` - - - Endpoints can be conditionally hidden by providing a callable object such as a lambda which evaluates to the desired - - state: - - - ```ruby - - desc 'Conditionally hide this endpoint', hidden: lambda { ENV['EXPERIMENTAL'] != 'true' } - - ``` - - - - #### Overriding Auto-Generated Nicknames - - - You can specify a swagger nickname to use instead of the auto generated name by adding `:nickname 'string'` in the description of the endpoint. - - - ```ruby - - desc 'Get a full list of pets', nickname: 'getAllPets' - - ``` - - - - #### Specify endpoint details - - - To specify further details for an endpoint, use the `detail` option within a block passed to `desc`: - - - ```ruby - - desc 'Get all kittens!' do - detail 'this will expose all the kittens' - end - - get '/kittens' do - - ``` - - - - #### Overriding the route summary - - - To override the summary, add `summary: '[string]'` after the description. - - - ```ruby - - namespace 'order' do - desc 'This will be your summary', - summary: 'Now this is your summary!' - get :order_id do - ... - end - end - - ``` - - - - #### Overriding the tags - - - Tags are used for logical grouping of operations by resources or any other qualifier. To override the - - tags array, add `tags: ['tag1', 'tag2']` after the description. - - - ```ruby - - namespace 'order' do - desc 'This will be your summary', tags: ['orders'] - get :order_id do - ... - end - end - - ``` - - - - #### Deprecating routes - - - To deprecate a route add `deprecated: true` after the description. - - - ```ruby - - namespace 'order' do - desc 'This is a deprecated route', deprecated: true - get :order_id do - ... - end - end - - ``` - - - - #### Overriding the name of the body parameter - - - By default, body parameters have a generated name based on the operation. For - - deeply nested resources, this name can get very long. To override the name of - - body parameter add `body_name: 'post_body'` after the description. - - - ```ruby - - namespace 'order' do - desc 'Create an order', body_name: 'post_body' - post do - ... - end - end - - ``` - - - - #### Defining an endpoint as an array - - - You can define an endpoint as an array by adding `is_array` in the description: - - - ```ruby - - desc 'Get a full list of pets', is_array: true - - ``` - - - - #### Using an options hash - - - The Grape DSL supports either an options hash or a restricted block to pass settings. Passing the `nickname`, `hidden` and `is_array` options together with response codes is only possible when passing an options hash. - - Since the syntax differs you'll need to adjust it accordingly: - - - ```ruby - - desc 'Get all kittens!', { - hidden: true, - is_array: true, - nickname: 'getKittens', - success: Entities::Kitten, # or success - failure: [[401, 'KittenBitesError', Entities::BadKitten]] # or failure - # also explicit as hash: [{ code: 401, message: 'KittenBitesError', model: Entities::BadKitten }] - produces: [ "array", "of", "mime_types" ], - consumes: [ "array", "of", "mime_types" ] - } - get '/kittens' do - - ``` - - - - #### Overriding parameter type - - - You can override paramType, using the documentation hash. See [parameter object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameter-object) for available types. - - - ```ruby - - params do - requires :action, type: Symbol, values: [:PAUSE, :RESUME, :STOP], documentation: { param_type: 'query' } - end - - post :act do - ... - end - - ``` - - - - #### Overriding data type of the parameter - - - You can override type, using the documentation hash. - - - ```ruby - - params do - requires :input, type: String, documentation: { type: 'integer' } - end - - post :act do - ... - end - - ``` - - - ```json - - { - "in": "formData", - "name": "input", - "type": "integer", - "format": "int32", - "required": true - } - - ``` - - - - #### Multiple types - - - By default when you set multiple types, the first type is selected as swagger type - - - ```ruby - - params do - requires :action, types: [String, Integer] - end - - post :act do - ... - end - - ``` - - - ```json - - { - "in": "formData", - "name": "action", - "type": "string", - "required": true - } - - ``` - - - - #### Array of data type - - - Array types are also supported. - - - ```ruby - - params do - requires :action_ids, type: Array[Integer] - end - - post :act do - ... - end - - ``` - - - ```json - - { - "in": "formData", - "name": "action_ids", - "type": "array", - "items": { - "type": "integer" - }, - "required": true - } - - ``` - - - - #### Collection format of arrays - - - You can set the collection format of an array, using the documentation hash. - - - Collection format determines the format of the array if type array is used. Possible values are: - - * csv - comma separated values foo,bar. - - * ssv - space separated values foo bar. - - * tsv - tab separated values foo\tbar. - - * pipes - pipe separated values foo|bar. - - * multi - corresponds to multiple parameter instances instead of multiple values for a single instance foo=bar&foo=baz. This is valid only for parameters in "query" or "formData". - - - ```ruby - - params do - requires :statuses, type: Array[String], documentation: { collectionFormat: 'multi' } - end - - post :act do - ... - end - - ``` - - - ```json - - { - "in": "formData", - "name": "statuses", - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "multi", - "required": true - } - - ``` - - - - #### Hiding parameters - - - Exclude single optional parameter from the documentation - - - ```ruby - - not_admins = lambda { |token_owner = nil| token_owner.nil? || !token_owner.admin? } - - - params do - optional :one, documentation: { hidden: true } - optional :two, documentation: { hidden: -> { |t=nil| true } } - optional :three, documentation: { hidden: not_admins } - end - - post :act do - ... - end - - ``` - - - - #### Setting a Swagger default value - - - Grape allows for an additional documentation hash to be passed to a parameter. - - - ```ruby - - params do - requires :id, type: Integer, desc: 'Coffee ID' - requires :temperature, type: Integer, desc: 'Temperature of the coffee in celcius', documentation: { default: 72 } - end - - ``` - - - Grape uses the option `default` to set a default value for optional parameters. This is different in that Grape will set your parameter to the provided default if the parameter is omitted, whereas the example value above will only set the value in the UI itself. This will set the Swagger `defaultValue` to the provided value. Note that the example value will override the Grape default value. - - - ```ruby - - params do - requires :id, type: Integer, desc: 'Coffee ID' - optional :temperature, type: Integer, desc: 'Temperature of the coffee in celcius', default: 72 - end - - ``` - - - ### Setting `additionalProperties` for `object`-type parameters - - - Use the `additional_properties` option in the `documentation` hash for `object`-type parameters to set [`additionalProperties`](https://swagger.io/specification/v2/#model-with-mapdictionary-properties). - - - #### Allow any additional properties - - ```ruby - - params do - optional :thing, type: Hash, documentation: { additional_properties: true } - end - - ``` - - - #### Allow any additional properties of a particular type - - ```ruby - - params do - optional :thing, type: Hash, documentation: { additional_properties: String } - end - - ``` - - - #### Allow any additional properties matching a defined schema - - ```ruby - - class Entity < Grape::Entity - expose :this - end - - - params do - optional :thing, type: Hash, documentation: { additional_properties: Entity } - end - - ``` - - - - #### Example parameter value - - - The example parameter will populate the Swagger UI with the example value, and can be used for optional or required parameters. - - - ```ruby - - params do - requires :id, type: Integer, documentation: { example: 123 } - optional :name, type: String, documentation: { example: 'Buddy Guy' } - end - - ``` - - - #### Expose nested namespace as standalone route - - - Use the `nested: false` property in the `swagger` option to make nested namespaces appear as standalone resources. - - This option can help to structure and keep the swagger schema simple. - - - ```ruby - - namespace 'store/order', desc: 'Order operations within a store', swagger: { nested: false } do - get :order_id do - ... - end - end - - ``` - - - All routes that belong to this namespace (here: the `GET /order_id`) will then be assigned to the `store_order` route instead of the `store` resource route. - - - It is also possible to expose a namespace within another already exposed namespace: - - - ```ruby - - namespace 'store/order', desc: 'Order operations within a store', swagger: { nested: false } do - get :order_id do - ... - end - namespace 'actions', desc: 'Order actions', nested: false do - get 'evaluate' do - ... - end - end - end - - ``` - - Here, the `GET /order_id` appears as operation of the `store_order` resource and the `GET /evaluate` as operation of the `store_orders_actions` route. - - - - ##### With a custom name - - - Auto generated names for the standalone version of complex nested resource do not have a nice look. - - You can set a custom name with the `name` property inside the `swagger` option, but only if the namespace gets exposed as standalone route. - - The name should not contain whitespaces or any other special characters due to further issues within swagger-ui. - - - ```ruby - - namespace 'store/order', desc: 'Order operations within a store', swagger: { nested: false, name: 'Store-orders' } do - get :order_id do - ... - end - end - - ``` - - - - #### Response documentation - - - You can also document the HTTP status codes with a description and a specified model, as ref in the schema to the definitions, that your API returns with one of the following syntax. - - - In the following cases, the schema ref would be taken from route. - - - ```ruby - - desc 'thing', failure: [ { code: 400, message: 'Invalid parameter entry' } ] - - get '/thing' do - # ... - end - - ``` - - - ```ruby - - desc 'thing' do - params Entities::Something.documentation - failure [ { code: 400, message: 'Invalid parameter entry' } ] - end - - get '/thing' do - # ... - end - - ``` - - - ```ruby - - get '/thing', failure: [ - { code: 400, message: 'Invalid parameter entry' }, - { code: 404, message: 'Not authorized' }, - ] do - # ... - end - - ``` - - - By adding a `model` key, e.g. this would be taken. Setting an empty string will act like an empty body. - - ```ruby - - get '/thing', failure: [ - { code: 400, message: 'General error' }, - { code: 403, message: 'Forbidden error', model: '' }, - { code: 422, message: 'Invalid parameter entry', model: Entities::ApiError } - ] do - # ... - end - - ``` - - If no status code is defined [defaults](/lib/grape-swagger/endpoint.rb#L210) would be taken. - - - The result is then something like following: - - - ```json - - "responses": { - "200": { - "description": "get Horses", - "schema": { - "$ref": "#/definitions/Thing" - } - }, - "401": { - "description": "HorsesOutError", - "schema": { - "$ref": "#/definitions/ApiError" - } - } - }, - - ``` - - - - #### Changing default status codes - - - The default status codes, one could be found (-> [status codes](lib/grape-swagger/doc_methods/status_codes.rb)) can be changed to your specific needs, to achive it, you have to change it for grape itself and for the documentation. - - - ```ruby - - desc 'Get a list of stuff', - success: { code: 202, model: Entities::UseResponse, message: 'a changed status code' } - get do - status 202 - # your code comes here - end - - ``` - - - ```json - - "responses": { - "202": { - "description": "ok", - "schema": { - "$ref": "#/definitions/UseResponse" - } - } - }, - - ``` - - - #### Multiple status codes for response - - - Multiple values can be provided for `success` and `failure` attributes in the response. - - - ```ruby - - desc 'Attach a field to an entity through a PUT', - success: [ - { code: 201, model: Entities::UseResponse, message: 'Successfully created' }, - { code: 204, message: 'Already exists' } - ], - failure: [ - { code: 400, message: 'Bad request' }, - { code: 404, message: 'Not found' } - ] - put do - # your code comes here - end - - ``` - - - ```json - - "responses": { - "201": { - "description": "Successfully created", - "schema": { - "$ref": "#/definitions/UseResponse" - } - }, - "204": { - "description": "Already exists" - }, - "400": { - "description": "Bad request" - }, - "404": { - "description": "Not found" - } - }, - - ``` - - - - #### File response - - - Setting `success` to `File` sets a default `produces` of `application/octet-stream`. - - - ```ruby - - desc 'Get a file', - success: File - get do - # your file response - end - - ``` - - - ```json - - "produces": [ - "application/octet-stream" - ], - - "responses": { - "200": { - "description": "Get a file", - "schema": { - "type": "file" - } - } - } - - ``` - - - #### Default response - - - By setting the `default` option you can also define a default response that is the result returned for all unspecified status codes. - - The definition supports the same syntax as `success` or `failure`. - - - In the following cases, the schema ref would be taken from route. - - - ```ruby - - desc 'thing', default: { message: 'the default response' } - - get '/thing' do - # ... - end - - ``` - - The generated swagger section will be something like - - - ```json - - "responses": { - "default": { - "description": "the default response" - } - }, - - ``` - - Just like with `success` or `failure` you can also provide a `model` parameter. - - - ```ruby - - desc 'Get a list of stuff', - default: { model: Entities::UseResponse, message: 'the default response' } - get do - # your code comes here - end - - ``` - - The generated swagger document will then correctly reference the model schema. - - - ```json - - "responses": { - "default": { - "description": "the default response", - "schema": { - "$ref": "#/definitions/UseResponse" - } - } - }, - - ``` - - - - #### Extensions - - - Swagger spec2.0 supports extensions on different levels, for the moment, - - the documentation on the root level object and the `info`, `verb`, `path` and `definition` levels are supported. - - - The documented key would be generated from the `x` + `-` + key of the submitted hash, - - for possibilities refer to the [extensions spec](spec/lib/extensions_spec.rb). - - To get an overview *how* the extensions would be defined on grape level, see the following examples: - - - - root object extension, add a `x` key to the root hash when calling ```add_swagger_documentation```: - - ```ruby - add_swagger_documentation \ - x: { - some: 'stuff' - }, - info: { - } - ``` - - this would generate: - - ```json - - { - "x-some": "stuff", - "info":{ - } - } - - ``` - - - - `info` extension, add a `x` key to the `info` hash when calling ```add_swagger_documentation```: - - ```ruby - add_swagger_documentation \ - info: { - x: { some: 'stuff' } - } - ``` - - this would generate: - - ```json - - "info":{ - "x-some":"stuff" - } - - ``` - - - - `verb` extension, add a `x` key to the `desc` hash: - - ```ruby - - desc 'This returns something with extension on verb level', - x: { some: 'stuff' } - ``` - - this would generate: - - ```json - - "/path":{ - "get":{ - "…":"…", - "x-some":"stuff" - } - } - - ``` - - - - `operation` extension, by setting via route settings:: - - ```ruby - - route_setting :x_operation, { some: 'stuff' } - - ``` - - this would generate: - - ```json - - "/path":{ - "get":{ - "…":"…", - "x-some":"stuff" - } - } - - ``` - - - - `path` extension, by setting via route settings: - - ```ruby - - route_setting :x_path, { some: 'stuff' } - - ``` - - this would generate: - - ```json - - "/path":{ - "x-some":"stuff", - "get":{ - "…":"…", - } - } - - ``` - - - - `definition` extension, again by setting via route settings, - - here the status code must be provided, for which definition the extensions should be: - - ```ruby - - route_setting :x_def, { for: 422, other: 'stuff' } - - ``` - - this would generate: - - ```json - - "/definitions":{ - "ApiError":{ - "x-other":"stuff", - "…":"…", - } - } - - ``` - - or, for more definitions: - - ```ruby - - route_setting :x_def, [{ for: 422, other: 'stuff' }, { for: 200, some: 'stuff' }] - - ``` - - - - `params` extension, add a `x` key to the `documentation` hash : - - ```ruby - - requires :foo, type: String, documentation: { x: { some: 'stuff' } } - - ``` - - this would generate: - - ```json - - { - "in": "formData", - "name": "foo", - "type": "string", - "required": true, - "x-some": "stuff" - } - - ``` - - - #### Response examples documentation - - - You can also add examples to your responses by using the `desc` DSL with block syntax. - - - By specifying examples to `success` and `failure`. - - - ```ruby - - desc 'This returns examples' do - success model: Thing, examples: { 'application/json' => { description: 'Names list', items: [{ id: '123', name: 'John' }] } } - failure [[404, 'NotFound', ApiError, { 'application/json' => { code: 404, message: 'Not found' } }]] - end - - get '/thing' do - ... - end - - ``` - - - The result will look like following: - - - ```json - "responses": { - "200": { - "description": "This returns examples", - "schema": { - "$ref": "#/definitions/Thing" - }, - "examples": { - "application/json": { - "description": "Names list", - "items": [ - { - "id": "123", - "name": "John" - } - ] - } - } - }, - "404": { - "description": "NotFound", - "schema": { - "$ref": "#/definitions/ApiError" - }, - "examples": { - "application/json": { - "code": 404, - "message": "Not found" - } - } - } - } - ``` - - - Failure information can be passed as an array of arrays or an array of hashes. - - - #### Response headers documentation - - - You can also add header information to your responses by using the `desc` DSL with block syntax. - - - By specifying headers to `success` and `failure`. - - - ```ruby - - desc 'This returns headers' do - success model: Thing, headers: { 'Location' => { description: 'Location of resource', type: 'string' } } - failure [[404, 'NotFound', ApiError, { 'application/json' => { code: 404, message: 'Not found' } }, { 'Date' => { description: 'Date of failure', type: 'string' } }]] - end - - get '/thing' do - ... - end - - ``` - - - The result will look like following: - - - ```json - "responses": { - "200": { - "description": "This returns examples", - "schema": { - "$ref": "#/definitions/Thing" - }, - "headers": { - "Location": { - "description": "Location of resource", - "type": "string" - } - } - }, - "404": { - "description": "NotFound", - "schema": { - "$ref": "#/definitions/ApiError" - }, - "examples": { - "application/json": { - "code": 404, - "message": "Not found" - } - }, - "headers": { - "Date": { - "description": "Date of failure", - "type": "string" - } - } - } - } - ``` - - - Failure information can be passed as an array of arrays or an array of hashes. - - - #### Adding root element to responses - - - You can specify a custom root element for a successful response: - - - ```ruby - - route_setting :swagger, root: 'cute_kitten' - - desc 'Get a kitten' do - http_codes [{ code: 200, model: Entities::Kitten }] - end - - get '/kittens/:id' do - - end - - ``` - - - The result will look like following: - - - ```json - "responses": { - "200": { - "description": "Get a kitten", - "schema": { - "type": "object", - "properties": { "cute_kitten": { "$ref": "#/definitions/Kitten" } } - } - } - } - ``` - - - If you specify `true`, the value of the root element will be deduced based on the model name. - - E.g. in the following example the root element will be "kittens": - - - ```ruby - - route_setting :swagger, root: true - - desc 'Get kittens' do - is_array true - http_codes [{ code: 200, model: Entities::Kitten }] - end - - get '/kittens' do - - end - - ``` - - - The result will look like following: - - - ```json - "responses": { - "200": { - "description": "Get kittens", - "schema": { - "type": "object", - "properties": { "type": "array", "items": { "kittens": { "$ref": "#/definitions/Kitten" } } } - } - } - } - ``` - - #### Multiple present Response - - - You can specify a custom multiple response by using the `as` key: - - ```ruby - - desc 'Multiple response', - success: [ - { model: Entities::EnumValues, as: :gender }, - { model: Entities::Something, as: :somethings } - ] - end - - - get '/things' do - ... - end - - ``` - - The result will look like following: - - ```json - "responses": { - "200": { - "description": "Multiple response", - "schema":{ - "type":"object", - "properties":{ - "gender":{ - "$ref":"#/definitions/EnumValues" - }, - "somethings":{ - "$ref":"#/definitions/Something" - } - } - } - } - } - ``` - - You can also specify if the response is an array, with the `is_array` key: - - ```ruby - - desc 'Multiple response with array', - success: [ - { model: Entities::EnumValues, as: :gender }, - { model: Entities::Something, as: :somethings, is_array: true, required: true } - ] - end - - - get '/things' do - ... - end - - ``` - - The result will look like following: - - ```json - "responses": { - "200": { - "description": "Multiple response with array", - "schema":{ - "type":"object", - "properties":{ - "gender":{ - "$ref":"#/definitions/EnumValues" - }, - "somethings":{ - "type":"array", - "items":{ - "$ref":"#/definitions/Something" - } - } - }, - "required": ["somethings"] - } - } - } - ``` - - - ## Using Grape Entities - - - Add the [grape-entity](https://github.com/ruby-grape/grape-entity) and [grape-swagger-entity](https://github.com/ruby-grape/grape-swagger-entity) gem to your Gemfile. - - - The following example exposes statuses. And exposes statuses documentation adding :type, :desc and :required. - - The documented class/definition name could be set via `#entity_name`. - - - ```ruby - - module API - module Entities - class Status < Grape::Entity - expose :text, documentation: { type: 'string', desc: 'Status update text.', required: true } - expose :links, using: Link, documentation: { type: 'link', is_array: true } - expose :numbers, documentation: { type: 'integer', desc: 'favourite number', values: [1,2,3,4] } - end - - class Link < Grape::Entity - expose :href, documentation: { type: 'url' } - expose :rel, documentation: { type: 'string'} - - def self.entity_name - 'LinkedStatus' - end - - end - end - - class Statuses < Grape::API - version 'v1' - - desc 'Statuses index', - entity: API::Entities::Status - get '/statuses' do - statuses = Status.all - type = current_user.admin? ? :full : :default - present statuses, with: API::Entities::Status, type: type - end - - desc 'Creates a new status', - entity: API::Entities::Status, - params: API::Entities::Status.documentation - post '/statuses' do - ... - end - end - end - - ``` - - - - ### Relationships - - - You may safely omit `type` from relationships, as it can be inferred. However, if you need to specify or override it, use the full name of the class leaving out any modules named `Entities` or `Entity`. - - - - #### 1xN - - - ```ruby - - module API - module Entities - class Client < Grape::Entity - expose :name, documentation: { type: 'string', desc: 'Name' } - expose :addresses, using: Entities::Address, - documentation: { type: 'Entities::Address', desc: 'Addresses.', param_type: 'body', is_array: true } - end - - class Address < Grape::Entity - expose :street, documentation: { type: 'string', desc: 'Street.' } - end - end - - class Clients < Grape::API - version 'v1' - - desc 'Clients index', - params: Entities::Client.documentation, - success: Entities::Client - get '/clients' do - ... - end - end - - add_swagger_documentation - end - - ``` - - - - #### 1x1 - - - Note: `is_array` is `false` by default. - - - ```ruby - - module API - module Entities - class Client < Grape::Entity - expose :name, documentation: { type: 'string', desc: 'Name' } - expose :address, using: Entities::Address, - documentation: { type: 'Entities::Address', desc: 'Addresses.', param_type: 'body', is_array: false } - end - - class Address < Grape::Entity - expose :street, documentation: { type: 'string', desc: 'Street' } - end - end - - class Clients < Grape::API - version 'v1' - - desc 'Clients index', - params: Entities::Client.documentation, - success: Entities::Client - get '/clients' do - ... - end - end - - add_swagger_documentation - end - - ``` - - - #### Inheritance with allOf and discriminator - - ```ruby - - module Entities - class Pet < Grape::Entity - expose :type, documentation: { - type: 'string', - is_discriminator: true, - required: true - } - expose :name, documentation: { - type: 'string', - required: true - } - end - - class Cat < Pet - expose :huntingSkill, documentation: { - type: 'string', - description: 'The measured skill for hunting', - default: 'lazy', - values: %w[ - clueless - lazy - adventurous - aggressive - ] - } - end - end - - ``` - - - Should generate this definitions: - - ```json - - { - "definitions": { - "Pet": { - "type": "object", - "discriminator": "petType", - "properties": { - "name": { - "type": "string" - }, - "petType": { - "type": "string" - } - }, - "required": [ - "name", - "petType" - ] - }, - "Cat": { - "description": "A representation of a cat", - "allOf": [ - { - "$ref": "#/definitions/Pet" - }, - { - "type": "object", - "properties": { - "huntingSkill": { - "type": "string", - "description": "The measured skill for hunting", - "default": "lazy", - "enum": [ - "clueless", - "lazy", - "adventurous", - "aggressive" - ] - }, - "petType": { - "type": "string", - "enum": ["Cat"] - } - }, - "required": [ - "huntingSkill", - "petType" - ] - } - ] - } - } - } - - ``` - - - - - - ## Securing the Swagger UI - - - The Swagger UI on Grape could be secured from unauthorized access using any middleware, which provides certain methods: - - - - some guard method, which could receive as argument a string or an array of authorization scopes; - - - a *before* method to be run in the Grape controller for authorization purpose; - - - a set of methods which will process the access token received in the HTTP request headers (usually in the - - 'HTTP_AUTHORIZATION' header) and try to return the owner of the token. - - - Below are some examples of securing the Swagger UI on Grape installed along with Ruby on Rails: - - - - The WineBouncer and Doorkeeper gems are used in the examples; - - - 'rails' and 'wine_bouncer' gems should be required prior to 'grape-swagger' in boot.rb; - - - This works with a fresh PR to WineBouncer which is yet unmerged - [WineBouncer PR](https://github.com/antek-drzewiecki/wine_bouncer/pull/64). - - - This is how to configure the grape_swagger documentation: - - - ```ruby - add_swagger_documentation base_path: '/', - title: 'My API', - doc_version: '0.0.1', - hide_documentation_path: true, - endpoint_auth_wrapper: WineBouncer::OAuth2, # This is the middleware for securing the Swagger UI - swagger_endpoint_guard: 'oauth2 false', # this is the guard method and scope - token_owner: 'resource_owner' # This is the method returning the owner of the token - ``` - - - The guard method should inject the Security Requirement Object into the endpoint's route settings (see Grape::DSL::Settings.route_setting method). - - - The 'oauth2 false' added to swagger_documentation is making the main Swagger endpoint protected with OAuth, i.e. the - - access_token is being retreiving from the HTTP request, but the 'false' scope is for skipping authorization and - - showing the UI for everyone. If the scope would be set to something else, like 'oauth2 admin', for example, than the UI - wouldn't be displayed at all to unauthorized users. - - Further on, the guard could be used, where necessary, for endpoint access protection. Put it prior to the endpoint's method: - - - ```ruby - resource :users do - oauth2 'read, write' - get do - render_users - end - - oauth2 'admin' - post do - User.create!... - end - end - ``` - - - And, finally, if you want to not only restrict the access, but to completely hide the endpoint from unauthorized - - users, you could pass a lambda to the :hidden key of a endpoint's description: - - - ```ruby - not_admins = lambda { |token_owner = nil| token_owner.nil? || !token_owner.admin? } - - resource :users do - desc 'Create user', hidden: not_admins - oauth2 'admin' - post do - User.create!... - end - end - ``` - - - The lambda is checking whether the user is authenticated (if not, the token_owner is nil by default), and has the admin - - role - only admins can see this endpoint. - - - - - ## Example - - - Go into example directory and run it: `$ bundle exec rackup` - - go to: `http://localhost:9292/swagger_doc` to get it - - - For request examples load the [postman file]() - - - #### Grouping the API list using Namespace - - - Use namespace for grouping APIs - - - ![grape-swagger-v2-new-corrected](https://cloud.githubusercontent.com/assets/1027590/13516020/979cfefa-e1f9-11e5-9624-f4a6b17a3c8a.png) - - - #### Example Code - - - ```ruby - - class NamespaceApi < Grape::API - namespace :hudson do - desc 'Document root' - get '/' do - end - - desc 'This gets something.', - detail: '_test_' - - get '/simple' do - { bla: 'something' } - end - end - - namespace :download do - desc 'download files', - success: File, - produces: ['text/csv'] - get ':id' do - # file response - end - end - end - … - - ``` - - - - - ## Rake Tasks - - - Add these lines to your Rakefile, and initialize the Task class with your Api class. - - - ```ruby - - require 'grape-swagger/rake/oapi_tasks' - - GrapeSwagger::Rake::OapiTasks.new(::Api::Base) - - ``` - - - You may initialize with the class name as a string if the class is not yet loaded at the time Rakefile is parsed: - - ```ruby - - require 'grape-swagger/rake/oapi_tasks' - - GrapeSwagger::Rake::OapiTasks.new('::Api::Base') - - ``` - - - #### OpenApi/Swagger Documentation - - - ``` - - rake oapi:fetch - - params: - - - store={ true | file_name.json } – save as JSON (optional) - - - resource=resource_name – get only for this one (optional) - - ``` - - For mutliversion API it creates several files with following naming: file_name_`API_VERSION`.json - - - #### OpenApi/Swagger Validation - - - **requires**: `npm` and `swagger-cli` to be installed - - - - ``` - - rake oapi:validate - - params: - - - resource=resource_name – get only for this one (optional) - - ``` - - - - ## Contributing to grape-swagger - - - See [CONTRIBUTING](CONTRIBUTING.md). - - - ## Copyright and License - - - Copyright (c) 2012-2016 Tim Vandecasteele, ruby-grape and contributors. See [LICENSE.txt](LICENSE.txt) for details. -apigee-127/swagger-tools: > - The project provides various tools for integrating and - interacting with Swagger. This project is in its infancy but - - what is within the repository should be fully tested and reusable. Please visit the [issue tracker][project-issues] to - - see what issues we are aware of and what features/enhancements we are working on. Otherwise, feel free to review the - - [Release Notes][release-notes] to see what is new and improved. - - - ## Project Badges - - - [![Join the chat at https://gitter.im/apigee-127/swagger-tools](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/apigee-127/swagger-tools?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - - - * Dependencies: [![Dependencies](https://david-dm.org/apigee-127/swagger-tools.svg)](https://david-dm.org/apigee-127/swagger-tools) - - * Developer dependencies: [![Dev Dependencies](https://david-dm.org/apigee-127/swagger-tools/dev-status.svg)](https://david-dm.org/apigee-127/swagger-tools#info=devDependencies&view=table) - - * Downloads: [![NPM Downloads Per Month](http://img.shields.io/npm/dm/swagger-tools.svg?style=flat)](https://www.npmjs.org/package/swagger-tools) - - * License: [![License](http://img.shields.io/npm/l/swagger-tools.svg?style=flat)](https://github.com/apigee-127/swagger-tools/blob/master/LICENSE) - - * Bower Version [![NPM Version](https://img.shields.io/bower/v/swagger-tools.svg?style=flat)](http://bower.io/search/?q=swagger-tools) - - * NPM Version: [![NPM Version](http://img.shields.io/npm/v/swagger-tools.svg?style=flat)](https://www.npmjs.org/package/swagger-tools) - - - ## Supported Swagger Versions - - - * [1.2][swagger-docs-v1_2] - - * [2.0][swagger-docs-v2_0] - - - ## Features - - - * Simple CLI - * Validate Swagger document(s) - * Convert Swagger 1.2 documents to Swagger 2.0 - * Schema validation: For the file(s) supported by the Swagger specification, ensure they pass structural validation - - based on the [JSON Schema][json-schema] associated with that version of the specification _(Browser and Node)_ - - * Semantic validation: Validates Swagger files above and beyond the structure of the file _(Browser and Node)_ - - * Connect middleware for adding pertinent Swagger information to your requests _(Node only)_ - - * Connect middleware for wiring up security handlers for requests based on Swagger documentation _(Node only)_ - - * Connect middleware for wiring request handlers to requests based on Swagger documentation _(Node only)_ - - * Connect middleware for serving your Swagger documents and [Swagger UI][swagger-ui] _(Node only)_ - - * Connect middleware for using Swagger resource documents for pre-route validation _(Node only)_ - * Validate the request/response Content-Type based on the operation's `consumes/produces` value(s) - * Validate the request parameter types - * Validate the request parameter values - * Validate the response values - - ## Installation - - - Swagger Tools is available for both Node.js and the browser. Installation instructions for each environment are below. - - - ### Browser - - - Installation for browser applications can be done via [Bower][bower] or by downloading a standalone binary. - - - #### Using Bower - - - ``` - - bower install swagger-tools --save - - ``` - - - #### Standalone Binaries - - - The standalone binaries come in two flavors: - - - * [swagger-tools-standalone.js](https://raw.github.com/apigee-127/swagger-tools/master/browser/swagger-tools-standalone.js): _2,280kb_, full source _(including all dependencies)_ and source maps - - * [swagger-tools-standalone-min.js](https://raw.github.com/apigee-127/swagger-tools/master/browser/swagger-tools-standalone-min.js): _316kb_, minified, compressed - - and no sourcemap - - - ### Node.js - - - Installation for Node.js applications can be done via [NPM][npm]. - - - ``` - - npm install swagger-tools --save - - ``` - - - If you want to use the `swagger-tools` executable for validating Swagger documents, you can install swagger-tools - - globally using the following: - - - ``` - - npm install -g swagger-tools - - ``` - - - ## Documentation - - - swagger-tools is heavily documented so head on over to the project [documentation][documentation] or jump straight to - - the [Quick Start][quick-start]. - - - ## Contributing - - - This project uses [Gulp][gulp] for building so `npm install -g gulp` once you clone this project. Running `gulp` in the - - project root will lint check the source code and run the unit tests. - - - [bower]: http://bower.io/ - - [documentation]: https://github.com/apigee-127/swagger-tools/blob/master/docs/README.md - - [gulp]: http://gulpjs.com/ - - [json-schema]: http://json-schema.org/ - - [npm]: https://www.npmjs.org/ - - [project-issues]: https://github.com/apigee/swagger-tools/issues - - [quick-start]: https://github.com/apigee-127/swagger-tools/blob/master/docs/QuickStart.md - - [release-notes]: https://github.com/apigee-127/swagger-tools/blob/master/RELEASE_NOTES.md - - [swagger]: http://swagger.io/ - - [swagger-docs-v1_2]: https://github.com/swagger-api/swagger-spec/blob/master/versions/1.2.md - - [swagger-docs-v2_0]: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md - - [swagger-ui]: https://github.com/swagger-api/swagger-ui -metosin/fnhouse-swagger: > - # fnhouse-swagger - - - [![Build Status](https://travis-ci.org/metosin/fnhouse-swagger.svg?branch=master)](https://travis-ci.org/metosin/fnhouse-swagger) - - [![Dependencies Status](http://jarkeeper.com/metosin/fnhouse-swagger/status.png)](http://jarkeeper.com/metosin/fnhouse-swagger) - - - [Swagger](https://helloreverb.com/developers/swagger) implementation - - for [fnhouse](https://github.com/Prismatic/fnhouse) using the - - [Ring-swagger](https://github.com/metosin/ring-swagger). Supports both 1.2 and 2.0 versions of the spec. - - - This is an alpha release, like fnhouse itself. - - - ## Latest version - - - [![Clojars Project](http://clojars.org/metosin/fnhouse-swagger/latest-version.svg)](http://clojars.org/metosin/fnhouse-swagger) - - - [Release notes](https://github.com/metosin/fnhouse-swagger/releases) - - - ## Usage - - - - create proto-handlers also from `fnhouse.swagger` namespace - - - call `collect-routes` to get ring-swagger map of handlers - - - assoc the map to key `:swagger` into the plumbing resource map - - - to use the embedded [swagger-ui](https://github.com/wordnik/swagger-ui), - - add a dependency to latest [ring-swagger-ui](https://github.com/metosin/ring-swagger-ui) - - and add add a ring-route `swagger-ui` to your app. - - - ## Examples - - - Guesthouse with fnhouse-swagger is found [here](https://github.com/metosin/fnhouse-swagger/tree/master/examples/guesthouse). - - - Running the example: - - - ```bash - - git clone https://github.com/metosin/fnhouse-swagger.git - - cd fnhouse-swagger/examples/guesthouse/src - - lein repl - - > (use 'guesthouse.core) - - > (start) - - ``` - - - - ## License - - - Copyright © 2014-2015 [Metosin Oy](http://www.metosin.fi) - - - Distributed under the Eclipse Public License, the same as Clojure. -yonaskolb/SwagGen: > - # SwagGen - - - ![Platforms](https://img.shields.io/badge/platforms-Linux%20%7C%20macOS-blue.svg?style=for-the-badge) - - [![SPM](https://img.shields.io/badge/spm-compatible-brightgreen.svg?style=for-the-badge)](https://swift.org/package-manager) - - [![Git Version](https://img.shields.io/github/release/yonaskolb/swaggen.svg?style=for-the-badge)](https://github.com/yonaskolb/SwagGen/releases) - - [![license](https://img.shields.io/github/license/yonaskolb/SwagGen.svg?style=for-the-badge)](https://github.com/yonaskolb/SwagGen/blob/master/LICENSE) - - - SwagGen is a library and command line tool for parsing and generating code for [OpenAPI/Swagger 3.0](https://swagger.io/specification) specs, completely written in Swift. - - - > Swagger 2 support has been removed. For Swagger 2 use version `3.0.2` or the `swagger_2` branch - - - #### Swagger parser - - It contains a `Swagger` library that can be used in Swift to load and parse Swagger specs. - - - #### Swagger code generator - - `SwagGen` is command line tool that generates code from a [OpenAPI/Swagger 3.0](https://swagger.io/specification) spec. - - Templates for any language can be written that leverage this generator. - - - #### Swift template - - `SwagGen` includes a bundled template for generating a client side Swift library for interfacing with the Swagger spec. It includes support for model inheritance, shared enums, discrete and mutable request objects, inline schemas, Codable and Equatable models, configurable options, generic networking stack, and many other niceties. - - - ## Installing - - Make sure Xcode 11+ is installed first. - - - ### [Mint](https://github.com/yonaskolb/mint) - - ```sh - - $ mint install yonaskolb/SwagGen - - ``` - - ### Homebrew - - - ```sh - - $ brew tap yonaskolb/SwagGen https://github.com/yonaskolb/SwagGen.git - - $ brew install SwagGen - - ``` - - - ### Make - - - ```sh - - $ git clone https://github.com/yonaskolb/SwagGen.git - - $ cd SwagGen - - $ make install - - ``` - - - ### Swift Package Manager - - - #### Use as CLI - - - ```sh - - $ git clone https://github.com/yonaskolb/SwagGen.git - - $ cd swaggen - - $ swift run - - ``` - - - #### Use as dependency - - - Add the following to your Package.swift file's dependencies: - - - ```swift - - .package(url: "https://github.com/yonaskolb/SwagGen.git", from: "4.4.0"), - - ``` - - - And then import wherever needed: - - - ```swift - - import SwagGenKit - - import Swagger - - ``` - - - ## Usage - - - Use `--help` to see usage information - - - ``` - - swaggen --help - - Usage: swaggen [options] - - - Commands: - generate Generates a template from a Swagger spec - help Prints this help information - version Prints the current version of this app - ``` - - - ### generate - - - ```sh - - swaggen generate path_to_spec - - ``` - - - Use `swaggen generate --help` to see the list of generation options. - - - - **spec**: This is the path to the Swagger spec and is a required parameter. It can either be a file path or a web url to a YAML or JSON file - - - **--language**: The language to generate a template for. This defaults to `swift` for now. - - - **--template**:: This is the path to the template config yaml file. It can either be a direct path to the file, or a path to the parent directory which will by default look for `/template.yml`. If this is not passed, the default template for the language will be used. - - - **--destination**: The directory that the generated files will be added to. - - - **--option**: An option that will be merged with the template config options with those in this argument taking precedence, meaning any existing options of the same name will be overwritten. This argument can be repeated to pass in multiple options. Options must specify the option name and option value separated by a colon, with any spaces contained in quotes. Nested options in dictionaries can be set by using a dot syntax. The following formats are allowed: - - `-- option myOption:myValue` - - `-- option modelSuffix: Model` - - `-- option propertyNames.identifier: id` - - `-- option "myOption: my value"` - - - **--clean**: Controls if and how the destination directory is cleaned of non generated files. Options are: - - `none`: no files are removed (default) - - `all`: all other files are removed - - `leave.files`: all files and directories except those that start with `.` in the destination directory are removed. This is useful for keeping configuration files and directories such as `.git` around, while still making sure that items removed from the spec are removed from the generated API. - - **--verbose**: Show more verbose output - - - **--silent**: Silences any standard output. Errors will still be shown - - - Example: - - - ``` - - swaggen generate http://myapi.com/spec --template Templates/Swift --destination generated --option name:MyAPI --option "customProperty: custom value --clean leave.files" - - ``` - - - For the Swift template, a handy option is `name`, which changes the name of the generated framework from the default of `API`. This can be set in the template or by passing in `--option name:MyCoolAPI`. - - - - ### Swift Template - - - List of all available options: - - - name | action | expected values | default value - - --- | --- | --- | --- - - name | name of the API | `String` | API - - authors | authors in podspec | `String` | Yonas Kolb - - baseURL | baseURL in APIClient | `String` | first scheme, host, and base path of spec - - fixedWidthIntegers | whether to use types like Int32 and Int64 | `Bool` | false - - homepage | homepage in podspec | `String` | https://github.com/yonaskolb/SwagGen - - modelPrefix | model by adding a prefix and model file name | `String` | null - - modelSuffix | model by adding a suffix and model file name | `String` | null - - mutableModels | whether model properties are mutable | `Bool` | true - - modelType | whether each model is a `struct` or `class` | `String` | class - - modelInheritance | whether models use inheritance. Must be false for structs | Bool | true - - modelNames | override model names | `[String: String]` | [:] - - modelProtocol | customize protocol name that all models conform to | `String` | APIModel - - enumNames | override enum names | `[String: String]` | [:] - - enumUndecodableCase | whether to add undecodable case to enums | `Bool` | false - - propertyNames | override property names | `[String: String]` | [:] - - safeArrayDecoding | filter out invalid items in array instead of throwing | `Bool` | false - - safeOptionalDecoding | set invalid optionals to nil instead of throwing | `Bool` | false - - tagPrefix | prefix for all tags | `String` | null - - tagSuffix | suffix for all tags | `String` | null - - codableResponses | constrains all responses to be `Codable` | `Bool` | false - - anyType | override `Any` with custom type | `String` | `Any` - - numberType | override default number type when format not specified | `String` | `Double` - - - If writing your own Swift template there are a few types that are generated that you will need to provide typealias's for: - - - - `ID`: The `UUID` format. Usually `UUID` or `String` - - - `File`: The `file` format. Usually `URL`, `Data` or a custom type with a mimeType and fileName - - - `DateTime`: The `date-time` format. Usually `Date` - - - `DateDay`: The `date` format. Usually `Date` or a custom type. - - - ## Development - - If you want to pass any required arguments when running in Xcode, you can edit the scheme to include launch arguments. - - - ## Templates - - Templates are made up of a template config file, a bunch of **Stencil** files, and other files that will be copied over during generation - - - ### Template config - - This is the configuration and manifest file for the template in YAML or JSON format. It can contain: - - - - **formatter**: Optional formatter to use. This affects what properties are available in the templates and how they are formatted e.g. `Swift` - - - **templateFiles**: a list of template files. These can each have their paths, contents and destination directories modified through Stencil tags. One template file can also output to multiple files if they path is changed depending on a list context. Each file contains: - - **path**: relative path to the template config. The extension is usually .stencil or the type it is going to end up as - - **context**: optional context within the spec. This is provided to the generated file, otherwise the full context will be passed. If this is a list then a file will be created for each object and the context within that list is used. (e.g. a file for every model in the spec `definitions` gets it's own definition context). Note that properties in the template `options` field can be used here - - **destination**: optional destination path. This can contain stencil tags whose context is that from the context above. e.g. if context was `definitions` then the path could be `Models/{{ type }}.swift` and the filename would be the type of the definition. If this is left out the destination will be the same as the path, relative to the final destination directory. If it resolves to an empty string it will be skipped and not generated. - - **copiedFiles**: this is an array of relative paths that will be copied to the destination. They can be files or directories. This is used for files that won't have their contents, filenames or paths changed. - - - **options**: these are the options passed into every stencil file and can be used to customize the template. These options are merged with the `options` argument, with the argument options taking precendance. These options can be references in template file paths and their contents. - - - An example template for Swift can be found [here](Templates/Swift/template.yml) - - - ### Template Files - - These files follow the **Stencil** file format outlined here [https://stencil.fuller.li](https://stencil.fuller.li) - - - ## Formatters - - Formatters change what information is available to the templates and how it's formatted. They can be specified via the `formatter` property in the template config. Usually these would map to a specific target language, but can be customized for different purposes. - - - ## Output Languages - - SwagGen can be used to generate code for any language. At the moment there is only a formatter and template for **Swift** - - - ## Swift API usage - - Usage documentation can be found in the [Readme](Templates/Swift/README.md) that is generated with your template. - - - --- - - - ## Attributions - - - This tool is powered by: - - - - [JSONUtilities](https://github.com/yonaskolb/JSONUtilities) - - - [Stencil](https://github.com/stencilproject/Stencil) - - - [StencilSwiftKit](https://github.com/SwiftGen/StencilSwiftKit) - - - [Spectre](https://github.com/kylef/Spectre) - - - [PathKit](https://github.com/kylef/PathKit) - - - [SwiftCLI](https://github.com/jakeheis/SwiftCLI) - - - [Yams](https://github.com/jpsim/Yams) - - - Thanks also to [Logan Shire](https://github.com/AttilaTheFun) and his initial work on [Swagger Parser](https://github.com/AttilaTheFun/SwaggerParser) - - - ## Alternatives - - - [swagger-codegen](https://github.com/swagger-api/swagger-codegen) - - - [CreateAPI](https://github.com/kean/CreateAPI) - - - [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator) - - - ## Contributions - - Pull requests and issues are welcome - - - ## License - - - SwagGen is licensed under the MIT license. See [LICENSE](LICENSE) for more info. -jolie/jester: > - # Jester (Jolie 1.6.0 Beta or greater required) - - Jester - the Jolie rEST routER (and related tools) - - - # tools/jolie2rest (Jolie 1.6.0 Beta or greater required) - - This tool allows for the creation of: - - - a declaration for the REST router in order to automatically publish an existing jolie microservice into the router - - - a Swagger interface which reports all the API published in the router - - - Usage: jolie jolie2rest.ol router_host [swagger_enable=true|false] [easy_interface=true|false] - - Ex: - - ``` - - jolie jolie2rest.ol localhost:8080 swagger_enable=true easy_interface=false - - ``` - - - It is worth noting that the parameter router_host identifies the location where the router is listening for, it does not represent the location of the target service. - - The tool will get the lits of the service to be analyzed from the file - - ``` - - service_list.txt - - ``` - - - Each line of the file service_list.txt represents a service to be analyzed, in particular the line syntax is: path of the ol file of the service , name of the input port to be analyzed - - EX: - - ``` - - ./demo/demo.ol, DEMO - - ``` - - - It is important to highlight that a microservice can have more than one inputPort with different operations declared in it. If more inputPorts must be analyzed, then a line for each of them must be reported into the file service_list.txt. - - - # REST annotations on the jolie interface - - In order to allow for the publishing of a jolie operation in a REST modality it is necessary to annotate each operation of the interfaces to be published as it follows: - - - ``` - - /**! @Rest: method=[post|get|put|delete] [,template=...]; */ - - ``` - - - where: - - * `/**! [...] */` are the tokens to be used for making the comment to be interpreted by the tool - - - * `@Rest:` is the token used for identify that the following operation must be imported as a REST method - - - * `method=` it specifies which kind of method must be used for the REST importing - - - * `template=` it specifies the template to be used for the given resource. It is worth noting that parameters must be specified within curl brackets as in the getOrders example in the demo folder. - - - Ex: - - ``` - - /**! @Rest: method=get, template=/orders/{userId}?maxItems={maxItems}; */ - - ``` - - In this case the request type of the getOrders operation is like it follows: - - ``` - - type GetOrdersRequest: void { - .userId: string - .maxItems: int - } - - ``` - - - The router automatically joins the parameters defined in the url {userId} and {maxItems} with the subnodes of the request message which have the same name. As an example the url: - - - ``` - - http://localhost:8080/DEMO/orders/homer?maxItems=10 - - ``` - - - it will trigger the invocation of the target microservice on the getOrders operation with the following request message: - - ``` - - .userId = "homer" - - .maxItems = 10 - - ``` - - - # output of the tool - - As output the tool produces a file called router_import.ol which must be copied inside the folder router in order to be automatically loaded by the router when it is run. Indeed, once copied router_import.ol into the folder router, it is sufficient to launch - - - ``` - - jolie router.ol - - ``` - - - for enabling the router. It is worth noting that the microservice published as a REST service into the router must running too. The router indeed, just interprets the REST requests message and forward them to the final microservice - - (which is the target microservice of the jolie2rest tool). - - - Options: - - - enable_swagger [ default = true ] - - This operation enables the creation of the related json swagger file which can be easily imported into Swagger (http://swagger.io/). Thanks to it, it is possible to invoke the rest apis from swagger. - - - - easy_interface [ default = false ] - - This modality allows for skipping the usage of the router. It is useful when the microservice already provides a http port where its operations are available. In such a case, the microservice is already able to receive json messages and reply with json messages. In these cases, only the swagger json file is created where all the operations are automatically converted into POST calls. No annotations and templates are required in these cases. - - WARNING: the http protocol of the microservice must define the follwing parameters: - - - ``` - - .response.headers.("Access-Control-Allow-Methods") = "POST,GET,OPTIONS"; - - .response.headers.("Access-Control-Allow-Origin") = "*"; - - .response.headers.("Access-Control-Allow-Headers") = "Content-Type" - - ``` - - - # Running the example - - Pre-requisite: - - Prepare a web application for running a local instance of a Swagger UI (http://swagger.io/swagger-ui/). If you want to use jolie, you could download Leonardo web server (https://github.com/jolie/leonardo) and put the content of the SwaggerUI inside the folder www. - - Then launch `jolie leonardo.ol` in a separate shell and get the index.html page from your browser. - - - The example: - - Go into folder tools and launch the following command: - - ``` - - jolie jolie2rest.ol localhost:8080 swagger_enable=true easy_interface=false - - ``` - - Copy the file `router_import.ol` into folder router. - - Copy the file swagger_DEMO.json in the folder where your SwaggerUI application can retrieve it. If you are using Leonardo just put it inside folder www. - - Go into the folder tools/demo and launch the demo microservice: - - ``` - - jolie demo.ol - - ``` - - Open a new shell, go into the router folder and launch the router: - - ``` - - jolie router.ol - - ``` - - Open the SwaggerUI application with your browser and put the URL for retrieving the file swagger_DEMO.json inside the explorer text field . If you are using Leonardo put `http://localhost:XXXX/swagger_DEMO.json`, where XXXX is the port you chose for Leonardo. - - - Try to call your REST jolie service using the SwaggerUI. - - - - # tools/jolie_stubs_from_swagger - - This tool allows for the creation of a jolie client for each path declared in a Swagger definition. - - Usage: - - ``` - - jolie jolie_stubs_from_swagger.ol url service_name output_folder - - ``` - - - where: - - - url is the url where the swagger definition can be retrieved - - - service_name is the name of the service represented by the swagger definition - - - output_folder is the name of the folder where all the files will be created - - - Example: - - ``` - - jolie jolie_stubs_from_swagger.ol http://petstore.swagger.io/v2/swagger.json petstore petstore - - ``` - - - Once executed the following files will be created in the output_folder: - - - outputPort.iol - - - list of all the clients (name_of_the_operation).ol - - - outputPort.iol contains the interface and the outputPort definition of the service described by the swagger definition. - - Such a file must be included in each microservice which aims at invoking the service described by the swagger definition. - - - In the example described above in the folder petstore it is possible to find the getOrderById.ol file. - - Try to open it and set the request message as: - - ``` - - with( request ) { - - .orderId = 8 - - }; - - ``` - - - Then run the command - - ``` - - jolie getOrderById.ol - - ``` - - and look at the reply printed out in the console. - - - NOTE: - - Only application/json APIs are enabled so far - - - #Router Admin - - The router comes with a router admin service which is executed together in order to allow for a remote administration of the router. In particular, the router admin exposes three operations: - - - getRegisteredResourceCollections: it returns the list of all the registered resource collections into the router; - - - addResourceCollection: it adds a resource collection into the router; - - - removeResourceCollection: it removes a resource collection from the router; - - - The resource collections are expressed by means of a jolie interface declaration where the - - REST api templates are described as in the previous section "REST annotations on the jolie interface". - - The fully description of the operations may be consulted in the file RouterAdminInterface.iol which is located in the sub-folder router_admin/public/interfaces. - - - In the sub-folder router_admin/scripts there are three client scripts which allows for the interaction with the router admin operations. - - - WARNING: every time a resource collection is modified, the router requires to be restarted in order to get the modifications. - - - #Available API list web application - - A web application which uses some libraries from Swagger UI (http://swagger.io/swagger-ui/) is exeecuted together with the router and the router admin. It automatically reads the registered resource collections and it provides the list into a web application located at port 9082 by default. - - Thus, if you execute the web application on your localhost the URL is: - - ``` - - http://localhost:9082 - - ``` - - - #Dockerization of the router - - Jester can be easily dockerized by exploiting the Dockerfile distributed together with the source code. In order to achieve it, docker must be previously installed in the host machine then just follow these steps: - - - go into folder router; - - - run the command `docker build -t jester .` which locally creates the docker image of jester; - - - run the command `docker run --name jester-cnt --net="host" -e JDEP_API_ROUTER="socket://127.0.0.1:9080" jester` to run the container starting from the image just created; - - - The option `--net="host"` will allow the container to directly exploit the network of the host machine. If you want to limit the port exposition, remember that jester requires three main ports: - - - 9080: it is the http port of the router, all the REST APIs are available on it - - - 9081: it is the sodep port of the router admin, if you want to add, remove or get the list of the registered resource collections, you need to use it - - - 9082: it is the http port of the API list web application - - - The environment variable JDEP_API_ROUTER must be set to the location of the router as it is addressed from a final user, thus put the external IP and the exposed port number. -Yelp/bravado-core: > - .. image:: - https://github.com/Yelp/bravado-core/workflows/build/badge.svg?branch=master - :target: https://github.com/Yelp/bravado-core/actions?query=workflow%3Abuild - - .. image:: https://img.shields.io/coveralls/Yelp/bravado-core.svg - :target: https://coveralls.io/r/Yelp/bravado-core - - .. image:: https://img.shields.io/pypi/v/bravado-core.svg - :target: https://pypi.python.org/pypi/bravado-core/ - :alt: PyPi version - - .. image:: https://img.shields.io/pypi/pyversions/bravado_core.svg - :target: https://pypi.python.org/pypi/bravado-core/ - :alt: Supported Python versions - - bravado-core - - ============ - - - About - - ----- - - - bravado-core is a Python library that adds client-side and server-side support - - for the `OpenAPI Specification v2.0 `__. - - - Features - - -------- - - * OpenAPI Specification schema validation - - * Marshaling, transformation, and validation of requests and responses - - * Models as Python classes or dicts - - * Custom formats for type conversion - - - Documentation - - ------------- - - - Documentation is available at `readthedocs.org `__ - - - - Installation - - ------------ - - - :: - - $ pip install bravado-core - - - Related Projects - - ---------------- - - * `bravado `__ - - * `pyramid-swagger `__ - - * `swagger-spec-validator `__ - - - Development - - =========== - - - | Code is documented using `Sphinx `__. - - | `virtualenv `__ is recommended to keep dependencies and libraries isolated. - - | `tox `__ is used for standardized testing. - - - Setup - - ----- - - - :: - - # Run tests - tox - - # Install git pre-commit hooks - .tox/py27/bin/pre-commit install - - - Contributing - - ------------ - - - 1. Fork it ( http://github.com/Yelp/bravado-core/fork ) - - 2. Create your feature branch (``git checkout -b my-new-feature``) - - 3. Add your modifications - - 4. Add short summary of your modifications on ``CHANGELOG.rst`` - - 5. Commit your changes (``git commit -m "Add some feature"``) - - 6. Push to the branch (``git push origin my-new-feature``) - - 7. Create new Pull Request - - - License - - ------- - - - | Copyright (c) 2013, Digium, Inc. All rights reserved. - - | Copyright (c) 2014-2015, Yelp, Inc. All rights reserved. - - - Bravado is licensed with a `BSD 3-Clause - - License `__. -unicredit/sbt-swagger-codegen: > - # SBT Swagger Code Generator - - - ## Overview - - - Like the official [swagger-codegen](https://github.com/swagger-api/swagger-codegen) this project aims to generate Scala source code from [Swagger 2.0 Specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) compliant API descriptions. - - Moreover, you can do it directly within an `sbt` project. - - - ## Compatibility - - - This code generator is designed specifically for Swagger Spec Version 2.0. Moreover, it relies on [Play! Framework](http://www.playframework.com/) 2.7 for Json marshalling/unmarshalling, server- and client-side code. - - - ## Install - - - Current release is [`0.0.12`](https://github.com/unicredit/sbt-swagger-codegen/tree/0.0.12) - - - If you want to try the latest version on `master`, first clone this project and `publishLocal` it. - - - Enable it inside your `project\plugins.sbt` like this: - - - `addSbtPlugin("eu.unicredit" % "sbt-swagger-codegen" % "0.1.0-SNAPSHOT")` - - - Enable it in your `build.sbt` like this: - - - `enablePlugins(SwaggerCodegenPlugin)` - - - ## Quick start - - - For a *super fast* hands-on tutorial refer to the related examples and check out [sbt-swagger-codegen-examples](https://github.com/unicredit/sbt-swagger-codegen-examples). - - - ## How it works - - - By default, the plugin will assume that you have put your `yaml` Swagger specification files under `src/main/swagger`. - - - If so, then you can just run `swaggerModelCodeGen` task and it will generate your *models* as case classes and [Play Framework](www.playframework.com) [Formats](https://www.playframework.com/documentation/2.5.x/ScalaJsonCombinators#Format) for them (for json serialization). - - - ## Tasks - - - All available tasks from the plugin - - - - `swaggerModelCodeGen` -> generated code for model classes - - - `swaggerServerCodeGen` -> generates Play Framework code - - - `swaggerClientCodeGen` -> generates client code using `play-ws` - - - `swaggerClean` -> cleans up already generated code - - - The `swaggerModelCodeGen`, `swaggerServerCodeGen` and `swaggerClientCodeGen` will run automatically when the swagger sources change. - - - ## Keys (and defaults) - - - These keys influence properties of the generated code itself: - - - - `swaggerSourcesDir` -> "/src/main/swagger" (path where to search for swagger files) - - - `swaggerCodeGenPackage` -> "swagger.codegen" (package name of the generated sources) - - - `swaggerModelFileSplitting` -> "oneFilePerSource" (in model generation how to group classes in '.scala' files available options are "oneFilePerSource" "oneFilePerModel") - - - `swaggerCodeProvidedPackage` -> "com.yourcompany" (where you will provide business logic server method implementation) - - - These keys determine where generated files will be put: - - - - `swaggerModelCodeTargetDir` -> "target/scala-2.1x/src_managed/src/main/swagger/model" (path where to put generated model files) - - - `swaggerClientCodeTargetDir` -> "target/scala-2.1x/src_managed/src/main/swagger/client" (path where to put generated client code files) - - - `swaggerServerCodeTargetDir` -> "target/scala-2.1x/src_managed/src/main/swagger/server" (path where to put generated server code files) - - - These keys can be used to determine what kind of code should be generated: - - - - `swaggerGenerateModel` -> true (to be disabled if you do not want model classes to be generated automatically when swagger source code changes) - - - `swaggerGenerateJsonRW` -> true (if you want to generate json Format for your model case classes) - - - `swaggerGenerateClient` -> false (enable this if you want client code to ge generated automatically when swagger source code changes) - - - `swaggerGenerateServer` -> false (enable this if you want client code to ge generated automatically when swagger source code changes) - - - Moreover, you can extend this plugin by providing alternative implementations of the generators via: - - - - `swaggerModelCodeGenClass` -> new eu.unicredit.swagger.generators.DefaultModelGenerator() (the class used to generate the model classes) - - - `swaggerJsonCodeGenClass` -> new eu.unicredit.swagger.generators.DefaultJsonGenerator() (the class used to generate the json marshaller/unmarshaller) - - - `swaggerServerCodeGenClass` -> new eu.unicredit.swagger.generators.DefaultServerGenerator() (the class used to generate the Server classes) - - - `swaggerClientCodeGenClass` -> new eu.unicredit.swagger.generators.DefaultClientGenerator() (the class used to generate the client classes) - - - ## Dependencies - - - - scala version 2.12.X - - - [play-ws-standalone-json 1.1.3](http://mvnrepository.com/artifact/com.typesafe.play/play-ws-standalone-json) - - - [play-ahc-ws-standalone 1.1.3](http://mvnrepository.com/artifact/com.typesafe.play/play-ahc-ws-standalone) (only if you use client) - - - ### Limitations - - - At the moment the project is developed to fulfill some internal projects needs, so do not expect it to cover all the corner cases of the Swagger Spec (i.e. some primitive types in body req or resp). - - - ## The road ahead - - - We are actively working with and on this project, trying to overcome any arising limitations and support all Swagger-spec properties we need. - - PRs are really welcome and please open an Issue if you find that something is not working. - - - ## Authors - - - * Andrea Peruffo ([@andreaTP](https://github.com/andreaTP)) - - * Francesco Montecuccoli Degli Erri ([@fralken](https://github.com/fralken)) - - * Marco Firrincieli ([@mfirry](https://github.com/mfirry)) - - - ### Acknowledgements - - - Thanks to Daniel Wunsch ([@dwunsch](https://github.com/dwunsch)), [@dvirf](https://github.com/dvirf) and Reto Habluetzel ([@rethab](https://github.com/rethab)) for their valuable contributions. - - - *** This is a work in progress and we are not done with it! *** -MicroarrayTecnologia/spec-synthase: > - # Spec-Synthase - - [![Build Status](https://travis-ci.org/MicroarrayTecnologia/spec-synthase.svg?branch=master)](https://travis-ci.org/MicroarrayTecnologia/spec-synthase) - - [![Coverage Status](https://coveralls.io/repos/github/MicroarrayTecnologia/spec-synthase/badge.svg)](https://coveralls.io/github/MicroarrayTecnologia/spec-synthase) - - - Spec-Synthase is a tool to help deal with big swagger files, by building the swagger specification file from little yaml files. - - - **Documentation:** - http://spec-synthase.readthedocs.io/en/latest/ - - - # Usage examples with Zalando/Connexion in production: - - [Mozilla/Balrog - Admin Api](https://github.com/mozilla/balrog/blob/c6ac05dc2f4245f33628c1c2cb4b5c5de02c21f5/auslib/web/admin/base.py#L20-L30) - - [Mozilla/Balrog - Public Api](https://github.com/mozilla/balrog/blob/c6ac05dc2f4245f33628c1c2cb4b5c5de02c21f5/auslib/web/public/base.py#L30-L37) - - [National Library of Finland/Finto-suggestions - - ](https://github.com/NatLibFi/Finto-suggestions/blob/master/api/app.py#L89) -fleekjs/fleek-router: '{"message":"Not - Found","documentation_url":"https://docs.github.com/rest/reference/repos#get-a-repository-readme"}' -Trax-air/swagger-stub: > - .. image:: - https://travis-ci.org/Trax-air/swagger-stub.svg?branch=master - :alt: Travis status - :target: https://travis-ci.org/Trax-air/swagger-stub - .. image:: https://badges.gitter.im/Trax-air/swagger-stub.svg - :alt: Join the chat at https://gitter.im/Trax-air/swagger-stub - :target: https://gitter.im/Trax-air/swagger-stub?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - .. image:: https://img.shields.io/pypi/v/swagger-stub.svg - :target: https://pypi.python.org/pypi/swagger-stub/ - - swagger-stub - - ============== - - - Swagger-stub create automatically a stub of your swagger REST API. This stub can be used anywhere you want like in a pytest fixture for your unit test. - - - In addition of mocking your API, you can mock some call, and check every call that have been made to the API. - - - Related Libraries - - ----------------- - - You may find related libraries to this one: - - - * https://github.com/Trax-air/swagger-tester: Auto-test your swagger API in your unit tests. All test calls are generated by your swagger file. - - * https://github.com/Trax-air/swagger-aggregator: Aggregate several swagger specs into one. Useful for your API gateways! - - * https://github.com/Trax-air/swagger-parser: A helper that parses swagger specs. You can access the HTTP actions / paths and some example data - - - Example Usage - - ------------- - - - .. code:: python - - import pytest - import requests - - from swagger_stub import swagger_stub - - # This is the fixture of your stub - # You only need to specify the path of the swagger file and the address - # where you want to bind your stub. - @pytest.fixture - def test_stub(): - return swagger_stub([('swagger.yaml', 'http://foo.com')]).next() - - # Then you can use this fixture anywhere you want like your API is really running. - def test_swagger_stub(test_stub): - # Get a definition example - test_stub.definitions['Foo'] - - # Check a simple call - response = requests.get('http://foo.com/v1/bar/') - assert response.status_code == 200 - assert response.json() == { - 'foo': 'bar' - } - - # Check that an invalid body cause an error - response = requests.post('http://foo.com/v1/bar/', data='invalid data') - assert response.status_code == 400 - - # Mock a call - test_stub.add_mock_call('get', '/test', {'mock': 'call'}) - response = requests.get('http://foo.com/v1/test') - assert response.json() == {'mock': 'call'} - - # Set some side_effect like in the mock library - test_stub.add_mock_side_effect('get', '/iter', [{'test': '1'}, {'test': '2'}, {'test': '3'}]) - response = requests.get('http://foo.com/v1/iter') - assert response.json() == {'test': '1'} - response = requests.get('http://foo.com/v1/iter') - assert response.json() == {'test': '2'} - response = requests.get('http://foo.com/v1/iter') - assert response.json() == {'test': '3'} - - # This side effect will raise a custom error - test_stub.add_mock_side_effect('get', '/error', Exception) - - with pytest.raises(Exception): - response = requests.get('http://foo.com/v1/error') - - Documentation - - ------------- - - - More documentation is available at https://swagger-stub.readthedocs.org/en/latest/. - - - Setup - - ----- - - - `make install` or `pip install swagger-stub` - - - License - - ------- - - - swagger-stub is licensed under http://opensource.org/licenses/MIT. -Nexmo/oas_parser: > - # Open API Definition Parser - - - Nexmo is now known as Vonage - - - A Ruby parser for Open API Spec 3.0+ definitions. - - - ### Install - - - Install the gem: - - - ``` - - $ gem install oas_parser - - ``` - - - Or add it to your Gemfile: - - - ```ruby - - gem 'oas_parser' - - ``` - - - ### Usage - - - Here is a basic example of how you can traverse through an Open API Spec 3 Definition: - - - ```ruby - - require 'oas_parser' - - - definition = OasParser::Definition.resolve('petstore.yml') - - # => # - - - # Get a specific path - - path = definition.path_by_path('/pets') - - # => # - - - # Get all paths. - - definition.paths - - # => [#, ...] - - - # Get a specific endpoint by method - - endpoint = path.endpoint_by_method('get') - - # => # - - - # Get all endpoints - - path.endpoints - - # => [#, ...] - - - # Get endpoint description - - endpoint.description - - # => "Returns all pets from the system that the user has access to" - - ``` - - - Checkout the tests and `lib` directory for more classes and methods. - - - ### Development - - - Run tests: - - - ``` - - $ rspec - - ``` - - - ### Publishing - - - Clone the repo and navigate to its directory: - - - ``` - - $ cd oas-parser - - ``` - - - Bump the latest version in `oas_parser/lib/oas_parser/version.rb`: - - - ``` - - //old - - module OasParser - VERSION = '1.0.0'.freeze - end - - - //new - - module OasParser - VERSION = '1.1.0'.freeze - end - - ``` - - - Build the gem: - - - ``` - - $ gem build oas_parser.gemspec - - ``` - - - _This will create a `oas_parser-1.1.0.gem` file._ - - - Push the gem to rubygems.org: - - - ``` - - $ gem push oas_parser-1.1.0.gem - - ``` - - - Verify the change was made by checking for the [new version on rubygems.org](https://rubygems.org/gems/oas_parser) - - - - - ## Contributing - - - Contributions are welcome, please follow [GitHub Flow](https://guides.github.com/introduction/flow/index.html) -ampedandwired/bottle-swagger: > - ===================== - - Bottle Swagger Plugin - - ===================== - - - About - - ----- - - This project is a Bottle plugin for working with Swagger. - - `Bottle `_ is a Python web framework. - - `Swagger (OpenAPI) `_ is a standard for defining REST APIs. - - - So if you are serving a REST API with Bottle, - - and you have a defined a Swagger schema for that API, - - this plugin can: - - - * Validate incoming requests and outgoing responses against the swagger schema - - * Return appropriate error responses on validation failures - - * Serve your swagger schema via Bottle (for use in `Swagger UI `_ for example) - - - Requirements - - ------------ - - - * Python >= 2.7 - - * Bottle >= 0.12 - - * Swagger specification >= 2.0 - - - This project relies on `bravado-core `_ to perform the swagger schema validation, - - so any version of the Swagger spec supported by that project is also supported by this plugin. - - - Installation - - ------------ - - :: - - $ pip install bottle-swagger - - Usage - - ----- - - See the "example" directory for a working example of using this plugin. - - - The simplest usage is:: - - import bottle - - swagger_def = _load_swagger_def() - bottle.install(SwaggerPlugin(swagger_def)) - - Where "_load_swagger_def" returns a dict representing your swagger specification - - (loaded from a yaml file, for example). - - - There are a number of arguments that you can pass to the plugin constructor: - - - * ``validate_requests`` - Boolean (default ``True``) indicating if incoming requests should be validated or not - - * ``validate_responses`` - Boolean (default ``True``) indicating if outgoing responses should be validated or not - - * ``ignore_undefined_routes`` - Boolean (default ``False``) indicating if undefined routes - (that is, routes not defined in the swagger spec) should be passed on ("True") or return a 404 ("False") - * ``invalid_request_handler`` - Callback called when request validation has failed. - Default behaviour is to return a "400 Bad Request" response. - * ``invalid_response_handler`` - Callback called when response validation has failed. - Default behaviour is to return a "500 Server Error" response. - * ``swagger_op_not_found_handler`` - Callback called when no swagger operation matching the request was found in the swagger schema. - Default behaviour is to return a "404 Not Found" response. - * ``exception_handler=_server_error_handler`` - Callback called when an exception is thrown by downstream handlers (including exceptions thrown by your code). - Default behaviour is to return a "500 Server Error" response. - * ``serve_swagger_schema`` - Boolean (default ``True``) indicating if the Swagger schema JSON should be served - - * ``swagger_schema_url`` - URL (default ``/swagger.json``) on which to serve the Swagger schema JSON - - - All the callbacks above receive a single parameter representing the ``Exception`` that was raised, - - or in the case of ``swagger_op_not_found_handler`` the ``Route`` that was not found. - - They should all return a Bottle ``Response`` object. - - - Contributing - - ------------ - - Development happens in the `bottle-swagger GitHub respository `_. - - Pull requests (with accompanying unit tests), feature suggestions and bug reports are welcome. - - - Use "tox" to run the unit tests:: - - $ tox -vanderlee/PHPSwaggerGen: > - # SwaggerGen - - Version 2.3.21 - - - [![License](https://img.shields.io/github/license/vanderlee/PHPSwaggerGen.svg)]() - - [![Build Status](https://travis-ci.org/vanderlee/PHPSwaggerGen.svg?branch=master)](https://travis-ci.org/vanderlee/PHPSwaggerGen) - - [![Quality](https://scrutinizer-ci.com/g/vanderlee/PHPSwaggerGen/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/vanderlee/PHPSwaggerGen) - - - Copyright © 2014-2018 Martijn van der Lee [Toyls.com](http://toyls.com). - - - MIT Open Source license applies. - - - ## Introduction - - SwaggerGen is a PHP library for generating [Swagger](http://swagger.io/) REST - - API documentation from PHP source code. - - - It reads comments starting with `@rest\`, containing commands describing the - - API as you go. - - Working with SwaggerGen is intended to be a natural extension to normal - - PHP-documentor style documentation. - - You can describe a REST API call similar to how you would describe method. - - - Using just a few simple commands like `@rest\endpoint /users` and - - `@rest\method GET Get a list of all users` gets you a definition of an API. - - By adding a `@rest\response 200 array(object(name:string, age:int[0,>, gender:enum(male,female)))` - - statement, you've just defined exactly what it'll return. - - You could have also just defined a `User` and do the same with a - - `@rest\response 200 array(User)` statement or even just `@rest\response ok [User]`. - - - SwaggerGen makes it quick and intuitive to write high quality documentation. - - - Use [Swagger-UI](https://github.com/swagger-api/swagger-ui) to read and test - - your API, as in this example generated real-time with SwaggerGen: - - [Example](example/docs/) (only available when running on a PHP server). - - - SwaggerGen is compatible with the latest - - [Swagger 2.0 specification](http://swagger.io/specification/), - - which forms the basis of the [Open API Initiative](https://openapis.org/). - - - ## Installation - - Requires PHP 5.4 or greater. PHP 5.3 is supported as long as no more recent - - features are absolutely necessary. There is no guarantee SwaggerGen will - - continue to work on PHP 5.3 in the future. - - - To install using Composer: - - composer require vanderlee/swaggergen - - Make sure you use version 2.x.x or up. - - - SwaggerGen aims to be PSR-4 compatible, so you should be able to use it in any - - package manager. - - - ## Using SwaggerGen - - The easiest part of generating Swagger documentation with SwaggerGen is setting - - it up. - - - 1. Set up your (PSR-0, PSR-4 or custom) autoloader to use the SwaggerGen - directory. - - You can take a look at the autoloader in the example folder if you don't - already have an autoloader. - - 2. Create an instance of the `/SwaggerGen/SwaggerGen` class. - - You can (and are advised to) specify the domainname of your server and the - path to the API in the constructor. - - 3. Call the `array SwaggerGen->getSwagger(string[] $filenames)` method to - generate the documentation. - - Just provide the files which contain the operation definitions of your API. - If your API uses other files, just specify an array of directories in the - `SwaggerGen` constructor and these files will be automatically parsed when - needed. - - 4. You're done. Your documentation is generated. All that's left to do is - output it. Store it in a file or return it real-time. - - If you want to use the preprocessor, you'll probably want to call the - - `SwaggerGen->define(string $name, string $value)` method of your `SwaggerGen` instance after - - step 2 to define preprocessor variable names. - - - The following is a typical example: - - // Assuming you don't already have an autoloader - spl_autoload_register(function ($classname) { - include_once __DIR__ . $classname . '.php'; - }); - - $SwaggerGen = new \SwaggerGen\SwaggerGen( - $_SERVER['HTTP_HOST'], - dirname($_SERVER['REQUEST_URI']), - [__DIR__ . '/api'] - ); - $SwaggerGen->define('admin'); // admin = 1 - $SwaggerGen->define('date', date('Y-m-d')); // date = "2015-12-31" - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - $SwaggerGen->define('windows'); // windows = 1 (only if on Windows OS) - } - $swagger = $SwaggerGen->getSwagger(['Example.php']); - - header('Content-type: application/json'); - echo json_encode($swagger); - - # SwaggerGen class - - The only class you need to know about is the `SwaggerGen` class in the similarly - - names `SwaggerGen` namespace. - - - ## `__construct($host = '', $basePath = '', $dirs = array())` - - Create a new SwaggerGen object with the given `host` and `basePath` and provide - - a set of `dirs` to use for scanning for classes that may be referenced - - from the sourcecode files you're about to scan. - - * `$host` should be the domain name, i.e. `www.example.com`. - - * `$basePath` should be the URL path to the root of the API, i.e. `/api/v1`. - - - ## `mixed getSwagger($files, $dirs = array(), $format = self::FORMAT_ARRAY)` - - Generate Swagger/OpenAPI documentation by scanning the provided list of `files`. - - Optionally you can specify additional `dirs` to scan for class files and - - provide a `format` to specify how you want to output the documentation. - - - By default, the documentation is output as an array, ready for encoding as JSON, - - YAML or for manual post-processing. The following formats are available as - - constants of the `SwaggerGen` class. - - * `FORMAT_ARRAY` output the raw array. - - * `FORMAT_JSON` JSON-encoded output (mimetype `application/json`). - - * `FORMAT_JSON_PRETTY` JSON-encoded output with a human-friendly layout - (mimetype `application/json`). - * `FORMAT_YAML` YAML (UTF-8 character encoding) output - (mimetype `application/x-yaml` (most common) or `text/yaml`). - - ## `define($name, $value = 1)` - - Define a value to be used by the preprocessor commands. - - By default, it's value will be set to `1`. - - - ## `undefine($name)` - - Undefine a value, so it is no longer recognized by the preprocessor commands. - - - # Creating documentation - - SwaggerGen takes a number of of source files and scans the comments for - - commands it understands. The following is a short example of the type of - - comments SwaggerGen understands: - - /* - * @rest\description SwaggerGen 2 Example API - * @rest\title Example API - * @rest\contact http://example.com Arthur D. Author - * @rest\license MIT - * @rest\security api_key apikey X-Api-Authentication header Authenticate using this fancy header - * @rest\require api_key - */ - - ## Comments - - All comments are parsed, this includes both doc-comments (`/** ... */`) and - - normal comments, both single line (`// ...`) and multi-line (`/* ... */`). - - - Comments that are attached to functions, methods and classes. Any doc-comment - - immediately preceeding a function, method or class will be attached to that - - function, method or class. Other comments will be attached to the function, - - method or class containing them. For instance, SwaggerGen comments within a - - function will be attached to that function. - - - ## Commands - - - All commands must be prefixed with `@rest\` to distinguish between SwaggerGen - - statements and normal comment statements and statements from other tools such - - as PHP-Documentor. - - - All commands are multi-line by default; any line(s) after the command that do - - not start with an at-sign (`@`) are automatically appended to the command on the - - previous line. - - - You can reference SwaggerGen documentation for other functions, methods or - - classes by using the `uses` command. This command lets you specify an other - - function, method or class whose documentation to include. - - - Commands are processed in the order in which they appear. This includes any - - documentation referenced with the `uses` command. - - - ## Contexts - - SwaggerGen uses a stack of contexts. Each context represents a certain part of - - the Swagger documentation that will be generated. Each context supports a few - - commands which hold meaning within that context. - - - You initially start at the Swagger context. - - - You can switch contexts using some of the commands available within the current - - context. In this manual, whenever a command switches the context, it is - - marked using '⇒ Context name' at the end of the command syntax description. - - - If a command is not recognized in the current context, the context is removed - - from the top of the stack and the previous context tries to handle the command. - - If no context is able to handle the command, SwaggerGen will report this as an - - error. - - - # Preprocessor commands - - SwaggerGen has a limited set of preprocessor statements to remove or change - - parts of the generated documentation at run-time. - - - The preprocessor statements are loosely based on the C/C++ preprocessors. - - - The work by defining values for variable names and checking whether or not a - - variable name is defined or checking if a variables name has a specific value. - - - SwaggerGen currently has no predefined variables, but you can define variables - - yourself by assigning them to the SwaggerGen parser before scanning starts. - - - Preprocessor statments may be nested and are available for PHP and text. - - - ### `define` *`name [value]`* - - Define a variable name and optionally assign a value to it. - - - ### `undef` *`name`* - - Remove the definition a variable name. - - - ### `if` *`name [value]`* - - If the variable name is defined *and*, if provided, it's value is equal to - - the specified value, then process all following SwaggerGen commands upto - - the next preprocessor command. - - Otherwise, do not process those commands. - - - ### `ifdef` *`name`* - - If the variable name is defined, then process all following SwaggerGen - - commands upto the next preprocessor command. - - Otherwise, do not process those commands. - - - ### `ifndef` *`name`* - - If the variable name is *not* defined, then process all following SwaggerGen - - commands upto the next preprocessor command. - - Otherwise, do not process those commands. - - - ### `else` - - If the previous `if...` or `elif` preprocessor command did *not* match, - - then process all following SwaggerGen commands upto the next preprocessor - - command. - - Otherwise, do not process those commands. - - - ### `elif` *`name [value]`* - - If the previous `if...` or `elif` preprocessor command did *not* match - - *and* if the variable name is defined *and*, if provided, it's value is - - equal to the specified value, then process all following SwaggerGen - - commands upto the next preprocessor command. - - Otherwise, do not process those commands. - - - ### `endif` - - End the previous `if...`, `elif` or `else` preprocessor command's block of - - SwaggerGen commands. - - - # SwaggerGen context and commands - - Ordered alphabetically for reference - - - The following commands can be used from within any context. - - - ### `uses` *`reference`* - - Include a reference to another function, method or class. - - - For example: - - * `uses functionName` - - * `uses self::staticMethodName` - - * `uses $this->methodName` - - * `uses ClassName::staticMethodName` - - * `uses ClassName->methodName` - - - SwaggerGen makes no distinction between the `self` and `this` or between - - the static and dynamic `::` and `->`. These can be interchanged without - - any impact. Though it is advised to stick to the proper terms. - - - Class inheritance is used if a method cannot be found within the indicated - - class. - - - alias: `see` - - - ### `x-[...]` *`data`* - - Add a custom extension (starting with `x-`) to the current context. - - - Extensions have no additional functionality and are treated as raw blobs of - - text data. - - - ## BodyParameter - - Represents a body parameter. - - - For a list of commands, read the chapter on **Parameter definitions**. - - The available command depend on the particular type. - - - ## Contact - - Contains the contact information for the API. - - - ### `email` *`email`* - - Set the email address of the contact person. - - - ### `name` *`text ...`* - - Set the name of the contact person. - - - ### `url` *`email`* - - Set the URL where users can contact the maintainer(s). - - - ## Error - - Represents a response with an error statuscode. - - - See the Response context for commands. - - - ## ExternalDocumentation - - Contains an URL reference to additional documentation of the context which - - created this context. - - - ### `description` *`text ...`* - - Set the description text for this external documentation. - - - ### `url` *`url`* - - Set the URL to the external documentation. - - - ## Header - - Represents a response header. - - - ### `description` *`text ...`* - - Set the description text of this response header. - - - ## Info - - Contains non-technical information about the API, such as a description, - - contact details and legal small-print. - - - ### `contact` *`[url] [email] [name ...]`* ⇒ Contact - - Set the contactpoint or -person for this API. - - You can specify the URL, email address and name in any order you want. - - The URL and email address will be automatically detected, the name will - - consist of all text remaining (properly separated with whitespace). - - - ### `description` *`text ...`* - Set the description for the API. - - ### `license` *`[url] [name ...]`* ⇒ License - - Set the license for this API. - - You can specify the URL in name in any order you want. - - If you omit the URL, you can use any number of predefined names, which are - - automatically expanded to a full URL, such as `gpl`, `gpl-2.1` or `bsd`. - - - ### `terms` *`text ...`* - - Set the text for the terms of service of this API. - - - alias: `tos`, `termsofservice` - - - ### `title` *`text ...`* - - Set the API title. - - - ### `version` *`number`* - - Set the API version number. - - - ## License - - Represents the name and URL of the license that applies to the API. - - - ### `name` *`text ...`* - - Set the name of the license. - - If you haven't set a URL yet, a URL may be automatically set if it is one - - of a number of recognized license names, such as `mpl` or `apache-2` - - - ### `url` *`text ...`* - - Set the URL of the license. - - - ## Operation - - Describes an operation; a call to a specifc path using a specific method. - - - ### `body`/`body?` *`definition name [description ...]`* ⇒ BodyParameter - - Add a new form Parameter to this operation. - - - Use `body` to make the parameter required. - - Use `body?` (with a question mark) to make the parameter optional. - - - See the chapter on **Parameter definitions** for a detailed - - description of all the possible definition formats. - - - ### `consumes` *`mime1 [mime2 ... mimeN]`* - - Adds mime types that this operation is able to understand. - - E.g. "application/json", "multipart/form-data" or - - "application/x-www-form-urlencoded". - - - ### `deprecated` - - Mark this operation as deprecated. - - - ### `description` *`text ...`* - - Set the long description of the operation. - - - ### `doc` *`url [description ...]`* ⇒ ExternalDocumentation - - Set an URL pointing to more documentation. - - - alias: `docs` - - - ### `error` *`statuscode [description]`* ⇒ Error - - Add a possible error statuscode that may be returned by this - - operation, including an optional description text. - - - If no description is given, the standard reason for the statuscode will - - be used instead. - - - ### `errors` *`statuscode1 [statuscode2 ... statuscodeN]`* - - Add several possible error statuscodes that may be returned by this - - operation. - - - ### `form`/`form?` *`definition name [description ...]`* ⇒ Parameter - - Add a new form Parameter to this operation. - - - Use `form` to make the parameter required. - - Use `form?` (with a question mark) to make the parameter optional. - - - See the chapter on **Parameter definitions** for a detailed - - description of all the possible definition formats. - - - ### `header`/`header?` *`definition name [description ...]`* ⇒ Parameter - - Add a new header Parameter to this operation. - - - Use `header` to make the parameter required. - - Use `header?` (with a question mark) to make the parameter optional. - - - See the chapter on **Parameter definitions** for a detailed - - description of all the possible definition formats. - - - ### `id` *`name`* - - Set an operation id for this operation. - - - `name` The ID name must be uniue among all operations in the document. - - If you specify an ID that has already been set, an exception will be thrown. - - - ### `parameter` *`name`* - - Add a new parameter by referencing the name of a globally defined parameter. - - - `name` The globally unique name of the parameter reference. - - - alias: `param` - - - ### `path` *`definition name [description ...]`* ⇒ Parameter - - Add a new path Parameter to this operation. - - - `path` parameters are always required; they cannot be optional. - - - See the chapter on **Parameter definitions** for a detailed - - description of all the possible definition formats. - - - ### `produces` *`mime1 [mime2 ... mimeN]`* - - Adds mime types that this operation is able to produce. - - E.g. "application/xml" or "application/json". - - - ### `query`/`query?` *`definition name [description ...]`* ⇒ Parameter - - Add a new query Parameter to this operation. - - - Use `query` to make the parameter required. - - Use `query?` (with a question mark) to make the parameter optional. - - - See the chapter on **Parameter definitions** for a detailed - - description of all the possible definition formats. - - - ### `require` *`security1 [security2 ... securityN]`* - - Set the required security scheme(s) for this operation. - - - Security schemes can be defined in the **Swagger** context. - - - ### `response` *`statuscode definition description`* ⇒ Response - - Adds a possible response status code with a definition of the data that - - will be returned. Though for error statuscodes you would typically use - - the `error` or `errors` commands, you can use this command for those - - status codes as well, including a return definition. - - - See the chapter on **Parameter definitions** for a detailed - - description of all the possible definition formats. - - - ### `response` *`reference statuscode`* - - Reference a response definition. - - - The `reference` name must exist as a Response definition defined in the - - **Swagger** context. - - - Note that this is one of two possible signatures for the `response` command. - - - ### `schemes` *`scheme1 [scheme2 ... schemeN]`* - - Add any number of schemes to the operation. - - - ### `summary` *`text ...`* - - Set the a short summary description of the operation. - - - ### `tags` *`tag1 [tag2 ... tagN]`* - - Add any number of tags to the operation. - - - ## Parameter - - Represents either a form, query, header of path parameter. - - - For a list of commands, read the chapter on **Parameter definitions**. - - The available command depend on the particular type. - - - ## Path - - Represents a URL endpoint or Path. - - - ### `operation` *`method [summary ...]`* ⇒ Operation - - Add a new operation to the most recently specified endpoint. - - Method can be any one of `get`, `put`, `post`, `delete` or `patch`. - - - ### `description` *`text ...`* - - If a tag exists, sets the description for the tag, otherwise to nothing. - - - ## Response - - Represents a response. - - - ### `example` *`name content`* - - Add an example to the response. - - - `name` single-word (without spaces) name of the example. Unique per Response. - - - `content` content of any type. Either a string, JSON object (quotes optional), - - `false`, `true`, `null` or a number (with or without floating point). - - - ### `header` *`type name [description]`* ⇒ Header - - Add a header to the response. - - - `type` must be either `string`, `number`, `integer`, `boolean` or `array`. - - - `name` must be a valid HTTP header name. I.e. `X-Rate-Limit-Limit`. - - - ## Schema - - Represents a definitions of a type, such as an array. - - - ### `doc` *`url [description ...]`* ⇒ ExternalDocumentation - - Set an URL pointing to more documentation. - - - alias: `docs` - - - ### `title` *`text ...`* - - Set the title of this schema. - - - ### `description` *`description ...`* - - Set the description of this schema. - - - For a list of other commands, read the chapter on **Parameter definitions**. - - The available command depend on the particular type. - - - ## SecurityScheme - - Represents a single way of authenticating the user/client to the server. - - You specify the type of security scheme and it's settings using the `security` - - command from the Swagger context. - - - ### `description` *`text ...`* - - Set the description. - - - ### `scope` *`name [description ...]`* - - Add a new oAuth2 scope name with optional description. - - - ## Swagger - - Represents the entire API documentation. - - This is the initial context for commands. - - - ### `consumes` *`mime1 [mime2] ... [mimeN]`* - - Adds mime types that the API is able to understand. E.g. - - "application/json", "multipart/form-data" or - - "application/x-www-form-urlencoded". - - - alias: `consume` - - - ### `contact` *`[url] [email] [name ...]`* ⇒ Contact - - Set the contactpoint or -person for this API. - - You can specify the URL, email address and name in any order you want. - - The URL and email address will be automatically detected, the name will consist - - of all text remaining (properly separated with whitespace). - - - ### `definition` *`name` [type]* ⇒ Schema - - Start definition of a Schema using the reference name specified. - - - Definitions can be specified as read only using exclamation point at the end of - - the definition command. E.g. `definition! user` will create a user model that - - will appear in GET responses and be omitted from POST, PUT, and PATCH requests. - - - When no type is specified, `definition` creates an `object` definition. You can - - specify `type` to create definitions for other types: - - definition PositiveInteger integer[1,> - - definition ArrayOfString array(string) - - See the chapter on **Parameter definitions** for a detailed description of all - - the possible definition types. - - - alias: `model` (for historical reasons) - - - ### `description` *`text ...`* ⇒ Info - - Set the description for the API. - - - ### `doc` *`url [description ...]`* ⇒ ExternalDocumentation - - Set an URL pointing to more documentation. - - - alias: `docs` - - - ### `endpoint` *`/path [tag] [description ...]`* ⇒ Path - - Create an endpoint using the /path. - - If tag is set, the endpoint will be assigned to the tag group of that name. - - If a description is set, the description of the group will be set. - - - ### `license` *`[url] [name ...]`* ⇒ License - - Set the license for this API. - - You can specify the URL in name in any order you want. - - If you omit the URL, you can use any number of predefined names, which are - - automatically expanded to a full URL, such as `gpl`, `gpl-2.1`, `mit` or `bsd`. - - - ### `produces` *`mime1 [mime2] ... [mimeN]`* - - Adds mime types that the API is able to produce. E.g. "application/xml" or - - "application/json". - - - alias: `produce` - - - ### `require` *`name [scopes]`* - - Set the required security scheme names. - - If multiple names are given, they must all apply. - - If an `oath2` scheme is specified, you may - - - ### `response` *`name definition description`* ⇒ Response - - Adds a response definition with a schema definition of the data that will be - - returned. You can omit the `definition` by specifying `null` instead. - - - See the chapter on **Parameter definitions** for a detailed - - description of all the possible definition formats. - - - ### `schemes` *`scheme1 [scheme2] ... [schemeN]`* - - Adds protocol schemes. E.g. "http" or "https". - - - alias: `scheme` - - - ### `security` *`name type [params ...]`* ⇒ SecurityScheme - - Define a security method, available to the API and individual operations. - - Name can be any random name you choose. These names will be used to reference - - to the security shemes later on. - - - `Type` must be either `basic`, `apikey` or `oauth2`. - - The parameters depend on the type. - - - For `basic`, you can only specify a description text. - - - For `apikey`, you must first specify a name to use for the query parameter or - - header, then use either `query` or `header` to set the type of apikey. - - Optionally followed by a description text. - - - For `oauth2`, you must set the flow type `implicit`, `password`, `application` - - or `accesscode`. For type `accesscode` you must specify two URL's, for - - authorization and token respectively, for the other types only one URL is - - needed. Optionally follow with a description text. You may need to add scopes - - using the `scope` command afterwards. - - - * `security` *`name`* `basic` *`[description ...]`* - - * `security` *`name`* `apikey` *`header-name`* `header` *`[description ...]`* - - * `security` *`name`* `apikey` *`query-variable`* `query` *`[description ...]`* - - * `security` *`name`* `oauth2 implicit` *`auth-url [description ...]`* - - * `security` *`name`* `oauth2 password` *`token-url [description ...]`* - - * `security` *`name`* `oauth2 application` *`token-url [description ...]`* - - * `security` *`name`* `oauth2 accesscode` *`auth-url token-url [description ...]`* - - - ### `tag` *`tag [description ...]`* ⇒ Tag - - Specifies a tag definition; essentially the category in which an endpoint path - - will be grouped together. - - - alias: `api` (for historical reasons). - - - ### `terms` *`text ...`* ⇒ Info - - Set the text for the terms of service of this API. - - - alias: `tos`, `termsofservice` - - - ### `title` *`text ...`* ⇒ Info - - Set the API title. - - - ### `version` *`number`* ⇒ Info - - Set the API version number. - - - ## Tag - - A tag is used to group paths and operations together in logical categories. - - - ### `description` *`text ...`* - - Set the description. - - - ### `doc` *`url [description ...]`* ⇒ ExternalDocumentation - - Set an URL pointing to more documentation. - - - alias: `docs` - - - # Parameter definitions - - - All parameters can handle the `example` command: - - - ### Commands - - * **`example` *content*** Set the example content of any type. - - Either a string, JSON object (quotes optional), `false`, `true`, `null` or a - - number (with or without floating point). - - - ## string, byte, binary, password - - Represents a text. - - type(pattern)[0,>=default - - * type: `string` or `binary`, - - * range: [min,max]. - Use `[` or `]` for inclusive and `<` or `>` for exclusive. - Empty `min` value means zero. - Empty `max` value means infinity. - * default: any valid text not containing whitespace. - - - ### Commands - - * **`default` *value*** Set the default value. - - * **`enum` *value1 value2 ... valueN*** Set or add allowed values. - - - ### Examples - - * **`string`** A simple text field. - - * **`string(^[a-z]{2}-[A-Z]{2}$)`** String matching ISO "ll-CC" locale. - - * **`string[,256>=red`** A text of at most 255 characters, default to "red". - - * **`binary[1,8]`** Upto 8 binary digits, requiring atleast one. - - - - ## int32 (integer, int), int64 (long) - - Represents numbers without decimals. - - type[0,>=default - - * type: `integer`, `int`, `int32`, `long` or `int64`. - - * range: [min,max]. - Use `[` or `]` for inclusive and `<` or `>` for exclusive. - Empty `min` or `max` values means infinity. - * default: any valid integer. - - - ### Commands - - * **`default` *value*** Set the default value. - - * **`enum` *value1 value2 ... valueN*** Set or add allowed values. - - * **`step` *value*** Set the stepsize between numbers. - - - ### Examples - - * **`int`** 32-bit integer without a default or limited range. - - * **`long<,0>`** 64-bit negative integers only. - - * **`integer[0,>=100`** 32-bit positive integer or zero, default to 100. - - - - ## float, double - - Represents floating point numbers (with decimals). - - type[0,>=default - - * type: `float` or `double` - - * range: [min,max]. - Use `[` or `]` for inclusive and `<` or `>` for exclusive. - Empty `min` or `max` values means infinity. - * default: any valid integer. - - - ### Commands - - * **`default` *value*** Set the default value. - - * **`enum` *value1 value2 ... valueN*** Set or add allowed values. - - * **`step` *value*** Set the stepsize between numbers. - - - ### Examples - - * **`float`** 32-bit floating point number without a default or limited range. - - * **`double<,1>`** 64-bit floating point numbers upto (but not including) 1. - - * **`float<0,>=0.1`** 32-bit positive numbers, excluding 0, default to 0.1. - - - - ## boolean (bool) - - A true/false choice. - - type=default - - * type: `boolean` or `bool`. - - * default: `true`, `false`, 1 (true) or 0 (false). - - - ### Commands - - * **`default` *value*** Set the default value. - - - ### Examples - - * **`boolean`** A basic boolean. - - * **`bool=true`** A boolean, default to true. - - - - ## date, date-time (datetime) - - Special type of string which is limited to dates only - - type=default - - * type: `date`, `date-time` or `datetime`, - - * default: Any valid date format recognized by the [PHP DateTime object](http://php.net/manual/en/datetime.formats.php). - - - ### Commands - - * **`default` *date*** Set the default value. - - - ### Examples - - * **`date`** A simple date - - * **`datetime=2015-12-31T12:34:56Z`** Date and time set to a default without - a timezone offset. - * **`datetime=2015-12-31T12:34:56.001+01:00`** Date and time set to a default - value with fractional seconds and a timezone offset. - - ## csv (array), ssv, tsv, pipes, multi - - List of items - - type(definition)[0,> - - Alternative short-hand notation for `array` lists: - - [definition][0,> - - * type: `csv`, `array`, `ssv`, `tsv`, `pipes`, or `multi`. - - * range: [min,max]. - Use `[` or `]` for inclusive and `<` or `>` for exclusive. - Empty `min` value means zero. - Empty `max` value means infinity. - * default: any valid text not containing whitespace. - - * definition: a definition of the type of the items in the list. It is possible to - define lists as items, creating multidimensional arrays. - - ### Commands - - * **`min` *value*** Set the minimum number of items required. - - * **`max` *value*** Set the maximum number of items allowed. - - * **`items` *definition*** Set the definition of the items in this list. - - - ### Types - - * **`csv`** Comma (`,`) separated. I.e. `red,green,blue`. Alias: `array`. - - * **`ssv`** Space ( ) separated. I.e. `red green blue`. - - * **`tsv`** Tab-separated. I.e. `red green blue`. - - * **`pipes`** Pipe (`|`) separated. I.e. `red|green|blue`. - - * **`multi`** query-string formatted. I.e. `color=red&color=green&color=blue`. - This choice is only available for `form` and `query` parameters. - - ### Examples - - * **`csv(string)`** A comma-separated list of strings. - - - ## file - - A file. - - file - - No further definition is possible. There are no command. - - - ### Examples - - * **`file`** A file. - - - ## object - - Object with properties. Typically used as key-value map - - object(definition)[0,> - - Alternative short-hand notation: - - {definition}[0,> - - * type: `object`. - - * range: [min,max]. - Use `[` or `]` for inclusive and `<` or `>` for exclusive. - Empty `min` value means zero properties (no minimum). - Empty `max` value means infinite properties (no maximum). - * definition: a comma-separated list of property definitions in the form of - `key:definition`, where `key` can be any sequence of characters except `:` or - `?` or `!`. The `?` means that key is optional. The `!` means the key is read only. - Read only implies optional as well. - - ### Commands - - * **`min` *value*** Set the minimum number of items required. - - * **`max` *value*** Set the maximum number of items allowed. - - * **`property` *definition name*** Add a required property. - - * **`property?` *definition name*** Add an optional property. - - * **`property!` *definition name*** Add a read only property. - - * **`discriminator` *propertyName*** Sets the property as a discriminator. - The property must be required (could not be read only nor optional), but - you can define it later. - - ### Examples - - * **`object(age:int[18,25>)`** An object containing a single key `age` with - an integer value greater or equal to 18 and less than 25. - * **`object(age:int,name?:string[2,>)`** An object containing an `age` and an - optional `name` string, where the value must be atleast two characters - long. - * **`object()[4,8]`** An object containing four to eight unknown properties. - - - ## allof - - Intersection type (data must satisfy all base types). May be used for type - - composition or to implement inheritance (in conjunction with `discriminator`). - - Could also be used to refine the constraints imposed by the base type. - - allof(definition) - - * definition: a comma-separated list of base types, either as inline - definitions or references to another definition - - ### Commands - - * **`item` *type*** Add the type to the list of allOf types - - - ### Examples - - * **`allOf(DataModel,IdModel)`** type composition: effectively creates - DataWithId type. - * **`allOf(ModelWithOptionalName,object(name:string))`** type refinement: - effectively makes `name` property required. - - ## enum - - Special type of string which is limited to one of a number of predefined values. - - enum(value1,value1,...,valueN)=default - - * values: any text not containing whitespace or commas. - - * default: any of the specified texts. - - - ### Commands - - See string. - - - ### Examples - - * **`enum(red,green,blue)=red`** A string containing either "red", "green" or - "blue", default to "red". - - ## uuid - - Special type of string which accepts - - [RFC 4122](https://www.ietf.org/rfc/rfc4122.txt) compliant Universally Unique - - IDentifier (UUID) strings. The default value is validated to ensure only valid - - UUID's are specified. - - uuid=default - - * default: any of the specified texts. - - - ### Commands - - See string. - - - ### Examples - - * **`uuid=123e4567-e89b-12d3-a456-426655440000`** A uuid string, default to - the uuid "123e4567-e89b-12d3-a456-426655440000". - - ## refobject - - Reference to a globally defined `definition` (a.k.a. `model`) object. - - refobject(definitionName) - - or - - definitionName - - * definitionName: the name of the globally defined `definition`. - - - ### Examples - - * **`refobject(Address)`** Reference the a globally defined model named - `Address`. - * **`Address`** Reference the a globally defined model named - `Address`. - - ### Notes - - Usually, using the definition name alone is good enough. - - Use `refobject(...)` if you are using a name which is also used as a builtin - - parameter type, such as `string` or `object`. - - It is best practice to start all definition names with an upper case character - - (i.e. `Address`). - - Using `refobject(...)` also offers the safest forward-compatible strategy if - - you do not start definition names with upper case (i.e. `address`). - - - # Appendices - - ## Mime types - - Some commands, such as `consumes` and `produces` take mime types as arguments. - - Instead of specifying the full mime types, you can any of the following - - predefined shorthands (case insensitive): - - fileform multipart/form-data - form application/x-www-form-urlencoded - json application/json - text text/plain - utf8 text/plain; charset=utf-8 - yml application/x-yaml - yaml application/x-yaml - php text/x-php - xml text/xml - - ## Licenses - - A selection of shorthands are available for licenses. - - If you want another license added to it, please submit an issue or create a - - pull request. The file you want to edit is `/SwaggerGen/Swagger/License.php`. - - - These are the license shorthands currently available: - - artistic-1.0 http://opensource.org/licenses/artistic-license-1.0 - artistic-1 http://opensource.org/licenses/artistic-license-1.0 - artistic-2.0 http://opensource.org/licenses/artistic-license-2.0 - artistic-2 http://opensource.org/licenses/artistic-license-2.0 - artistic http://opensource.org/licenses/artistic-license-2.0 - bsd-new https://opensource.org/licenses/BSD-3-Clause - bsd-3 https://opensource.org/licenses/BSD-3-Clause - bsd-2 https://opensource.org/licenses/BSD-2-Clause - bsd https://opensource.org/licenses/BSD-2-Clause - epl-1.0 http://www.eclipse.org/legal/epl-v10.html - epl-1 http://www.eclipse.org/legal/epl-v10.html - epl http://www.eclipse.org/legal/epl-v10.html - apache-2.0 http://www.apache.org/licenses/LICENSE-2.0.html - apache-2 http://www.apache.org/licenses/LICENSE-2.0.html - apache http://www.apache.org/licenses/LICENSE-2.0.html - gpl-1.0 https://www.gnu.org/licenses/gpl-1.0.html - gpl-1 https://www.gnu.org/licenses/gpl-1.0.html - gpl-2.0 https://www.gnu.org/licenses/gpl-2.0.html - gpl-2 https://www.gnu.org/licenses/gpl-2.0.html - gpl-3.0 http://www.gnu.org/licenses/gpl-3.0.html - gpl-3 http://www.gnu.org/licenses/gpl-3.0.html - gpl http://www.gnu.org/licenses/gpl-3.0.html - lgpl-2.0 http://www.gnu.org/licenses/lgpl-2.0.html - lgpl-2.1 http://www.gnu.org/licenses/lgpl-2.1.html - lgpl-2 http://www.gnu.org/licenses/lgpl-2.1.html - lgpl-3.0 http://www.gnu.org/licenses/lgpl-3.0.html - lgpl-3 http://www.gnu.org/licenses/lgpl-3.0.html - lgpl http://www.gnu.org/licenses/lgpl-3.0.html - mit http://opensource.org/licenses/MIT - mpl-1.1 https://www.mozilla.org/en-US/MPL/1.1/ - mpl-1 https://www.mozilla.org/en-US/MPL/1.1/ - mpl-2.0 https://www.mozilla.org/en-US/MPL/ - mpl-2 https://www.mozilla.org/en-US/MPL/ - mpl https://www.mozilla.org/en-US/MPL/ - mspl https://msdn.microsoft.com/en-us/library/ff648068.aspx - - - # Example - - To view an example of Swagger documentation generated with SwaggerGen, visit - - the [Example API documentation](./example/docs/). - - - The following is a fragment of code from this example: - - /** - * @rest\endpoint /user/{username} - * @rest\method GET Get a list of all users - * @rest\path String username Name of the user - * @rest\see self::request - */ - private function getUser($name) - { - /* - * @rest\model User - * @rest\property int age Age of the user in years - * @rest\property int height Height of the user in centimeters - */ - return $this->data['users'][$name]; // @rest\response OK object(age:int[0,100>,height:float) User - } -garethjevans/swagger-codegen-maven-plugin: > - swagger-codegen-maven-plugin - - ============================ - - - [![Build Status](https://travis-ci.org/garethjevans/swagger-codegen-maven-plugin.svg?branch=master)](https://travis-ci.org/garethjevans/swagger-codegen-maven-plugin) - - [![Maven version][maven-img]][maven-url] - - - A Maven plugin to support the [swagger](http://swagger.io) code generation project - - - Usage - - ============================ - - - Add to your `build->plugins` section (default phase is `generate-sources` phase) - - ```xml - - - com.garethevans.plugin - swagger-codegen-maven-plugin - ${project.version} - - - - generate - - - src/main/resources/api.yaml - java - - - - - - ``` - - - Followed by: - - - ``` - - mvn clean compile - - ``` - - - ### Configuration parameters - - - - `inputSpec` - swagger spec file path - - - `language` - target generation language - - - `output` - target output path (default is `${project.build.directory}/generated-sources/swagger`) - - - `templateDirectory` - directory with mustache templates - - - `addCompileSourceRoot` - add the output directory to the project as a source root (`true` by default) - - - -- - - [maven-url]: https://search.maven.org/#search%7Cga%7C1%7Cswagger-codegen-maven-plugin - - [maven-img]: https://img.shields.io/maven-central/v/com.garethevans.plugin/swagger-codegen-maven-plugin -noirbizarre/flask-restplus: > - ============== - - Flask RestPlus - - ============== - - - .. image:: https://secure.travis-ci.org/noirbizarre/flask-restplus.svg?branch=master - :target: https://travis-ci.org/noirbizarre/flask-restplus?branch=master - :alt: Build status - .. image:: https://coveralls.io/repos/noirbizarre/flask-restplus/badge.svg?branch=master - :target: https://coveralls.io/r/noirbizarre/flask-restplus?branch=master - :alt: Code coverage - .. image:: https://readthedocs.org/projects/flask-restplus/badge/?version=latest - :target: https://flask-restplus.readthedocs.io/en/latest/ - :alt: Documentation status - .. image:: https://img.shields.io/pypi/l/flask-restplus.svg - :target: https://pypi.org/project/flask-restplus - :alt: License - .. image:: https://img.shields.io/pypi/pyversions/flask-restplus.svg - :target: https://pypi.org/project/flask-restplus - :alt: Supported Python versions - .. image:: https://badges.gitter.im/Join%20Chat.svg - :alt: Join the chat at https://gitter.im/noirbizarre/flask-restplus - :target: https://gitter.im/noirbizarre/flask-restplus?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - - **IMPORTANT NOTICE**: - - - This project has been **forked** to `Flask-RESTX `_ - - and will be maintained by by the `python-restx `_ - - organization. **Flask-RESTPlus should be considered unmaintained**. - - - The community has decided to fork the project due to lack of response from the - - original author @noirbizarre. We have been discussing this eventuality for - - almost `a year `_. - - - Things evolved a bit since that discussion and a few of us have been granted - - maintainers access to the github project, but only the original author has - - access rights on the PyPi project. As such, we been unable to make any actual - - releases. To prevent this project from dying out, we have forked it to continue - - development and to support our users. - - - - Flask-RESTPlus is an extension for `Flask`_ that adds support for quickly building REST APIs. - - Flask-RESTPlus encourages best practices with minimal setup. - - If you are familiar with Flask, Flask-RESTPlus should be easy to pick up. - - It provides a coherent collection of decorators and tools to describe your API - - and expose its documentation properly using `Swagger`_. - - - - Compatibility - - ============= - - - Flask-RestPlus requires Python 2.7 or 3.4+. - - - - Installation - - ============ - - - You can install Flask-Restplus with pip: - - - .. code-block:: console - - $ pip install flask-restplus - - or with easy_install: - - - .. code-block:: console - - $ easy_install flask-restplus - - - Quick start - - =========== - - - With Flask-Restplus, you only import the api instance to route and document your endpoints. - - - .. code-block:: python - - from flask import Flask - from flask_restplus import Api, Resource, fields - - app = Flask(__name__) - api = Api(app, version='1.0', title='TodoMVC API', - description='A simple TodoMVC API', - ) - - ns = api.namespace('todos', description='TODO operations') - - todo = api.model('Todo', { - 'id': fields.Integer(readOnly=True, description='The task unique identifier'), - 'task': fields.String(required=True, description='The task details') - }) - - - class TodoDAO(object): - def __init__(self): - self.counter = 0 - self.todos = [] - - def get(self, id): - for todo in self.todos: - if todo['id'] == id: - return todo - api.abort(404, "Todo {} doesn't exist".format(id)) - - def create(self, data): - todo = data - todo['id'] = self.counter = self.counter + 1 - self.todos.append(todo) - return todo - - def update(self, id, data): - todo = self.get(id) - todo.update(data) - return todo - - def delete(self, id): - todo = self.get(id) - self.todos.remove(todo) - - - DAO = TodoDAO() - DAO.create({'task': 'Build an API'}) - DAO.create({'task': '?????'}) - DAO.create({'task': 'profit!'}) - - - @ns.route('/') - class TodoList(Resource): - '''Shows a list of all todos, and lets you POST to add new tasks''' - @ns.doc('list_todos') - @ns.marshal_list_with(todo) - def get(self): - '''List all tasks''' - return DAO.todos - - @ns.doc('create_todo') - @ns.expect(todo) - @ns.marshal_with(todo, code=201) - def post(self): - '''Create a new task''' - return DAO.create(api.payload), 201 - - - @ns.route('/') - @ns.response(404, 'Todo not found') - @ns.param('id', 'The task identifier') - class Todo(Resource): - '''Show a single todo item and lets you delete them''' - @ns.doc('get_todo') - @ns.marshal_with(todo) - def get(self, id): - '''Fetch a given resource''' - return DAO.get(id) - - @ns.doc('delete_todo') - @ns.response(204, 'Todo deleted') - def delete(self, id): - '''Delete a task given its identifier''' - DAO.delete(id) - return '', 204 - - @ns.expect(todo) - @ns.marshal_with(todo) - def put(self, id): - '''Update a task given its identifier''' - return DAO.update(id, api.payload) - - - if __name__ == '__main__': - app.run(debug=True) - - - Contributors - - ============ - - - Flask-RESTPlus is brought to you by @noirbizarre. Since early 2019 @SteadBytes, - - @a-luna, @j5awry, @ziirish volunteered to help @noirbizarre keep the project up - - and running. - - Of course everyone is welcome to contribute and we will be happy to review your - - PR's or answer to your issues. - - - - Documentation - - ============= - - - The documentation is hosted `on Read the Docs `_ - - - - .. _Flask: http://flask.pocoo.org/ - - .. _Swagger: http://swagger.io/ - - - - Contribution - - ============ - - Want to contribute! That's awesome! Check out `CONTRIBUTING.rst! `_ -Trax-air/swagger-parser: > - .. image:: - https://travis-ci.org/Trax-air/swagger-parser.svg?branch=master - :alt: Travis status - :target: https://travis-ci.org/Trax-air/swagger-parser - .. image:: https://badges.gitter.im/Trax-air/swagger-parser.svg - :alt: Join the chat at https://gitter.im/Trax-air/swagger-parser - :target: https://gitter.im/Trax-air/swagger-parser?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - .. image:: https://img.shields.io/pypi/v/swagger-parser.svg - :target: https://pypi.python.org/pypi/swagger-parser/ - - swagger-parser - - ============== - - - Swagger-parser is a python module giving you access to some interesting data about your swagger file. Like getting a dictionary example from a definition name, get the definition of a dictionary, and more. - - - Related Libraries - - ----------------- - - You may find related libraries to this one: - - - * https://github.com/Trax-air/swagger-tester: Auto-test your swagger API in your unit tests. All test calls are generated by your swagger file. - - * https://github.com/Trax-air/swagger-stub: A stub you can use in your client's unit tests. All the HTTP calls to your swagger API are mocked by default. You can also add your own mocked_calls in your test functions. - - * https://github.com/Trax-air/swagger-aggregator: Aggregate several swagger specs into one. Useful for your API gateways! - - - Example Usage - - ------------- - - - .. code:: python - - from swagger_parser import SwaggerParser - - parser = SwaggerParser(swagger_path='swagger_path') # Init with file - parser = SwaggerParser(swagger_dict={}) # Init with dictionary - - # Get an example of dict for the definition Foo - parser.definitions_example.get('Foo') - - # Get the definition of a dictionary - test = { - 'foo': 'bar' - } - parser.get_dict_definition(test) - - # Validate the definition of a dict - parser.validate_definition('Foo', test) - - # Validate that the given data match a path specification - parser.validate_request('/foo', 'post', body=test, query={'foo': 'bar'}) - - # Get the possible return value of a path - # It will return a dictionary with keys as status_code - # and value as example of return value. - parser.get_request_data('/foo', 'post', body=test) - - # Get an example of a correct body for a path - parser.get_send_request_correct_body('/foo', 'post') - - Documentation - - ------------- - - - More documentation is available at https://swagger-parser.readthedocs.org/en/latest/. - - - Setup - - ----- - - - `make install` or `pip install swagger-parser` - - - License - - ------- - - - swagger-parser is licensed under http://opensource.org/licenses/MIT. -elmiko/pecan-swagger: | - ===================== - Pecan Swagger Project - ===================== - - some helpers to create swagger output from a pecan app - - example usage - ------------- - - given a file named ``myapp.py`` - - :: - - import pecan - from pecan_swagger import decorators as swagger - - - @swagger.path('profile', 'Profile', 'Root') - class ProfileController(object): - - @pecan.expose(generic=True, template='index.html') - def index(self): - return dict() - - @index.when(method='POST') - def index_post(self, **kw): - print(kw) - pecan.redirect('/profile') - - - @swagger.path('/', 'Root') - class RootController(object): - - profile = ProfileController() - - and another file named ``myapp-doc.py`` - - :: - - import pprint - - from pecan_swagger import utils - import myapp - - pp = pprint.PrettyPrinter(indent=2) - pp.pprint(utils.swagger_build('myapp', '1.0')) - - - the following will be produced when run - - :: - - $ python myapp-doc.py - { - "swagger": "2.0", - "info": { - "version": "1.0", - "title": "myapp" - }, - "paths": { - "/profile": { - "POST": {}, - "GET": {} - } - } - } -smoketurner/dropwizard-swagger: > - dropwizard-swagger - - ================== - - [![Build Status](https://travis-ci.org/smoketurner/dropwizard-swagger.svg?branch=master)](https://travis-ci.org/smoketurner/dropwizard-swagger) - - [![Coverage Status](https://coveralls.io/repos/smoketurner/dropwizard-swagger/badge.svg?branch=master&service=github)](https://coveralls.io/github/smoketurner/dropwizard-swagger?branch=master) - - [![Maven Central](https://img.shields.io/maven-central/v/com.smoketurner/dropwizard-swagger.svg?style=flat-square)](https://maven-badges.herokuapp.com/maven-central/com.smoketurner/dropwizard-swagger/) - - [![GitHub license](https://img.shields.io/github/license/smoketurner/dropwizard-swagger.svg?style=flat-square)](https://github.com/smoketurner/dropwizard-swagger/tree/master) - - [![Become a Patron](https://img.shields.io/badge/Patron-Patreon-red.svg)](https://www.patreon.com/bePatron?u=9567343) - - - A Dropwizard bundle that serves Swagger UI static content and loads Swagger endpoints. Swagger UI static content is taken from https://github.com/swagger-api/swagger-ui - - - Current version has been tested with Dropwizard 2.0.0 and Swagger 1.6.0 which supports Swagger 2 spec! - - - Note: if you come from previous versions there have been some changes in the way the bundle is configured, see details below. - - - License - - ------- - - - http://www.apache.org/licenses/LICENSE-2.0 - - - Version matrix - - -------------- - - - | dropwizard-swagger | Dropwizard | Swagger API | Swagger UI | - - |--------------------|------------|-------------|------------| - - | < 0.5 | 0.7.x | 1.3.2 | ? | - - | 0.5.x | 0.7.x | 1.3.12 | v2.1.4-M1 | - - | 0.6.x | 0.8.0 | 1.3.12 | v2.1.4-M1 | - - | 0.7.x | 0.8.x | 1.5.1-M2 | v2.1.4-M1 | - - | 0.7.2 | 0.8.4 | 1.5.3 | v2.1.2 | - - | 0.9.x | 0.9.x | 1.5.9 | v2.1.5 | - - | 1.0.x | 1.0.x | 1.5.12 | v2.2.10 | - - | 1.1.x | 1.1.x | 1.5.16 | v2.2.10 | - - | 1.2.x | 1.2.x | 1.5.18 | v3.9.2 | - - | 1.3.x | 1.3.x | 1.5.22 | v3.23.0 | - - | 2.0.x | 2.0.x | 1.6.0 | v3.24.3 | - - - How to use it - - ------------- - - - * Add the Maven dependency (available in Maven Central) - - - ```xml - - - com.smoketurner - dropwizard-swagger - 2.0.0-1 - - - ``` - - - - * Add the following to your Configuration class: - - - ```java - - public class YourConfiguration extends Configuration { - - @JsonProperty("swagger") - public SwaggerBundleConfiguration swaggerBundleConfiguration; - ``` - - - * Add the following your configuration yaml (this is the minimal configuration you need): - - - ```yaml - - prop1: value1 - - prop2: value2 - - - # the only required property is resourcePackage, for more config options see below - - swagger: - resourcePackage: - ``` - - - * In your Application class: - - - ```java - - @Override - - public void initialize(Bootstrap bootstrap) { - bootstrap.addBundle(new SwaggerBundle() { - @Override - protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(YourConfiguration configuration) { - return configuration.swaggerBundleConfiguration; - } - }); - } - - ``` - - - * As usual, add Swagger annotations to your resource classes and methods - - - * Open a browser and hit `http://localhost:/swagger` - - - Additional Swagger configuration - - -------------------------------- - - - To see all the properties that can be used to customize Swagger see [SwaggerBundleConfiguration.java](src/main/java/io/federecio/dropwizard/swagger/SwaggerBundleConfiguration.java) - - - A note on Swagger 2 - - ------------------- - - - Host and port do not seem to be needed for Swagger 2 to work properly as it uses relative URLs. At the moment I haven't run through all the scenarios so some adjustments might be needed, please open a bug if you encounter any problems. - - - - Contributors - - ------------ - - - * Federico Recio [@federecio](http://twitter.com/federecio) - - * Jochen Szostek [prefabsoft](http://prefabsoft.com) - - * Damien Raude-Morvan [drazzib](https://github.com/drazzib) - - * Marcel Stör [marcelstoer](https://github.com/marcelstoer) - - * Flemming Frandsen [dren-dk](https://github.com/dren-dk) - - * Tristan Burch [tburch](https://github.com/tburch) - - * Matt Carrier [mattcarrier](https://github.com/mattcarrier) - - * Justin Plock [jplock](https://github.com/jplock) - - * Ian Rogers [IanRogers-LShift](https://github.com/IanRogers-LShift) -Trax-air/swagger-tester: > - .. image:: - https://travis-ci.org/Trax-air/swagger-tester.svg?branch=master - :alt: Travis status - :target: https://travis-ci.org/Trax-air/swagger-tester - .. image:: https://badges.gitter.im/Trax-air/swagger-tester.svg - :alt: Join the chat at https://gitter.im/Trax-air/swagger-tester - :target: https://gitter.im/Trax-air/swagger-tester?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - .. image:: https://img.shields.io/pypi/v/swagger-tester.svg - :target: https://pypi.python.org/pypi/swagger-tester/ - - swagger-tester - - ============== - - - Swagger-tester will test automatically your swagger API. Swagger API made with connexion (https://github.com/zalando/connexion) are supported directly without running the API server. In the case you use connexion it will automatically run a test server from your swagger file. - - - To run the test, swagger-tester will detect every path and actions of your API. And for each, it will send a request and check if the response match the swagger file specification. - - - Related Libraries - - ----------------- - - You may find related libraries to this one: - - - - https://github.com/Trax-air/swagger-stub: A stub you can use in your client's unit tests. All the HTTP calls to your swagger API are mocked by default. You can also add your own mocked_calls in your test functions. - - - https://github.com/Trax-air/swagger-aggregator: Aggregate several swagger specs into one. Useful for your API gateways! - - - https://github.com/Trax-air/swagger-parser: A helper that parses swagger specs. You can access the HTTP actions / paths and some example data - - - Example Usage - - ------------- - - - .. code:: python - - from swagger_tester import swagger_test - - # Dict containing the error you don't want to raise. - # By default, every status_code over other than 1xx, 2xx or 3xx - # will be considered as an error. - authorize_error = { - 'post': { - '/pet/{petId}': [200], - '/pet': [200] - }, - 'put': { - '/user/{username}': [200], - '/pet': [200] - }, - 'delete': { - '/pet/{petId}': [200], - '/store/order/{orderId}': [200], - '/user/{username}': [200] - } - } - - # Run the test with connexion - # An AssertionError will be raise in case of error. - swagger_test('path_to_your_swagger.yaml', authorize_error=authorize_error) - - # Or if you have a running API - swagger_test(app_url='http://petstore.swagger.io/v2', authorize_error=authorize_error) - - Documentation - - ------------- - - - More documentation is available at https://swagger-tester.readthedocs.org/en/latest/. - - - Setup - - ----- - - - `make install` or `pip install swagger-tester` - - - License - - ------- - - - swagger-tester is licensed under http://opensource.org/licenses/MIT. -cachecontrol/hippie-swagger: > - ![hippie-swagger](http://i.imgur.com/icjd94P.png) - - - _"The confident hippie"_ - - - [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) - - [![Build Status](https://travis-ci.org/CacheControl/hippie-swagger.svg)](https://travis-ci.org/CacheControl/hippie-swagger) - - [![npm version](https://badge.fury.io/js/hippie-swagger.svg)](https://badge.fury.io/js/hippie-swagger) - - - ## Synopsis - - - ```hippie-swagger``` is a tool for testing RESTful APIs. In addition to validating api behavior, it will fail tests when swagger documentation is missing or inaccurate. - - - As the test suite runs, any request or response details *not* matching the swagger file will throw an appropriate exception, failing the spec. This ensures the swagger definition accurately describes application behavior, keeping documentation in sync with reality. - - - ```hippie-swagger``` uses [hippie](https://github.com/vesln/hippie) under the hood, an excellent API testing tool. - - - ## Features - - - * All [hippie](https://github.com/vesln/hippie) features included - - * All aspects of swagger file validated; parameters, request/response body, paths, etc. - - * Checks for extra parameters, paths, headers, etc not mentioned in the swagger file - - * Ensures swagger file accurately describes API behavior - - * Accurate, human readable assertion messages - - - ## Installation - - - ``` - - npm install hippie-swagger --save-dev - - ``` - - - ## Basic Usage - - - ```js - - var hippie = require('hippie-swagger'), - swagger = require('./my-dereferenced-swagger-file'); // see example for how to dereference swagger - - hippie(app, swagger) - - .get('/users/{username}') - - .pathParams({ - username: 'cachecontrol' - }) - - .expectStatus(200) - - .expectValue('user.first', 'John') - - .expectHeader('cache-control', 'no-cache') - - .end(function(err, res, body) { - if (err) throw err; - }); - - ``` - - - ## Usage - - * See [hippie](https://github.com/vesln/hippie) documentation for a description of the base api - - * When specifying a url(.get, .post, .patch, .url, etc), use the [swagger path](http://swagger.io/specification/#pathsObject) - - * Provide any path variables using [pathParams](#pathparams) - - - These aside, use hippie as you normally would; see the [example](example/index.js). - - - ## Methods - - - ### #constructor (Object app, Object swagger, Object [options]) - - - Test an HTTP app (like express) directly - - - ```js - - hippie(app, swagger, options) - - .get('/projects') - - .end(fn); - - ``` - - - ### #constructor (Object swagger, Object [options]) - - - Test a remote HTTP app using a fully qualified url - - - ```js - - hippie(swagger, options) - - .get('http://localhost:3000/projects') - - .end(fn); - - ``` - - - ### #pathParams(Object hash) - - - Replaces variables contained in the swagger path. - - - ```js - - hippie(app, swagger) - - .get('/projects/{projectId}/tasks/{taskId}') - - .pathParams({ - projectId: 123, - taskId: 99 - }) - - .end(fn); - - ``` - - - ## Options - - - To customize behavior, an ```options``` hash may be passed to the constructor. Typically, ```options``` only need to be specified in situations where the test covers responses to improper requests (e.g. validating the application returns a 422 when a required parameter is not provided). - - - ```js - - var options = { - validateResponseSchema: true, - validateParameterSchema: true, - errorOnExtraParameters: true, - errorOnExtraHeaderParameters: false - }; - - hippie(app, swagger, options) - - ``` - - - ```validateResponseSchema``` - Validate the server's response against the swagger json-schema definition (default: ```true```) - - - ```validateParameterSchema``` - Validate the request parameters against the swagger json-schema definition (default: ```true```) - - - ```validateRequiredParameters``` - Validate that required parameters were provided (default: ```true```) - - - ```errorOnExtraParameters``` - Throw an error if a parameter is missing from the swagger file (default: ```true```) - - - ```errorOnExtraHeaderParameters``` - Throw an error if a request header is missing from the swagger file. By default this is turned off, because it results in every request needing to specify the "Content-Type" and "Accept" headers, which quickly becomes verbose. (default: ```false```) - - - - ## Example - - See the [example](example/index.js) folder - - - ## Validations - - - When hippie-swagger detects it is interacting with the app in ways not specified in the swagger file, it will throw an error and fail the test. The idea is to use hippie's core features to write API tests as per usual, and hippie-swagger will only interject if the swagger contract is violated. - - - Below are list of some of the validations that hippie-swagger checks for: - - - ### Paths - - ```js - - hippie(app, swagger) - - .get('/pathNotMentionedInSwagger') - - .end(fn); - - // path does not exist in swagger file; throws: - - // Swagger spec does not define path: pathNotMentionedInSwagger - - ``` - - - ### Parameter format - - ```js - - hippie(app, swagger) - - .get('/users/{userId}') - - .pathParams({ - userId: 'string-value', - }) - - .end(fn); - - // userId provided as a string, but swagger specifies it as an integer; throws: - - // Invalid format for parameter {userId} - - ``` - - - ### Required Parameters - - ```js - - hippie(app, swagger) - - .get('/users/{username}') - - .end(fn); - - // "username" is marked 'required' in swagger file; throws: - - // Missing required parameter in path: username - - ``` - - - ### Extraneous Parameters - - ```js - - hippie(app, swagger) - - .get('/users') - - .qs({ page: 2, limit: 30 }) - - .end(fn); - - // "page" missing from swagger file; throws: - - // Error: query parameter not mentioned in swagger spec: "page", available params: limit - - ``` - - - ### Response format - - ```js - - hippie(app, swagger) - - .get('/users') - - .end(fn); - - // body failed to validate against swagger file's "response" schema; throws: - - // Response from /users failed validation: [failure description] - - ``` - - - ### Method validation - - ```js - - hippie(app, swagger) - - .post('/users') - - .end(fn); - - // "post" method not mentioned in swagger file; throws: - - // Swagger spec does not define method: "post" in path /users - - ``` - - - ### Post body format - - ```js - - hippie(app, swagger) - - .post('/users') - - .send({"bogus":"post-body"}) - - .end(fn); - - - // post body fails to validate against swagger file's "body" parameter; throws: - - // Invalid format for parameter {body}, received: {"bogus":"post-body"} - - ``` - - - ### Form Url-Encoded Parameters - - ```js - - hippie(app, swagger) - - .form() - - .post('/users') - - .send({}) - - .end(fn); - - - // "username" is {required: true, in: formData} in swagger; throws: - - // Missing required parameter in formData: username - - ``` - - - ### Multipart Forms - - ```js - - hippie(app, swagger) - - .header('Content-Type','multipart/form-data') - - .send() - - .post('/users/upload') - - .end(fn); - - - // "fileUpload" is {required: true, in: formData, type: file} in swagger; throws: - - // Missing required parameter in formData: fileUpload - - ``` - - - ## Troubleshooting - - - The most common mistake is forgetting to dereference the swagger file: - - - ```js - - "'Error: cant resolve reference ...' - - ``` - - - Dereferencing can be accomplished using [swagger-parser](https://github.com/BigstickCarpet/swagger-parser/blob/master/docs/swagger-parser.md#dereferenceapi-options-callback). The [example](example/index.js) gives a demonstration. - - - ## Contributing - - - To run the `hippie-swagger` tests: - - - ``` - - npm test - - ``` - - - ## License - - [ISC](./LICENSE) -guokr/swagger-py-codegen: > - # Python RESTful Web Framework Generator - - - [![Build Status][travis-image]][travis-url] [![PyPi Version][pypi-image]][pypi-url] - - - ## Overview - - - - Swagger Py Codegen is a Python web framework generator, which can help you generate a Python web framework automatically based on a given Swagger Specification doc. Currently, the following languages/frameworks are supported: - - - - * [Flask](http://flask.pocoo.org/) (Python) - - * [Tornado](http://www.tornadoweb.org/en/stable/) (Python) - - * [Falcon](https://falconframework.org/) (Python) - - * [Sanic](https://github.com/channelcat/sanic) (Python) - - - - **Alpha version for now, it may not handle all validation properly. If you found a bug, feel free to contact us.** - - - - ## Install - - - ``` - - pip install swagger-py-codegen - - ``` - - - ## Usage - - - Create all: - - - ``` - - swagger_py_codegen --swagger-doc api.yml example-app - - ``` - - - Command Options: - - -s, --swagger-doc Swagger doc file. [required] - -f, --force Force overwrite. - -p, --package Package name / application name. - -t, --template-dir Path of your custom templates directory. - --spec, --specification Generate online specification json response. - --ui Generate swagger ui. - --validate Validate swagger file. - -tlp, --templates gen flask/tornado/falcon templates, default flask. - --version Show current version. - --help Show this message and exit. - - ## Examples: - - - Generate example-app from [api.yml](https://github.com/guokr/swagger-py-codegen/blob/master/api.yml "Title"): - - - #### Flask Example - - $ swagger_py_codegen -s api.yml example-app -p demo - $ tree (flask-demo) - . - |__ api.yml - |__ example-app - |__ demo - | |__ __init__.py - | |__ v1 - | |__ api - | | |__ __init__.py - | | |__ pets.py - | | |__ pets_petId.py - | |__ __init__.py - | |__ routes.py - | |__ schemas.py - | |__ validators.py - |__ requirements.txt - - #### Tornado Example - - $ swagger_py_codegen -s api.yml example-app -p demo -tlp=tornado - $ tree (tornado-demo) - . - |__ api.yml - |__ example-app - |__ demo - | |__ __init__.py - | |__ core - | |__ __init.py - | |__ v1 - | |__ api - | | |__ __init__.py - | | |__ pets.py - | | |__ pets_petId.py - | |__ __init__.py - | |__ routes.py - | |__ schemas.py - | |__ validators.py - |__ requirements.txt - - #### Falcon Example - - $ swagger_py_codegen -s api.yml example-app -p demo -tlp=falcon - $ tree (falcon-demo) - . - |__ api.yml - |__ example-app - |__ demo - | |__ __init__.py - | |__ v1 - | |__ api - | | |__ __init__.py - | | |__ pets.py - | | |__ pets_petId.py - | |__ __init__.py - | |__ routes.py - | |__ schemas.py - | |__ validators.py - |__ requirements.txt - - - #### Sanic Example - - $ swagger_py_codegen -s api.yml example-app -p demo -tlp=sanic - $ tree (sanic-demo) - . - |__ api.yml - |__ example-app - |__ demo - | |__ __init__.py - | |__ v1 - | |__ api - | | |__ __init__.py - | | |__ pets.py - | | |__ pets_petId.py - | |__ __init__.py - | |__ routes.py - | |__ schemas.py - | |__ validators.py - |__ requirements.txt - - - #### Run Web Server - - - Install example-app requirements: - - $ cd example-app - $ pip install -r requirements.txt - - Start example-app: - - $ cd demo - $ python __init__.py - - And generate example-app-ui from api.yml with ui: - - $ swagger_py_codegen -s api.yml example-app-ui -p demo-ui --ui --spec - - Then you can visit [http://127.0.0.1:5000/static/swagger-ui/index.html](http://127.0.0.1:5000/static/swagger-ui/index.html) in a browser. - - - - #### OAuth2 Scopes Usage - - - See the [wiki](https://github.com/guokr/swagger-py-codegen/wiki/OAuth2-Scopes-Usage) - - - - ## Compatibility - - - |component|compatibility| - - |-----|-----| - - |OpenAPI Spec|2.0| - - |Python|2.\*, 3.\*(Sanic only 3.\*)| - - - - ## Authors - - - See the [AUTHORS](https://github.com/guokr/swagger-py-codegen/blob/master/AUTHORS "Title"). - - - - ## License - - - MIT - - - [travis-url]: https://travis-ci.org/guokr/swagger-py-codegen - - [travis-image]: https://travis-ci.org/guokr/swagger-py-codegen.svg - - - [pypi-url]: https://pypi.python.org/pypi/swagger-py-codegen/ - - [pypi-image]: https://img.shields.io/pypi/v/swagger-py-codegen.svg?style=flat-square -domaindrivendev/rswag: >+ - rswag - - ========= - - [![Build Status](https://travis-ci.org/rswag/rswag.svg?branch=master)](https://travis-ci.org/rswag/rswag) - - [![Maintainability](https://api.codeclimate.com/v1/badges/1175b984edc4610f82ab/maintainability)](https://codeclimate.com/github/rswag/rswag/maintainability) - - - OpenApi 3.0 and Swagger 2.0 compatible! - - - Rswag extends rspec-rails "request specs" with a Swagger-based DSL for describing and testing API operations. You describe your API operations with a succinct, intuitive syntax, and it automaticaly runs the tests. Once you have green tests, run a rake task to auto-generate corresponding Swagger files and expose them as YAML or JSON endpoints. Rswag also provides an embedded version of the awesome [swagger-ui](https://github.com/swagger-api/swagger-ui) that's powered by the exposed file. This toolchain makes it seamless to go from integration specs, which youre probably doing in some form already, to living documentation for your API consumers. - - - Api Rswag creates [Swagger](http://swagger.io) tooling for Rails API's. Generate beautiful API documentation, including a UI to explore and test operations, directly from your rspec integration tests. - - - - And that's not all ... - - - Once you have an API that can describe itself in Swagger, you've opened the treasure chest of Swagger-based tools including a client generator that can be targeted to a wide range of popular platforms. See [swagger-codegen](https://github.com/swagger-api/swagger-codegen) for more details. - - - ## Compatibility ## - - - |Rswag Version|Swagger (OpenAPI) Spec.|swagger-ui| - - |----------|----------|----------| - - |[master](https://github.com/rswag/rswag/tree/master)|3.0.3|3.23.11| - - |[2.3.0](https://github.com/rswag/rswag/tree/2.3.0)|3.0.3|3.23.11| - - |[2.2.0](https://github.com/rswag/rswag/tree/2.2.0)|2.0|3.18.2| - - |[1.6.0](https://github.com/rswag/rswag/tree/1.6.0)|2.0|2.2.5| - - - - - - **Table of Contents** - - - - [rswag](#rswag) - - [Compatibility](#compatibility) - - [Getting Started](#getting-started) - - [The rspec DSL](#the-rspec-dsl) - - [Paths, Operations and Responses](#paths-operations-and-responses) - - [Null Values](#null-values) - - [Support for oneOf, anyOf or AllOf schemas](#support-for-oneof-anyof-or-allof-schemas) - - [Global Metadata](#global-metadata) - - [Supporting multiple versions of API](#supporting-multiple-versions-of-api) - - [Formatting the description literals:](#formatting-the-description-literals) - - [Specifying/Testing API Security](#specifyingtesting-api-security) - - [Configuration & Customization](#configuration--customization) - - [Output Location for Generated Swagger Files](#output-location-for-generated-swagger-files) - - [Input Location for Rspec Tests](#input-location-for-rspec-tests) - - [Referenced Parameters and Schema Definitions](#referenced-parameters-and-schema-definitions) - - [Response headers](#response-headers) - - [Response examples](#response-examples) - - [Enable auto generation examples from responses](#enable-auto-generation-examples-from-responses) - - [Running tests without documenting](#running-tests-without-documenting) - - [rswag helper methods](#rswag-helper-methods) - - [rswag response examples](#rswag-response-examples) - - [Route Prefix for Swagger JSON Endpoints](#route-prefix-for-swagger-json-endpoints) - - [Root Location for Swagger Files](#root-location-for-swagger-files) - - [Dynamic Values for Swagger JSON](#dynamic-values-for-swagger-json) - - [Custom Headers for Swagger Files](#custom-headers-for-swagger-files) - - [Enable Swagger Endpoints for swagger-ui](#enable-swagger-endpoints-for-swagger-ui) - - [Enable Simple Basic Auth for swagger-ui](#enable-simple-basic-auth-for-swagger-ui) - - [Route Prefix for the swagger-ui](#route-prefix-for-the-swagger-ui) - - [Customizing the swagger-ui](#customizing-the-swagger-ui) - - [Serve UI Assets Directly from your Web Server](#serve-ui-assets-directly-from-your-web-server) - - - - - - - ## Getting Started ## - - - 1. Add this line to your applications _Gemfile_: - - ```ruby - gem 'rswag' - ``` - - or if you like to avoid loading rspec in other bundler groups load the rswag-specs component separately. - Note: Adding it to the :development group is not strictly necessary, but without it, generators and rake tasks must be preceded by RAILS_ENV=test. - - ```ruby - # Gemfile - gem 'rswag-api' - gem 'rswag-ui' - - group :development, :test do - gem 'rspec-rails' - gem 'rswag-specs' - end - ``` - - 2. Run the install generator - - ```ruby - rails g rswag:install - ``` - - Or run the install generators for each package separately if you installed Rswag as separate gems, as indicated above: - - ```ruby - rails g rswag:api:install - rails g rswag:ui:install - RAILS_ENV=test rails g rswag:specs:install - ``` - - 3. Create an integration spec to describe and test your API. - - There is also a generator which can help get you started `rails generate rspec:swagger API::MyController` - - ```ruby - # spec/integration/blogs_spec.rb - require 'swagger_helper' - - describe 'Blogs API' do - - path '/blogs' do - - post 'Creates a blog' do - tags 'Blogs' - consumes 'application/json' - parameter name: :blog, in: :body, schema: { - type: :object, - properties: { - title: { type: :string }, - content: { type: :string } - }, - required: [ 'title', 'content' ] - } - - response '201', 'blog created' do - let(:blog) { { title: 'foo', content: 'bar' } } - run_test! - end - - response '422', 'invalid request' do - let(:blog) { { title: 'foo' } } - run_test! - end - end - end - - path '/blogs/{id}' do - - get 'Retrieves a blog' do - tags 'Blogs' - produces 'application/json', 'application/xml' - parameter name: :id, in: :path, type: :string - - response '200', 'blog found' do - schema type: :object, - properties: { - id: { type: :integer }, - title: { type: :string }, - content: { type: :string } - }, - required: [ 'id', 'title', 'content' ] - - let(:id) { Blog.create(title: 'foo', content: 'bar').id } - run_test! - end - - response '404', 'blog not found' do - let(:id) { 'invalid' } - run_test! - end - - response '406', 'unsupported accept header' do - let(:'Accept') { 'application/foo' } - run_test! - end - end - end - end - ``` - - - 4. Generate the Swagger JSON file(s) - - ```ruby - rake rswag:specs:swaggerize - ``` - - This common command is also aliased as `rake rswag`. - - Or if you installed your gems separately: - ``` - RAILS_ENV=test rails rswag - ``` - - 5. Spin up your app and check out the awesome, auto-generated docs at _/api-docs_! - - - ## The rspec DSL ## - - - ### Paths, Operations and Responses ### - - - If you've used [Swagger](http://swagger.io/specification) before, then the syntax should be very familiar. To describe your API operations, start by specifying a path and then list the supported operations (i.e. HTTP verbs) for that path. Path parameters must be surrounded by curly braces ({}). Within an operation block (see "post" or "get" in the example above), most of the fields supported by the [Swagger "Operation" object](http://swagger.io/specification/#operationObject) are available as methods on the example group. To list (and test) the various responses for an operation, create one or more response blocks. Again, you can reference the [Swagger "Response" object](http://swagger.io/specification/#responseObject) for available fields. - - - Take special note of the __run_test!__ method that's called within each response block. This tells rswag to create and execute a corresponding example. It builds and submits a request based on parameter descriptions and corresponding values that have been provided using the rspec "let" syntax. For example, the "post" description in the example above specifies a "body" parameter called "blog". It also lists 2 different responses. For the success case (i.e. the 201 response), notice how "let" is used to set the blog parameter to a value that matches the provided schema. For the failure case (i.e. the 422 response), notice how it's set to a value that does not match the provided schema. When the test is executed, rswag also validates the actual response code and, where applicable, the response body against the provided [JSON Schema](http://json-schema.org/documentation.html). - - - If you want to do additional validation on the response, pass a block to the __run_test!__ method: - - - ```ruby - - response '201', 'blog created' do - run_test! do |response| - data = JSON.parse(response.body) - expect(data['title']).to eq('foo') - end - end - - ``` - - - If you'd like your specs to be a little more explicit about what's going on here, you can replace the call to __run_test!__ with equivalent "before" and "it" blocks: - - - ```ruby - - response '201', 'blog created' do - let(:blog) { { title: 'foo', content: 'bar' } } - - before do |example| - submit_request(example.metadata) - end - - it 'returns a valid 201 response' do |example| - assert_response_matches_metadata(example.metadata) - end - end - - ``` - - - ### Null Values ### - - - This library is currently using JSON::Draft4 for validation of response models. Nullable properties can be supported with the non-standard property 'x-nullable' to a definition to allow null/nil values to pass. Or you can add the new standard ```nullable``` property to a definition. - - ```ruby - - describe 'Blogs API' do - path '/blogs' do - post 'Creates a blog' do - ... - - response '200', 'blog found' do - schema type: :object, - properties: { - id: { type: :integer }, - title: { type: :string, nullable: true }, # preferred syntax - content: { type: :string, 'x-nullable': true } # legacy syntax, but still works - } - .... - end - end - end - end - - ``` - - - ### Support for oneOf, anyOf or AllOf schemas ### - - - Open API 3.0 now supports more flexible schema validation with the ```oneOf```, ```anyOf``` and ```allOf``` directives. rswag will handle these definitions and validate them properly. - - - - Notice the ```schema``` inside the ```response``` section. Placing a ```schema``` method inside the response will validate (and fail the tests) - - if during the integration test run the endpoint response does not match the response schema. This test validation can handle anyOf and allOf as well. See below: - - - ```ruby - - path '/blogs/flexible' do - post 'Creates a blog flexible body' do - tags 'Blogs' - description 'Creates a flexible blog from provided data' - operationId 'createFlexibleBlog' - consumes 'application/json' - produces 'application/json' - - parameter name: :blog, in: :body, schema: { - oneOf: [ - { '$ref' => '#/components/schemas/blog' }, - { '$ref' => '#/components/schemas/flexible_blog' } - ] - } - - response '201', 'flexible blog created' do - schema oneOf: [{ '$ref' => '#/components/schemas/blog' }, { '$ref' => '#/components/schemas/flexible_blog' }] - run_test! - end - end - end - - ``` - - This automatic schema validation is a powerful feature of rswag. - - - ### Global Metadata ### - - - In addition to paths, operations and responses, Swagger also supports global API metadata. When you install rswag, a file called _swagger_helper.rb_ is added to your spec folder. This is where you define one or more Swagger documents and provide global metadata. Again, the format is based on Swagger so most of the global fields supported by the top level ["Swagger" object](http://swagger.io/specification/#swaggerObject) can be provided with each document definition. As an example, you could define a Swagger document for each version of your API and in each case specify a title, version string. In Open API 3.0 the pathing and server definitions have changed a bit [Swagger host/basePath](https://swagger.io/docs/specification/api-host-and-base-path/): - - - ```ruby - - # spec/swagger_helper.rb - - RSpec.configure do |config| - config.swagger_root = Rails.root.to_s + '/swagger' - - config.swagger_docs = { - 'v1/swagger.json' => { - openapi: '3.0.1', - info: { - title: 'API V1', - version: 'v1', - description: 'This is the first version of my API' - }, - servers: [ - { - url: 'https://{defaultHost}', - variables: { - defaultHost: { - default: 'www.example.com' - } - } - } - ] - }, - - 'v2/swagger.yaml' => { - openapi: '3.0.1', - info: { - title: 'API V2', - version: 'v2', - description: 'This is the second version of my API' - }, - servers: [ - { - url: 'https://{defaultHost}', - variables: { - defaultHost: { - default: 'www.example.com' - } - } - } - ] - } - } - end - - ``` - - - #### Supporting multiple versions of API #### - - By default, the paths, operations and responses defined in your spec files will be associated with the first Swagger document in _swagger_helper.rb_. If your API has multiple versions, you should be using separate documents to describe each of them. In order to assign a file with a given version of API, you'll need to add the ```swagger_doc``` tag to each spec specifying its target document name: - - - ```ruby - - # spec/integration/v2/blogs_spec.rb - - describe 'Blogs API', swagger_doc: 'v2/swagger.yaml' do - - path '/blogs' do - ... - - path '/blogs/{id}' do - ... - end - - ``` - - - #### Formatting the description literals: #### - - Swagger supports the Markdown syntax to format strings. This can be especially handy if you were to provide a long description of a given API version or endpoint. Use [this guide](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) for reference. - - - __NOTE:__ There is one difference between the official Markdown syntax and Swagger interpretation, namely tables. To create a table like this: - - - | Column1 | Collumn2 | - - | ------- | -------- | - - | cell1 | cell2 | - - - you should use the folowing syntax, making sure there are no whitespaces at the start of any of the lines: - - - ``` - - - - | Column1 | Collumn2 | - - | ------- | -------- | - - | cell1 | cell2 | - - - - ``` - - - ### Specifying/Testing API Security ### - - - Swagger allows for the specification of different security schemes and their applicability to operations in an API. - - To leverage this in rswag, you define the schemes globally in _swagger_helper.rb_ and then use the "security" attribute at the operation level to specify which schemes, if any, are applicable to that operation. - - Swagger supports :basic, :bearer, :apiKey and :oauth2 and :openIdConnect scheme types. See [the spec](https://swagger.io/docs/specification/authentication/) for more info, as this underwent major changes between Swagger 2.0 and Open API 3.0 - - - ```ruby - - # spec/swagger_helper.rb - - RSpec.configure do |config| - config.swagger_root = Rails.root.to_s + '/swagger' - - config.swagger_docs = { - 'v1/swagger.json' => { - ... # note the new Open API 3.0 compliant security structure here, under "components" - components: { - securitySchemes: { - basic_auth: { - type: :http, - scheme: :basic - }, - api_key: { - type: :apiKey, - name: 'api_key', - in: :query - } - } - } - } - } - end - - - # spec/integration/blogs_spec.rb - - describe 'Blogs API' do - - path '/blogs' do - - post 'Creates a blog' do - tags 'Blogs' - security [ basic_auth: [] ] - ... - - response '201', 'blog created' do - let(:Authorization) { "Basic #{::Base64.strict_encode64('jsmith:jspass')}" } - run_test! - end - - response '401', 'authentication failed' do - let(:Authorization) { "Basic #{::Base64.strict_encode64('bogus:bogus')}" } - run_test! - end - end - end - end - - - # example of documenting an endpoint that handles basic auth and api key based security - - describe 'Auth examples API' do - path '/auth-tests/basic-and-api-key' do - post 'Authenticates with basic auth and api key' do - tags 'Auth Tests' - operationId 'testBasicAndApiKey' - security [{ basic_auth: [], api_key: [] }] - - response '204', 'Valid credentials' do - let(:Authorization) { "Basic #{::Base64.strict_encode64('jsmith:jspass')}" } - let(:api_key) { 'foobar' } - run_test! - end - - response '401', 'Invalid credentials' do - let(:Authorization) { "Basic #{::Base64.strict_encode64('jsmith:jspass')}" } - let(:api_key) { 'barfoo' } - run_test! - end - end - end - end - - - ``` - - - __NOTE:__ Depending on the scheme types, you'll be required to assign a corresponding parameter value with each example. - - For example, :basic auth is required above and so the :Authorization (header) parameter must be set accordingly - - - ## Configuration & Customization ## - - - The steps described above will get you up and running with minimal setup. However, rswag offers a lot of flexibility to customize as you see fit. Before exploring the various options, you'll need to be aware of it's different components. The following table lists each of them and the files that get added/updated as part of a standard install. - - - |Gem|Description|Added/Updated| - - |---------|-----------|-------------| - - |__rswag-specs__|Swagger-based DSL for rspec & accompanying rake task for generating Swagger files|_spec/swagger_helper.rb_| - - |__rswag-api__ |Rails Engine that exposes your Swagger files as JSON endpoints|_config/initializers/rswag_api.rb, config/routes.rb_| - - |__rswag-ui__ |Rails Engine that includes [swagger-ui](https://github.com/swagger-api/swagger-ui) and powers it from your Swagger endpoints|_config/initializers/rswag-ui.rb, config/routes.rb_| - - - ### Output Location for Generated Swagger Files ### - - - You can adjust this in the _swagger_helper.rb_ that's installed with __rswag-specs__: - - - ```ruby - - # spec/swagger_helper.rb - - RSpec.configure do |config| - config.swagger_root = Rails.root.to_s + '/your-custom-folder-name' - ... - end - - ``` - - - __NOTE__: If you do change this, you'll also need to update the rswag_api.rb initializer (assuming you're using rswag-api). More on this later. - - - ### Input Location for Rspec Tests ### - - - By default, rswag will search for integration tests in _spec/requests_, _spec/api_ and _spec/integration_. If you want to use tests from other locations, provide the PATTERN argument to rake: - - - ```ruby - - # search for tests in spec/swagger - - rake rswag:specs:swaggerize PATTERN="spec/swagger/**/*_spec.rb" - - ``` - - - ### Referenced Parameters and Schema Definitions ### - - - Swagger allows you to describe JSON structures inline with your operation descriptions OR as referenced globals. - - For example, you might have a standard response structure for all failed operations. - - Again, this is a structure that changed since swagger 2.0. Notice the new "schemas" section for these. - - Rather than repeating the schema in every operation spec, you can define it globally and provide a reference to it in each spec: - - - ```ruby - - # spec/swagger_helper.rb - - config.swagger_docs = { - 'v1/swagger.json' => { - openapi: '3.0.0', - info: { - title: 'API V1' - }, - components: { - schemas: { - errors_object: { - type: 'object', - properties: { - errors: { '$ref' => '#/components/schemas/errors_map' } - } - }, - errors_map: { - type: 'object', - additionalProperties: { - type: 'array', - items: { type: 'string' } - } - }, - blog: { - type: 'object', - properties: { - id: { type: 'integer' }, - title: { type: 'string' }, - content: { type: 'string', nullable: true }, - thumbnail: { type: 'string', nullable: true } - }, - required: %w[id title] - } - } - } - } - } - - - # spec/integration/blogs_spec.rb - - describe 'Blogs API' do - - path '/blogs' do - - post 'Creates a blog' do - - response 422, 'invalid request' do - schema '$ref' => '#/components/schemas/errors_object' - ... - end - - - # spec/integration/comments_spec.rb - - describe 'Blogs API' do - - path '/blogs/{blog_id}/comments' do - - post 'Creates a comment' do - - response 422, 'invalid request' do - schema '$ref' => '#/components/schemas/errors_object' - ... - end - - ``` - - - ### Response headers ### - - - In Rswag, you could use `header` method inside the response block to specify header objects for this response. - - Rswag will validate your response headers with those header objects and inject them into the generated swagger file: - - - ```ruby - - # spec/integration/comments_spec.rb - - describe 'Blogs API' do - - path '/blogs/{blog_id}/comments' do - - post 'Creates a comment' do - - response 422, 'invalid request' do - header 'X-Rate-Limit-Limit', type: :integer, description: 'The number of allowed requests in the current period' - header 'X-Rate-Limit-Remaining', type: :integer, description: 'The number of remaining requests in the current period' - ... - end - - ``` - - - ### Response examples ### - - - You can provide custom response examples to the generated swagger file by calling the method `examples` inside the response block: - - However, auto generated example responses are now enabled by default in rswag. See below. - - ```ruby - - # spec/integration/blogs_spec.rb - - describe 'Blogs API' do - - path '/blogs/{blog_id}' do - - get 'Retrieves a blog' do - - response 200, 'blog found' do - examples 'application/json' => { - id: 1, - title: 'Hello world!', - content: '...' - } - ... - end - - ``` - - - - ### Enable auto generation examples from responses ### - - - - To enable examples generation from responses add callback above run_test! like: - - - ``` - - after do |example| - example.metadata[:response][:examples] = { 'application/json' => JSON.parse(response.body, symbolize_names: true) } - end - - ``` - - - You need to disable --dry-run option for Rspec > 3 - - - - - - Add to config/environments/test.rb: - - ```ruby - - RSpec.configure do |config| - config.swagger_dry_run = false - end - - ``` - - - #### Running tests without documenting #### - - - If you want to use Rswag for testing without adding it to you swagger docs, you can provide the document tag: - - ```ruby - - describe 'Blogs API' do - path '/blogs/{blog_id}' do - get 'Retrieves a blog' do - # documentation is now disabled for this response only - response 200, 'blog found', document: false do - ... - ``` - - - You can also reenable documentation for specific responses only: - - ```ruby - - # documentation is now disabled - - describe 'Blogs API', document: false do - path '/blogs/{blog_id}' do - get 'Retrieves a blog' do - # documentation is reenabled for this response only - response 200, 'blog found', document: true do - ... - end - - response 401, 'special case' do - ... - end - ``` - - - ##### rswag helper methods ##### - - - ### Route Prefix for Swagger JSON Endpoints ### - - - The functionality to expose Swagger files, such as those generated by rswag-specs, as JSON endpoints is implemented as a Rails Engine. As with any Engine, you can change it's mount prefix in _routes.rb_: - - - ```ruby - - TestApp::Application.routes.draw do - ... - - mount Rswag::Api::Engine => 'your-custom-prefix' - end - - ``` - - - Assuming a Swagger file exists at <swagger_root>/v1/swagger.json, this configuration would expose the file as the following JSON endpoint: - - - ``` - - GET http:///your-custom-prefix/v1/swagger.json - - ``` - - - ### Root Location for Swagger Files ### - - - You can adjust this in the _rswag_api.rb_ initializer that's installed with __rspec-api__: - - - ```ruby - - Rswag::Api.configure do |c| - c.swagger_root = Rails.root.to_s + '/your-custom-folder-name' - ... - end - - ``` - - - __NOTE__: If you're using rswag-specs to generate Swagger files, you'll want to ensure they both use the same <swagger_root>. The reason for separate settings is to maintain independence between the two gems. For example, you could install rswag-api independently and create your Swagger files manually. - - - ### Dynamic Values for Swagger JSON ## - - - There may be cases where you need to add dynamic values to the Swagger JSON that's returned by rswag-api. For example, you may want to provide an explicit host name. Rather than hardcoding it, you can configure a filter that's executed prior to serializing every Swagger document: - - - ```ruby - - Rswag::Api.configure do |c| - ... - - c.swagger_filter = lambda { |swagger, env| swagger['host'] = env['HTTP_HOST'] } - end - - ``` - - - Note how the filter is passed the rack env for the current request. This provides a lot of flexibilty. For example, you can assign the "host" property (as shown) or you could inspect session information or an Authorization header and remove operations based on user permissions. - - - ### Custom Headers for Swagger Files ### - - - You can specify custom headers for serving your generated Swagger JSON. For example you may want to force a specific charset for the 'Content-Type' header. You can configure a hash of headers to be sent with the request: - - - ```ruby - - Rswag::Api.configure do |c| - ... - - c.swagger_headers = { 'Content-Type' => 'application/json; charset=UTF-8' } - end - - ``` - - - Take care when overriding Content-Type if you serve both YAML and JSON files as it will no longer switch the Content-Type header correctly. - - - - ### Enable Swagger Endpoints for swagger-ui ### - - - You can update the _rswag-ui.rb_ initializer, installed with rswag-ui, to specify which Swagger endpoints should be available to power the documentation UI. If you're using rswag-api, these should correspond to the Swagger endpoints it exposes. When the UI is rendered, you'll see these listed in a drop-down to the top right of the page: - - - ```ruby - - Rswag::Ui.configure do |c| - c.swagger_endpoint '/api-docs/v1/swagger.json', 'API V1 Docs' - c.swagger_endpoint '/api-docs/v2/swagger.json', 'API V2 Docs' - end - - ``` - - - ### Enable Simple Basic Auth for swagger-ui - - - You can also update the _rswag-ui.rb_ initializer, installed with rswag-ui to specify a username and password should you want to keep your documentation private. - - - ```ruby - - Rswag::Ui.configure do |c| - c.basic_auth_enabled = true - c.basic_auth_credentials 'username', 'password' - end - - ``` - - - ### Route Prefix for the swagger-ui ### - - - Similar to rswag-api, you can customize the swagger-ui path by changing it's mount prefix in _routes.rb_: - - - ```ruby - - TestApp::Application.routes.draw do - ... - - mount Rswag::Api::Engine => 'api-docs' - mount Rswag::Ui::Engine => 'your-custom-prefix' - end - - ``` - - - ### Customizing the swagger-ui ### - - - The swagger-ui provides several options for customizing it's behavior, all of which are documented here https://github.com/swagger-api/swagger-ui/tree/2.x#swaggerui. If you need to tweak these or customize the overall look and feel of your swagger-ui, then you'll need to provide your own version of index.html. You can do this with the following generator. - - - ```ruby - - rails g rswag:ui:custom - - - ``` - - - This will add a local version that you can modify at _app/views/rswag/ui/home/index.html.erb_ - - - ### Serve UI Assets Directly from your Web Server - - - Rswag ships with an embedded version of the [swagger-ui](https://github.com/swagger-api/swagger-ui), which is a static collection of JavaScript and CSS files. These assets are served by the rswag-ui middleware. However, for optimal performance you may want to serve them directly from your web server (e.g. Apache or NGINX). To do this, you'll need to copy them to the web server root. This is the "public" folder in a typical Rails application. - - - ``` - - bundle exec rake rswag:ui:copy_assets[public/api-docs] - - ``` - - - __NOTE:__: The provided subfolder MUST correspond to the UI mount prefix - "api-docs" by default. - - - - Notes to test swagger output locally with swagger editor - - ``` - - docker pull swaggerapi/swagger-editor - - ``` - - ``` - - docker run -d -p 80:8080 swaggerapi/swagger-editor - - ``` - - This will run the swagger editor in the docker daemon and can be accessed - - at ```http://localhost```. From here, you can use the UI to load the generated swagger.json to validate the output. - -drewish/rspec-rails-swagger: > - # RSpec Rails Swagger - - - [![Build Status](https://travis-ci.org/drewish/rspec-rails-swagger.svg?branch=master)](https://travis-ci.org/drewish/rspec-rails-swagger) - - [![Code Climate](https://codeclimate.com/github/drewish/rspec-rails-swagger/badges/gpa.svg)](https://codeclimate.com/github/drewish/rspec-rails-swagger) - - - This gem helps you generate Swagger docs by using RSpec to document the paths. - - You execute a command to run the tests and generate the `.yaml` or `.json` output. - - Running the tests ensures that your API and docs are in agreement, and generates - - output that can be saved as response examples. - - - The design of this was heavily influenced by the awesome [swagger_rails gem](https://github.com/domaindrivendev/swagger_rails). - - - ## Setup - - - Add the gem to your Rails app's `Gemfile`: - - ```rb - - group :development, :test do - gem 'rspec-rails-swagger' - end - - ``` - - - Update your bundle: - - ``` - - bundle install - - ``` - - - If you don't have a `spec/rails_helper.rb` file: - - ``` - - rails generate rspec:install - - ``` - - - Create the `spec/swagger_helper.rb` file: - - ``` - - rails generate rspec:swagger_install - - ``` - - - ## Documenting Your API - - - Now you can edit `spec/swagger_helper.rb` and start filling in the top level - - Swagger documentation, e.g. basePath, [definitions](http://swagger.io/specification/#definitionsObject), - - [parameters](http://swagger.io/specification/#parametersDefinitionsObject), - - [tags](http://swagger.io/specification/#tagObject), etc. - - - You can use the generator to create a spec to documentation a controller: - - - ``` - - rails generate rspec:swagger PostsController - - ``` - - - That will create a `spec/requests/posts_spec.rb` file with the paths, operations - - and some default requests filled in. With the structure in place you should only - - need to add `before` calls to create records and then update the `let`s to - - return the appropriate values. - - - ## Generate the JSON or YAML - - - To create the Swagger files use the rake task: - - - ``` - - bundle exec rake swagger - - ``` - - - Now you can use Swagger UI or the renderer of your choice to display the - - formatted documentation. [swagger_engine](https://github.com/batdevis/swagger_engine) - - works pretty well and supports multiple documents. - - - ## RSpec DSL - - - The DSL follows the hierarchy of the Swagger Schema: - - - - [Paths Object](http://swagger.io/specification/#paths-object-29) - - [Path Item Object](http://swagger.io/specification/#path-item-object-32) - - [Parameter Object](http://swagger.io/specification/#parameter-object-44)s (Optional) - - [Operation Object](http://swagger.io/specification/#operation-object-36) - - [Parameter Object](http://swagger.io/specification/#parameter-object-44)s (Optional) - - [Responses Object](http://swagger.io/specification/#responses-object-54) - - [Response Object](http://swagger.io/specification/#response-object-58) - - [Example Object](http://swagger.io/specification/#example-object-65)s (Optional) - - Here's an example of a spec with comments to for the corresponding objects: - - - ```rb - - require 'swagger_helper' - - - # Paths Object - - RSpec.describe "Posts Controller", type: :request do - before { Post.new.save } - - # Path Item Object - path '/posts' do - # Operation Object - operation "GET", summary: "fetch list" do - # Response Object - response 200, description: "successful" - end - end - - # Path Object - path '/posts/{post_id}' do - # Parameter Object - parameter "post_id", { in: :path, type: :integer } - let(:post_id) { 1 } - - # Operation Object - get summary: "fetch item" do - # Response Object - response 200, description: "success" - end - end - - # Path Post Object - path '/posts/' do - # Parameter Object for content type could be defined like: - consumes 'application/json' - # or: - parameter 'Content-Type', { in: :header, type: :string } - let(:'Content-Type') { 'application/json' } - # one of them would be considered - - # authorization token in the header: - parameter 'Authorization', { in: :header, type: :string } - let(:'Authorization') { 'Bearer ' } - - # Parameter Object - parameter "post_id", { in: :path, type: :integer } - let(:post_id) { 1 } - - # Parameter Object for Body - parameter "body", { in: :body, required: true, schema: { - type: :object, - properties: { - title: { type: :string }, - author_email: { type: :email } - } - } - let (:body) { - { post: - { title: 'my example', - author_email: 'me@example.com' } - } - } - } - # checkout http://swagger.io/specification/#parameter-object-44 for more information, options and details - - # Operation Object - post summary: "update an item" do - # Response Object - response 200, description: "success" - end - # ... - end - - ``` - - - - ### Paths Object - - These methods are available inside of an RSpec contexts with the `type: :request` tag. - - - #### `path(template, attributes = {}, &block)` - - Defines a new Path Item. - - - The `attributes` parameter accepts: - - - `swagger_doc` a key in `RSpec.configuration.swagger_docs` that determines - which file the path belongs in. - - `tags` with an array of tags that will be applied to the child Operations. - - - You can also provide a default file and tags by setting them on a parent RSpec - - context block: - - ```rb - - RSpec.describe "Sample Requests", type: :request do - # The swagger_doc will be used as a default for the paths defined within the - # context block. Similarly, the tags will be merged with those set on paths - # defined within them. - context "setting defaults", swagger_doc: 'default_document.json', tags: [:context_tag] do - path '/posts', swagger_doc: 'overridden_document.yaml' tags: ['path_tag'] do - operation "GET", summary: "fetch list" do - produces 'application/json' - tags 'operation_tag' - - response(200, { description: "successful" }) - end - end - end - end - - ``` - - The `GET /posts` operation in this example will be saved in the `'overridden_document.yaml'` - - file and tagged with `["context_tag", "path_tag", "operation_tag"]`. - - - - ### Path Item Object - - These methods are available inside of blocks passed to the `path` method. - - - #### `operation(method, attributes = {}, &block)` - - Defines a new Operation Object. The `method` is case insensitive. - - - The `attributes` parameter accepts: - - - `tags` with an array of tags. These will be merged with tags passed to the - Path Item or `tags` method inside the Operation's block. - - #### `delete(attributes = {}, &block)` - - Alias for `operation(:delete, attributes, block)`. - - - #### `get(attributes = {}, &block)` - - Alias for `operation(:get, attributes, block)`. - - - #### `head(attributes = {}, &block)` - - Alias for `operation(:head, attributes, block)`. - - - #### `options(attributes = {}, &block)` - - Alias for `operation(:options, attributes, block)`. - - - #### `patch(attributes = {}, &block)` - - Alias for `operation(:patch, attributes, block)`. - - - #### `post(attributes = {}, &block)` - - Alias for `operation(:post, attributes, block)`. - - - #### `put(attributes = {}, &block)` - - Alias for `operation(:put, attributes, block)`. - - - - ### Parameters - - These methods are available inside of blocks passed to the `path` or `operation` method. - - - #### `parameter(name, attributes = {})` - - Defines a new Parameter Object. You can define the parameter inline: - - ```rb - - parameter :callback_url, in: :query, type: :string, required: true - - ``` - - - Or, via reference: - - ```rb - - parameter ref: "#/parameters/site_id" - - ``` - - - Values for the parameters are set using `let`: - - ```rb - - post summary: "create" do - parameter "body", in: :body, schema: { foo: :bar } - let(:body) { { post: { title: 'asdf', body: "blah" } } } - # ... - end - - ``` - - - - ### Operation Object - - These methods are available inside of blocks passed to the `operation` method. - - - #### `consumes(*mime_types)` - - Use this to add MIME types that are specific to the operation. They will be merged - - with the Swagger Object's consumes field. - - ```rb - - consumes 'application/json', 'application/xml' - - ``` - - - #### `produces(*mime_types)` - - Use this to add MIME types that are specific to the operation. They will be merged - - with the Swagger Object's consumes field. - - ```rb - - produces 'application/json', 'application/xml' - - ``` - - - #### `response(status_code, attributes = {}, &block)` - - Defines a new Response Object. `status_code` must be between 1 and 599. `attributes` - - must include a `description`. - - - #### `tags(*tags)` - - Adds operation specific tags. - - ```rb - - tags :accounts, :pets - - ``` - - - You can also provide tags through the RSpec context block and/or `path` method: - - ```rb - - RSpec.describe "Sample Requests", type: :request, tags: [:context_tag] do - path '/posts', tags: ['path_tag'] do - operation "GET", summary: "fetch list" do - produces 'application/json' - tags 'operation_tag' - - response(200, { description: "successful" }) - end - end - end - - ``` - - These tags will be merged with those of the operation. The `GET /posts` operation - - in this example will be tagged with `["context_tag", "path_tag", "operation_tag"]`. - - - - ### Response Object - - These methods are available inside of blocks passed to the `response` method. - - - #### `capture_example()` - - This method will capture the response body from the test and create an Example - - Object for the Response. - - - You could also set this in an RSpec context block if you'd like examples for - - multiple operations or paths: - - ```rb - - describe 'Connections', type: :request, capture_examples: true do - # Any requests in this block will capture example responses - end - - ``` - - - #### `schema(definition)` - - Sets the schema field for the Response Object. You can define it inline: - - ```rb - - schema( - type: :array, - items: { - type: :object, - properties: { - id: { type: :string }, - name: { type: :string }, - }, - } - ) - - ``` - - - Or, by reference: - - ```rb - - schema ref: '#/definitions/Account' - - ``` -zalando/connexion: > - Connexion - - ========= - - - .. image:: https://badges.gitter.im/zalando/connexion.svg - :alt: Join the chat at https://gitter.im/zalando/connexion - :target: https://gitter.im/zalando/connexion?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge - - .. image:: https://github.com/zalando/connexion/actions/workflows/pipeline.yml/badge.svg - :alt: Build status - :target: https://github.com/zalando/connexion/actions/workflows/pipeline.yml - - .. image:: https://coveralls.io/repos/github/zalando/connexion/badge.svg?branch=main - :target: https://coveralls.io/github/zalando/connexion?branch=main - :alt: Coveralls status - - .. image:: https://img.shields.io/pypi/v/connexion.svg - :target: https://pypi.python.org/pypi/connexion - :alt: Latest Version - - .. image:: https://img.shields.io/pypi/status/connexion.svg - :target: https://pypi.python.org/pypi/connexion - :alt: Development Status - - .. image:: https://img.shields.io/pypi/pyversions/connexion.svg - :target: https://pypi.python.org/pypi/connexion - :alt: Python Versions - - .. image:: https://img.shields.io/pypi/l/connexion.svg - :target: https://github.com/zalando/connexion/blob/main/LICENSE.txt - :alt: License - - Connexion is a framework that automagically handles HTTP requests based on `OpenAPI Specification`_ - - (formerly known as Swagger Spec) of your API described in `YAML format`_. Connexion allows you to - - write an OpenAPI specification, then maps the endpoints to your Python functions; this makes it - - unique, as many tools generate the specification based on your Python code. You can describe your - - REST API in as much detail as you want; then Connexion guarantees that it will work as you - - specified. - - - We built Connexion this way in order to: - - - - simplify the development process - - - confirm expectations about what your API will look like - - - Connexion Features: - - ------------------- - - - - Validates requests and endpoint parameters automatically, based on - your specification - - Provides a Web Swagger Console UI so that the users of your API can - have live documentation and even call your API's endpoints - through it - - Handles OAuth 2 token-based authentication - - - Supports API versioning - - - Supports automatic serialization of payloads. If your - specification defines that an endpoint returns JSON, Connexion will - automatically serialize the return value for you and set the right - content type in the HTTP header. - - Why Connexion - - ------------- - - - With Connexion, you write the spec first. Connexion then calls your Python - - code, handling the mapping from the specification to the code. This - - incentivizes you to write the specification so that all of your - - developers can understand what your API does, even before you write a - - single line of code. - - - If multiple teams depend on your APIs, you can use Connexion to easily send them the documentation of your API. This guarantees that your API will follow the specification that you wrote. This is a different process from that offered by frameworks such as Hug_, which generates a specification *after* you've written the code. Some disadvantages of generating specifications based on code is that they often end up lacking details or mix your documentation with the code logic of your application. - - - Other Sources/Mentions - - ---------------------- - - - - Zalando RESTful API guidelines with `API First`_ - - - Connexion listed on Swagger_'s website - - - Blog post: `Crafting effective Microservices in Python`_ - - - New in Connexion 2.0: - - --------------------- - - - App and Api options must be provided through the "options" argument (``old_style_options`` have been removed). - - - You must specify a form content-type in 'consumes' in order to consume form data. - - - The `Operation` interface has been formalized in the `AbstractOperation` class. - - - The `Operation` class has been renamed to `Swagger2Operation`. - - - Array parameter deserialization now follows the Swagger 2.0 spec more closely. - In situations when a query parameter is passed multiple times, and the collectionFormat is either csv or pipes, the right-most value will be used. - For example, `?q=1,2,3&q=4,5,6` will result in `q = [4, 5, 6]`. - The old behavior is available by setting the collectionFormat to `multi`, or by importing `decorators.uri_parsing.AlwaysMultiURIParser` and passing `parser_class=AlwaysMultiURIParser` to your Api. - - The spec validator library has changed from `swagger-spec-validator` to `openapi-spec-validator`. - - - Errors that previously raised `SwaggerValidationError` now raise the `InvalidSpecification` exception. - All spec validation errors should be wrapped with `InvalidSpecification`. - - Support for nullable/x-nullable, readOnly and writeOnly/x-writeOnly has been added to the standard json schema validator. - - - Custom validators can now be specified on api level (instead of app level). - - - Added support for basic authentication and apikey authentication - - - If unsupported security requirements are defined or ``x-tokenInfoFunc``/``x-tokenInfoUrl`` is missing, connexion now denies requests instead of allowing access without security-check. - - - Accessing ``connexion.request.user`` / ``flask.request.user`` is no longer supported, use ``connexion.context['user']`` instead - - - How to Use - - ========== - - - Prerequisites - - ------------- - - - Python 3.6+ - - - Installing It - - ------------- - - - In your command line, type: - - - .. code-block:: bash - - $ pip install connexion - - Running It - - ---------- - - - Place your API YAML inside a folder in the root - - path of your application (e.g ``swagger/``). Then run: - - - .. code-block:: python - - import connexion - - app = connexion.App(__name__, specification_dir='swagger/') - app.add_api('my_api.yaml') - app.run(port=8080) - - See the `Connexion Pet Store Example Application`_ for a sample - - specification. - - - Now you're able to run and use Connexion! - - - - OAuth 2 Authentication and Authorization - - ---------------------------------------- - - - Connexion supports one of the three OAuth 2 handling methods. (See - - "TODO" below.) With Connexion, the API security definition **must** - - include a 'x-tokenInfoUrl' or 'x-tokenInfoFunc (or set ``TOKENINFO_URL`` - - or ``TOKENINFO_FUNC`` env var respectively). 'x-tokenInfoUrl' must contain an - - URL to validate and get the `token information`_ and 'x-tokenInfoFunc must - - contain a reference to a function used to obtain the token info. When both 'x-tokenInfoUrl' - - and 'x-tokenInfoFunc' are used, Connexion will prioritize the function method. Connexion expects to - - receive the OAuth token in the ``Authorization`` header field in the - - format described in `RFC 6750 `_ section 2.1. This aspect - - represents a significant difference from the usual OAuth flow. - - - Dynamic Rendering of Your Specification - - --------------------------------------- - - - Connexion uses Jinja2_ to allow specification parameterization through the ``arguments`` parameter. You can define specification arguments for the application either globally (via the ``connexion.App`` constructor) or for each specific API (via the ``connexion.App#add_api`` method): - - - .. code-block:: python - - app = connexion.App(__name__, specification_dir='swagger/', - arguments={'global': 'global_value'}) - app.add_api('my_api.yaml', arguments={'api_local': 'local_value'}) - app.run(port=8080) - - When a value is provided both globally and on the API, the API value will take precedence. - - - Endpoint Routing to Your Python Views - - ------------------------------------- - - - Connexion uses the ``operationId`` from each `Operation Object`_ to - - identify which Python function should handle each URL. - - - **Explicit Routing**: - - - .. code-block:: yaml - - paths: - /hello_world: - post: - operationId: myapp.api.hello_world - - If you provide this path in your specification POST requests to - - ``http://MYHOST/hello_world``, it will be handled by the function - - ``hello_world`` in the ``myapp.api`` module. Optionally, you can include - - ``x-swagger-router-controller`` (or ``x-openapi-router-controller``) in your - - operation definition, making ``operationId`` relative: - - - .. code-block:: yaml - - paths: - /hello_world: - post: - x-swagger-router-controller: myapp.api - operationId: hello_world - - Keep in mind that Connexion follows how `HTTP methods work in Flask`_ and therefore HEAD requests will be handled by the ``operationId`` specified under GET in the specification. If both methods are supported, ``connexion.request.method`` can be used to determine which request was made. - - - Automatic Routing - - ----------------- - - - To customize this behavior, Connexion can use alternative - - ``Resolvers``--for example, ``RestyResolver``. The ``RestyResolver`` - - will compose an ``operationId`` based on the path and HTTP method of - - the endpoints in your specification: - - - .. code-block:: python - - from connexion.resolver import RestyResolver - - app = connexion.App(__name__) - app.add_api('swagger.yaml', resolver=RestyResolver('api')) - - .. code-block:: yaml - - paths: - /: - get: - # Implied operationId: api.get - /foo: - get: - # Implied operationId: api.foo.search - post: - # Implied operationId: api.foo.post - - '/foo/{id}': - get: - # Implied operationId: api.foo.get - put: - # Implied operationId: api.foo.put - copy: - # Implied operationId: api.foo.copy - delete: - # Implied operationId: api.foo.delete - - ``RestyResolver`` will give precedence to any ``operationId`` encountered in the specification. It will also respect - - ``x-router-controller``. You can import and extend ``connexion.resolver.Resolver`` to implement your own ``operationId`` - - (and function) resolution algorithm. - - - Automatic Parameter Handling - - ---------------------------- - - - Connexion automatically maps the parameters defined in your endpoint specification to arguments of your Python views as named parameters, and, whenever possible, with value casting. Simply define the endpoint's parameters with the same names as your views arguments. - - - As an example, say you have an endpoint specified as: - - - .. code-block:: yaml - - paths: - /foo: - get: - operationId: api.foo_get - parameters: - - name: message - description: Some message. - in: query - type: string - required: true - - And the view function: - - - .. code-block:: python - - # api.py file - - def foo_get(message): - # do something - return 'You send the message: {}'.format(message), 200 - - In this example, Connexion automatically recognizes that your view - - function expects an argument named ``message`` and assigns the value - - of the endpoint parameter ``message`` to your view function. - - - .. note:: In the OpenAPI 3.x.x spec, the requestBody does not have a name. - By default it will be passed in as 'body'. You can optionally - provide the x-body-name parameter in your requestBody - (or legacy position within the requestBody schema) - to override the name of the parameter that will be passed to your - handler function. - - .. code-block:: yaml - - - /path - post: - requestBody: - x-body-name: body - content: - application/json: - schema: - # legacy location here should be ignored because the preferred location for x-body-name is at the requestBody level above - x-body-name: this_should_be_ignored - $ref: '#/components/schemas/someComponent' - - .. warning:: When you define a parameter at your endpoint as *not* required, and - this argument does not have default value in your Python view, you will get - a "missing positional argument" exception whenever you call this endpoint - WITHOUT the parameter. Provide a default value for a named argument or use - ``**kwargs`` dict. - - Type casting - - ^^^^^^^^^^^^ - - - Whenever possible, Connexion will try to parse your argument values and - - do type casting to related Python native values. The current - - available type castings are: - - - +--------------+-------------+ - - | OpenAPI Type | Python Type | - - +==============+=============+ - - | integer | int | - - +--------------+-------------+ - - | string | str | - - +--------------+-------------+ - - | number | float | - - +--------------+-------------+ - - | boolean | bool | - - +--------------+-------------+ - - | array | list | - - +--------------+-------------+ - - | null | None | - - +--------------+-------------+ - - | object | dict | - - +--------------+-------------+ - - - If you use the ``array`` type In the Swagger definition, you can define the - - ``collectionFormat`` so that it won't be recognized. Connexion currently - - supports collection formats "pipes" and "csv". The default format is "csv". - - - Connexion is opinionated about how the URI is parsed for ``array`` types. - - The default behavior for query parameters that have been defined multiple - - times is to use the right-most value. For example, if you provide a URI with - - the the query string ``?letters=a,b,c&letters=d,e,f``, connexion will set - - ``letters = ['d', 'e', 'f']``. - - - You can override this behavior by specifying the URI parser in the app or - - api options. - - - .. code-block:: python - - from connexion.decorators.uri_parsing import AlwaysMultiURIParser - options = {'uri_parser_class': AlwaysMultiURIParser} - app = connexion.App(__name__, specification_dir='swagger/', options=options) - - You can implement your own URI parsing behavior by inheriting from - - ``connexion.decorators.uri_parsing.AbstractURIParser``. - - - There are a handful of URI parsers included with connection. - - - +----------------------+---------------------------------------------------------------------------+ - - | OpenAPIURIParser | This parser adheres to the OpenAPI 3.x.x spec, and uses the ``style`` | - - | default: OpenAPI 3.0 | parameter. Query parameters are parsed from left to right, so if a query | - - | | parameter is defined twice, then the right-most definition will take | - - | | precedence. For example, if you provided a URI with the query string | - - | | ``?letters=a,b,c&letters=d,e,f``, and ``style: simple``, then connexion | - - | | will set ``letters = ['d', 'e', 'f']``. For additional information see | - - | | `OpenAPI 3.0 Style Values`_. | - - +----------------------+---------------------------------------------------------------------------+ - - | Swagger2URIParser | This parser adheres to the Swagger 2.0 spec, and will only join together | - - | default: OpenAPI 2.0 | multiple instance of the same query parameter if the ``collectionFormat`` | - - | | is set to ``multi``. Query parameters are parsed from left to right, so | - - | | if a query parameter is defined twice, then the right-most definition | - - | | wins. For example, if you provided a URI with the query string | - - | | ``?letters=a,b,c&letters=d,e,f``, and ``collectionFormat: csv``, then | - - | | connexion will set ``letters = ['d', 'e', 'f']`` | - - +----------------------+---------------------------------------------------------------------------+ - - | FirstValueURIParser | This parser behaves like the Swagger2URIParser, except that it prefers | - - | | the first defined value. For example, if you provided a URI with the query| - - | | string ``?letters=a,b,c&letters=d,e,f`` and ``collectionFormat: csv`` | - - | | hen connexion will set ``letters = ['a', 'b', 'c']`` | - - +----------------------+---------------------------------------------------------------------------+ - - | AlwaysMultiURIParser | This parser is backwards compatible with Connexion 1.x. It joins together | - - | | multiple instances of the same query parameter. | - - +----------------------+---------------------------------------------------------------------------+ - - - - Parameter validation - - ^^^^^^^^^^^^^^^^^^^^ - - - Connexion can apply strict parameter validation for query and form data - - parameters. When this is enabled, requests that include parameters not defined - - in the swagger spec return a 400 error. You can enable it when adding the API - - to your application: - - - .. code-block:: python - - app.add_api('my_apy.yaml', strict_validation=True) - - API Versioning and basePath - - --------------------------- - - - Setting a base path is useful for versioned APIs. An example of - - a base path would be the ``1.0`` in ``http://MYHOST/1.0/hello_world``. - - - If you are using OpenAPI 3.x.x, you set your base URL path in the - - servers block of the specification. You can either specify a full - - URL, or just a relative path. - - - .. code-block:: yaml - - servers: - - url: https://MYHOST/1.0 - description: full url example - - url: /1.0 - description: relative path example - - paths: - ... - - If you are using OpenAPI 2.0, you can define a ``basePath`` on the top level - - of your OpenAPI 2.0 specification. - - - .. code-block:: yaml - - basePath: /1.0 - - paths: - ... - - If you don't want to include the base path in your specification, you - - can provide it when adding the API to your application: - - - .. code-block:: python - - app.add_api('my_api.yaml', base_path='/1.0') - - Swagger JSON - - ------------ - - Connexion makes the OpenAPI/Swagger specification in JSON format - - available from either ``swagger.json`` (for OpenAPI 2.0) or - - ``openapi.json`` (for OpenAPI 3.x.x) at the base path of the API. - - For example, if your base path was ``1.0``, then your spec would be - - available at ``/1.0/openapi.json``. - - - You can disable serving the spec JSON at the application level: - - - .. code-block:: python - - options = {"serve_spec": False} - app = connexion.App(__name__, specification_dir='openapi/', - options=options) - app.add_api('my_api.yaml') - - You can also disable it at the API level: - - - .. code-block:: python - - options = {"serve_spec": False} - app = connexion.App(__name__, specification_dir='openapi/') - app.add_api('my_api.yaml', options=options) - - HTTPS Support - - ------------- - - - When specifying HTTPS as the scheme in the API YAML file, all the URIs - - in the served Swagger UI are HTTPS endpoints. The problem: The default - - server that runs is a "normal" HTTP server. This means that the - - Swagger UI cannot be used to play with the API. What is the correct - - way to start a HTTPS server when using Connexion? - - - One way, `described by Flask`_, looks like this: - - - .. code-block:: python - - from OpenSSL import SSL - context = SSL.Context(SSL.SSLv23_METHOD) - context.use_privatekey_file('yourserver.key') - context.use_certificate_file('yourserver.crt') - - app.run(host='127.0.0.1', port='12344', - debug=False/True, ssl_context=context) - - However, Connexion doesn't provide an ssl_context parameter. This is - - because Flask doesn't, either--but it uses ``**kwargs`` to send the - - parameters to the underlying `werkzeug`_ server. - - - The Swagger UI Console - - ---------------------- - - - The Swagger UI for an API is available through pip extras. - - You can install it with ``pip install connexion[swagger-ui]``. - - It will be served up at ``{base_path}/ui/`` where ``base_path`` is the - - base path of the API. - - - You can disable the Swagger UI at the application level: - - - .. code-block:: python - - app = connexion.App(__name__, specification_dir='openapi/', - options={"swagger_ui": False}) - app.add_api('my_api.yaml') - - - You can also disable it at the API level: - - - .. code-block:: python - - app = connexion.App(__name__, specification_dir='openapi/') - app.add_api('my_api.yaml', options={"swagger_ui": False}) - - If necessary, you can explicitly specify the path to the directory with - - swagger-ui to not use the connexion[swagger-ui] distro. - - In order to do this, you should specify the following option: - - - .. code-block:: python - - options = {'swagger_path': '/path/to/swagger_ui/'} - app = connexion.App(__name__, specification_dir='openapi/', options=options) - - If you wish to provide your own swagger-ui distro, note that connexion - - expects a jinja2 file called ``swagger_ui/index.j2`` in order to load the - - correct ``swagger.json`` by default. Your ``index.j2`` file can use the - - ``openapi_spec_url`` jinja variable for this purpose: - - - .. code-block:: - - const ui = SwaggerUIBundle({ url: "{{ openapi_spec_url }}"}) - - Additionally, if you wish to use swagger-ui-3.x.x, it is also provided by - - installing connexion[swagger-ui], and can be enabled like this: - - - .. code-block:: python - - from swagger_ui_bundle import swagger_ui_3_path - options = {'swagger_path': swagger_ui_3_path} - app = connexion.App(__name__, specification_dir='swagger/', options=options) - - - Server Backend - - -------------- - - - By default Connexion uses the Flask_ server. For asynchronous - - applications, you can also use Tornado_ as the HTTP server. To do - - this, set your server to ``tornado``: - - - .. code-block:: python - - import connexion - - app = connexion.App(__name__, specification_dir='swagger/') - app.run(server='tornado', port=8080) - - You can use the Flask WSGI app with any WSGI container, e.g. `using - - Flask with uWSGI`_ (this is common): - - - .. code-block:: python - - app = connexion.App(__name__, specification_dir='swagger/') - application = app.app # expose global WSGI application object - - You can use the ``aiohttp`` framework as server backend as well: - - - .. code-block:: python - - import connexion - - app = connexion.AioHttpApp(__name__, specification_dir='swagger/') - app.run(port=8080) - - .. note:: Also check aiohttp handler examples_. - - - Set up and run the installation code: - - - .. code-block:: bash - - $ sudo pip3 install uwsgi - $ uwsgi --http :8080 -w app -p 16 # use 16 worker processes - - See the `uWSGI documentation`_ for more information. - - - .. _using Flask with uWSGI: http://flask.pocoo.org/docs/latest/deploying/uwsgi/ - - .. _uWSGI documentation: https://uwsgi-docs.readthedocs.org/ - - .. _examples: https://docs.aiohttp.org/en/stable/web.html#handler - - - - Documentation - - ============= - - Additional information is available at `Connexion's Documentation Page`_. - - - Changes - - ======= - - - A full changelog is maintained on the `GitHub releases page`_. - - - .. _GitHub releases page: https://github.com/zalando/connexion/releases - - - Contributing to Connexion/TODOs - - =============================== - - - We welcome your ideas, issues, and pull requests. Just follow the - - usual/standard GitHub practices. - - - For easy development, install connexion using poetry with all extras, and - - install the pre-commit hooks to automatically run black formatting and static analysis checks. - - - .. code-block:: bash - - poetry install --all-extras - pre-commit install - - You can find out more about how Connexion works and where to apply your changes by having a look - - at our `ARCHITECTURE.rst `_. - - - Unless you explicitly state otherwise in advance, any non trivial - - contribution intentionally submitted for inclusion in this project by you - - to the steward of this repository (Zalando SE, Berlin) shall be under the - - terms and conditions of Apache License 2.0 written below, without any - - additional copyright information, terms or conditions. - - - TODOs - - ----- - - - - If you'd like to become a more consistent contributor to Connexion, we'd love your help working on - - these we have a list of `issues where we are looking for contributions`_. - - - Thanks - - =================== - - - We'd like to thank all of Connexion's contributors for working on this - - project, and to Swagger/OpenAPI for their support. - - - License - - =================== - - - Copyright 2015 Zalando SE - - - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. - - - Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - - .. _Flask: http://flask.pocoo.org/ - - .. _issues waffle board: https://waffle.io/zalando/connexion - - .. _API First: https://opensource.zalando.com/restful-api-guidelines/#api-first - - .. _Hug: https://github.com/timothycrosley/hug - - .. _Swagger: http://swagger.io/open-source-integrations/ - - .. _Jinja2: http://jinja.pocoo.org/ - - .. _rfc6750: https://tools.ietf.org/html/rfc6750 - - .. _OpenAPI Specification: https://www.openapis.org/ - - .. _OpenAPI 3.0 Style Values: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#style-values - - .. _Operation Object: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#operation-object - - .. _swager.spec.security_definition: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#security-definitions-object - - .. _swager.spec.security_requirement: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#security-requirement-object - - .. _YAML format: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#format - - .. _token information: https://tools.ietf.org/html/rfc6749 - - .. _Tornado: http://www.tornadoweb.org/en/stable/ - - .. _Connexion Pet Store Example Application: https://github.com/hjacobs/connexion-example - - .. _described by Flask: http://flask.pocoo.org/snippets/111/ - - .. _werkzeug: http://werkzeug.pocoo.org/ - - .. _Connexion's Documentation Page: http://connexion.readthedocs.org/en/latest/ - - .. _Crafting effective Microservices in Python: https://jobs.zalando.com/tech/blog/crafting-effective-microservices-in-python/ - - .. _issues where we are looking for contributions: https://github.com/zalando/connexion/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22 - - .. _HTTP Methods work in Flask: http://flask.pocoo.org/docs/1.0/quickstart/#http-methods -rochacbruno/flasgger: >+ - # Flasgger - - ## Easy Swagger UI for your Flask API - - - [![Build Status](https://travis-ci.com/flasgger/flasgger.svg?branch=master)](https://travis-ci.com/flasgger/flasgger) - - [![Code Health](https://landscape.io/github/rochacbruno/flasgger/master/landscape.svg?style=flat)](https://landscape.io/github/rochacbruno/flasgger/master) - - [![Coverage Status](https://coveralls.io/repos/github/rochacbruno/flasgger/badge.svg?branch=master)](https://coveralls.io/github/rochacbruno/flasgger?branch=master) - - [![PyPI](https://img.shields.io/pypi/v/flasgger.svg)](https://pypi.python.org/pypi/flasgger) - Donate with Paypal - - - ![flasgger](docs/flasgger.png) - - - Flasgger is a Flask extension to **extract [OpenAPI-Specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#operation-object)** from all Flask views registered in your API. - - - Flasgger also comes with **[SwaggerUI](http://swagger.io/swagger-ui/) embedded** so you can access [http://localhost:5000/apidocs](localhost:5000/apidocs) and visualize and interact with your API resources. - - - Flasgger also **provides validation** of the incoming data, using the same specification it can validates if the data received as as a POST, PUT, PATCH is valid against the schema defined using **YAML**, **Python dictionaries** or **Marshmallow Schemas**. - - - Flasgger can work with simple function views or MethodViews using docstring as specification, or using `@swag_from` decorator to get specification from **YAML** or **dict** and also provides **SwaggerView** which can use **Marshmallow Schemas** as specification. - - - Flasgger is compatible with `Flask-RESTful` so you can use `Resources` and `swag` specifications together, take a look at [restful example.](examples/restful.py) - - - Flasgger also supports `Marshmallow APISpec` as base template for specification, if you are using APISPec from Marshmallow take a look at [apispec example.](examples/apispec_example.py) - - - # Top Contributors - - - [![](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/images/0)](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/links/0)[![](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/images/1)](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/links/1)[![](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/images/2)](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/links/2)[![](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/images/3)](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/links/3)[![](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/images/4)](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/links/4)[![](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/images/5)](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/links/5)[![](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/images/6)](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/links/6)[![](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/images/7)](https://sourcerer.io/fame/rochacbruno/rochacbruno/flasgger/links/7) - - - # Examples and demo app - - - There are some [example applications](examples/) and you can also play with examples in [Flasgger demo app](http://flasgger.pythonanywhere.com/) - - - > NOTE: all the examples apps are also test cases and run automatically in Travis CI to ensure quality and coverage. - - - ## Docker - - - The examples and demo app can also be built and run as a Docker image/container: - - - ``` - - docker build -t flasgger . - - docker run -it --rm -p 5000:5000 --name flasgger flasgger - - ``` - - Then access the Flasgger demo app at http://localhost:5000 . - - - # Installation - - - > under your virtualenv do: - - - Ensure you have latest setuptools - - ``` - - pip install -U setuptools - - ``` - - - then - - - ``` - - pip install flasgger - - ``` - - - or (dev version) - - - ``` - - pip install https://github.com/rochacbruno/flasgger/tarball/master - - ``` - - - > NOTE: If you want to use **Marshmallow Schemas** you also need to run `pip install marshmallow apispec` - - - # Getting started - - - ## Using docstrings as specification - - - Create a file called for example `colors.py` - - - ```python - - from flask import Flask, jsonify - - from flasgger import Swagger - - - app = Flask(__name__) - - swagger = Swagger(app) - - - @app.route('/colors//') - - def colors(palette): - """Example endpoint returning a list of colors by palette - This is using docstrings for specifications. - --- - parameters: - - name: palette - in: path - type: string - enum: ['all', 'rgb', 'cmyk'] - required: true - default: all - definitions: - Palette: - type: object - properties: - palette_name: - type: array - items: - $ref: '#/definitions/Color' - Color: - type: string - responses: - 200: - description: A list of colors (may be filtered by palette) - schema: - $ref: '#/definitions/Palette' - examples: - rgb: ['red', 'green', 'blue'] - """ - all_colors = { - 'cmyk': ['cian', 'magenta', 'yellow', 'black'], - 'rgb': ['red', 'green', 'blue'] - } - if palette == 'all': - result = all_colors - else: - result = {palette: all_colors.get(palette)} - - return jsonify(result) - - app.run(debug=True) - - ``` - - - Now run: - - - ``` - - python colors.py - - ``` - - - And go to: [http://localhost:5000/apidocs/](http://localhost:5000/apidocs/) - - - You should get: - - - ![colors](docs/colors.png) - - - ## Using external YAML files - - - Save a new file `colors.yml` - - - ```yaml - - Example endpoint returning a list of colors by palette - - In this example the specification is taken from external YAML file - - --- - - parameters: - - name: palette - in: path - type: string - enum: ['all', 'rgb', 'cmyk'] - required: true - default: all - definitions: - Palette: - type: object - properties: - palette_name: - type: array - items: - $ref: '#/definitions/Color' - Color: - type: string - responses: - 200: - description: A list of colors (may be filtered by palette) - schema: - $ref: '#/definitions/Palette' - examples: - rgb: ['red', 'green', 'blue'] - ``` - - - - lets use the same example changing only the view function. - - - ```python - - from flasgger import swag_from - - - @app.route('/colors//') - - @swag_from('colors.yml') - - def colors(palette): - ... - ``` - - - If you do not want to use the decorator you can use the docstring `file:` shortcut. - - - ```python - - @app.route('/colors//') - - def colors(palette): - """ - file: colors.yml - """ - ... - ``` - - - - ## Using dictionaries as raw specs - - - Create a Python dictionary as: - - - ```python - - specs_dict = { - "parameters": [ - { - "name": "palette", - "in": "path", - "type": "string", - "enum": [ - "all", - "rgb", - "cmyk" - ], - "required": "true", - "default": "all" - } - ], - "definitions": { - "Palette": { - "type": "object", - "properties": { - "palette_name": { - "type": "array", - "items": { - "$ref": "#/definitions/Color" - } - } - } - }, - "Color": { - "type": "string" - } - }, - "responses": { - "200": { - "description": "A list of colors (may be filtered by palette)", - "schema": { - "$ref": "#/definitions/Palette" - }, - "examples": { - "rgb": [ - "red", - "green", - "blue" - ] - } - } - } - } - - ``` - - - Now take the same function and use the dict in the place of YAML file. - - - ```python - - @app.route('/colors//') - - @swag_from(specs_dict) - - def colors(palette): - """Example endpoint returning a list of colors by palette - In this example the specification is taken from specs_dict - """ - ... - ``` - - - ## Using Marshmallow Schemas - - - > FIRST: `pip install marshmallow apispec` - - - ```python - - from flask import Flask, jsonify - - from flasgger import Swagger, SwaggerView, Schema, fields - - - - class Color(Schema): - name = fields.Str() - - class Palette(Schema): - pallete_name = fields.Str() - colors = fields.Nested(Color, many=True) - - class PaletteView(SwaggerView): - parameters = [ - { - "name": "palette", - "in": "path", - "type": "string", - "enum": ["all", "rgb", "cmyk"], - "required": True, - "default": "all" - } - ] - responses = { - 200: { - "description": "A list of colors (may be filtered by palette)", - "schema": Palette - } - } - - def get(self, palette): - """ - Colors API using schema - This example is using marshmallow schemas - """ - all_colors = { - 'cmyk': ['cian', 'magenta', 'yellow', 'black'], - 'rgb': ['red', 'green', 'blue'] - } - if palette == 'all': - result = all_colors - else: - result = {palette: all_colors.get(palette)} - return jsonify(result) - - app = Flask(__name__) - - swagger = Swagger(app) - - - app.add_url_rule( - '/colors/', - view_func=PaletteView.as_view('colors'), - methods=['GET'] - ) - - - app.run(debug=True) - - - ``` - - - > NOTE: take a look at `examples/validation.py` for a more complete example. - - - - > NOTE: when catching arguments in path rule always use explicit types, bad: ``/api/`` good: ``/api/`` - - - - ## Using **Flask RESTful** Resources - - - Flasgger is compatible with Flask-RESTful you only need to install `pip install flask-restful` and then: - - - ```python - - - from flask import Flask - - from flasgger import Swagger - - from flask_restful import Api, Resource - - - app = Flask(__name__) - - api = Api(app) - - swagger = Swagger(app) - - - class Username(Resource): - def get(self, username): - """ - This examples uses FlaskRESTful Resource - It works also with swag_from, schemas and spec_dict - --- - parameters: - - in: path - name: username - type: string - required: true - responses: - 200: - description: A single user item - schema: - id: User - properties: - username: - type: string - description: The name of the user - default: Steven Wilson - """ - return {'username': username}, 200 - - - api.add_resource(Username, '/username/') - - - app.run(debug=True) - - - ``` - - - ## Auto-parsing external YAML docs and `MethodView`s - - - Flasgger can be configured to auto-parse external YAML API docs. [Set a `doc_dir`](https://github.com/rochacbruno/flasgger/blob/aaef05c17cc559d01b7436211093463642eb6ae2/examples/parsed_view_func.py#L16) in your `app.config['SWAGGER']` and Swagger will load API docs by looking in `doc_dir` for YAML files stored by endpoint-name and method-name. For example, `'doc_dir': './examples/docs/'` and a file `./examples/docs/items/get.yml` will provide a Swagger doc for `ItemsView` method `get`. - - - Additionally, when using **Flask RESTful** per above, by passing `parse=True` when constructing `Swagger`, Flasgger will use `flask_restful.reqparse.RequestParser`, locate all `MethodView`s and parsed and validated data will be stored in `flask.request.parsed_data`. - - - ## Handling multiple http methods and routes for a single function - - - You can separate specifications by endpoint or methods - - - ```python - - from flasgger.utils import swag_from - - - @app.route('/api/', endpoint='with_user_name', methods=['PUT', 'GET']) - - @app.route('/api/', endpoint='without_user_name') - - @swag_from('path/to/external_file.yml', endpoint='with_user_name') - - @swag_from('path/to/external_file_no_user_get.yml', endpoint='without_user_name', methods=['GET']) - - @swag_from('path/to/external_file_no_user_put.yml', endpoint='without_user_name', methods=['PUT']) - - def fromfile_decorated(username=None): - if not username: - return "No user!" - return jsonify({'username': username}) - ``` - - - And the same can be achieved with multiple methods in a `MethodView` or `SwaggerView` by - - registering the `url_rule` many times. Take a look at `examples/example_app` - - - - # Use the same data to validate your API POST body. - - - Setting `swag_from`'s _validation_ parameter to `True` will validate incoming data automatically: - - - ```python - - from flasgger import swag_from - - - @swag_from('defs.yml', validation=True) - - def post(): - # if not validate returns ValidationError response with status 400 - # also returns the validation message. - ``` - - - Using `swagger.validate` annotation is also possible: - - - ```python - - from flasgger import Swagger - - - swagger = Swagger(app) - - - @swagger.validate('UserSchema') - - def post(): - ''' - file: defs.yml - ''' - # if not validate returns ValidationError response with status 400 - # also returns the validation message. - ``` - - - Yet you can call `validate` manually: - - - ```python - - from flasgger import swag_from, validate - - - @swag_from('defs.yml') - - def post(): - validate(request.json, 'UserSchema', 'defs.yml') - # if not validate returns ValidationError response with status 400 - # also returns the validation message. - ``` - - - It is also possible to define `validation=True` in `SwaggerView` and also use - - `specs_dict` for validation. - - - Take a look at `examples/validation.py` for more information. - - - All validation options can be found at http://json-schema.org/latest/json-schema-validation.html - - - ### Custom validation - - - By default Flasgger will use [python-jsonschema](https://python-jsonschema.readthedocs.io/en/latest/) - - to perform validation. - - - Custom validation functions are supported as long as they meet the requirements: - - take two, and only two, positional arguments: - - the data to be validated as the first; and - - the schema to validate against as the second argument - - raise any kind of exception when validation fails. - - Any return value is discarded. - - - - Providing the function to the Swagger instance will make it the default: - - - ```python - - from flasgger import Swagger - - - swagger = Swagger(app, validation_function=my_validation_function) - - ``` - - - Providing the function as parameter of `swag_from` or `swagger.validate` - - annotations or directly to the `validate` function will force it's use - - over the default validation function for Swagger: - - - ```python - - from flasgger import swag_from - - - @swag_from('spec.yml', validation=True, validation_function=my_function) - - ... - - ``` - - - ```python - - from flasgger import Swagger - - - swagger = Swagger(app) - - - @swagger.validate('Pet', validation_function=my_function) - - ... - - ``` - - - ```python - - from flasgger import validate - - - ... - - validate( - request.json, 'Pet', 'defs.yml', validation_function=my_function) - ``` - - - ### Validation Error handling - - - By default Flasgger will handle validation errors by aborting the - - request with a 400 BAD REQUEST response with the error message. - - - A custom validation error handling function can be provided to - - supersede default behavior as long as it meets the requirements: - - take three, and only three, positional arguments: - - the error raised as the first; - - the data which failed validation as the second; and - - the schema used in to validate as the third argument - - - Providing the function to the Swagger instance will make it the default: - - - ```python - - from flasgger import Swagger - - - swagger = Swagger(app, validation_error_handler=my_handler) - - ``` - - - Providing the function as parameter of `swag_from` or `swagger.validate` - - annotations or directly to the `validate` function will force it's use - - over the default validation function for Swagger: - - - ```python - - from flasgger import swag_from - - - @swag_from( - 'spec.yml', validation=True, validation_error_handler=my_handler) - ... - - ``` - - - ```python - - from flasgger import Swagger - - - swagger = Swagger(app) - - - @swagger.validate('Pet', validation_error_handler=my_handler) - - ... - - ``` - - - ```python - - from flasgger import validate - - - ... - - validate( - request.json, 'Pet', 'defs.yml', - validation_error_handler=my_handler) - ``` - - - Examples of use of a custom validation error handler function can be - - found at [example validation_error_handler.py](examples/validation_error_handler.py) - - - # Get defined schemas as python dictionaries - - - You may wish to use schemas you defined in your Swagger specs as dictionaries - - without replicating the specification. For that you can use the `get_schema` - - method: - - - ```python - - from flask import Flask, jsonify - - from flasgger import Swagger, swag_from - - - app = Flask(__name__) - - swagger = Swagger(app) - - - @swagger.validate('Product') - - def post(): - """ - post endpoint - --- - tags: - - products - parameters: - - name: body - in: body - required: true - schema: - id: Product - required: - - name - properties: - name: - type: string - description: The product's name. - default: "Guarana" - responses: - 200: - description: The product inserted in the database - schema: - $ref: '#/definitions/Product' - """ - rv = db.insert(request.json) - return jsonify(rv) - - ... - - - product_schema = swagger.get_schema('product') - - ``` - - - This method returns a dictionary which contains the Flasgger schema id, - - all defined parameters and a list of required parameters. - - - # HTML sanitizer - - - By default Flasgger will try to sanitize the content in YAML definitions - - replacing every ```\n``` with ```
``` but you can change this behaviour - - setting another kind of sanitizer. - - - ```python - - from flasgger import Swagger, NO_SANITIZER - - - app =Flask() - - swagger = Swagger(app, sanitizer=NO_SANITIZER) - - ``` - - - You can write your own sanitizer - - - ```python - - swagger = Swagger(app, sanitizer=lambda text: do_anything_with(text)) - - ``` - - - There is also a Markdown parser available, if you want to be able to render - - Markdown in your specs description use **MK_SANITIZER** - - - - # Swagger UI and templates - - - You can override the `templates/flasgger/index.html` in your application and - - this template will be the `index.html` for SwaggerUI. Use `flasgger/ui2/templates/index.html` - - as base for your customization. - - - Flasgger supports Swagger UI versions 2 and 3, The version 3 is still experimental but you - - can try setting `app.config['SWAGGER']['uiversion']`. - - - ```python - - app = Flask(__name__) - - app.config['SWAGGER'] = { - 'title': 'My API', - 'uiversion': 3 - } - - swagger = Swagger(app) - - - ``` - - - # OpenAPI 3.0 Support - - - There is experimental support for OpenAPI 3.0 that should work when using SwaggerUI 3. To use OpenAPI 3.0, set `app.config['SWAGGER']['openapi']` to a version that the current SwaggerUI 3 supports such as `'3.0.2'`. - - - For an example of this that uses `callbacks` and `requestBody`, see the [callbacks example](examples/callbacks.py). - - - ## Externally loading Swagger UI and jQuery JS/CSS - - - Starting with Flasgger 0.9.2 you can specify external URL locations for loading the JavaScript and CSS for the Swagger and jQuery libraries loaded in the Flasgger default templates. If the configuration properties below are omitted, Flasgger will serve static versions it includes - these versions may be older than the current Swagger UI v2 or v3 releases. - - - The following example loads Swagger UI and jQuery versions from unpkg.com: - - - ``` - - swagger_config = Swagger.DEFAULT_CONFIG - - swagger_config['swagger_ui_bundle_js'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js' - - swagger_config['swagger_ui_standalone_preset_js'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui-standalone-preset.js' - - swagger_config['jquery_js'] = '//unpkg.com/jquery@2.2.4/dist/jquery.min.js' - - swagger_config['swagger_ui_css'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui.css' - - Swagger(app, config=swagger_config) - - ``` - - - # Initializing Flasgger with default data. - - - You can start your Swagger spec with any default data providing a template: - - - ```python - - template = { - "swagger": "2.0", - "info": { - "title": "My API", - "description": "API for my data", - "contact": { - "responsibleOrganization": "ME", - "responsibleDeveloper": "Me", - "email": "me@me.com", - "url": "www.me.com", - }, - "termsOfService": "http://me.com/terms", - "version": "0.0.1" - }, - "host": "mysite.com", # overrides localhost:500 - "basePath": "/api", # base bash for blueprint registration - "schemes": [ - "http", - "https" - ], - "operationId": "getmyData" - } - - - swagger = Swagger(app, template=template) - - - ``` - - - And then the template is the default data unless some view changes it. You - - can also provide all your specs as template and have no views. Or views in - - external APP. - - - ## Getting default data at runtime - - - Sometimes you need to get some data at runtime depending on dynamic values ex: you want to check `request.is_secure` to decide if `schemes` will be `https` you can do that by using `LazyString`. - - - ```py - - from flask import Flask - - from flasgger import, Swagger, LazyString, LazyJSONEncoder - - - app = Flask(__init__) - - - # Set the custom Encoder (Inherit it if you need to customize) - - app.json_encoder = LazyJSONEncoder - - - - template = dict( - info={ - 'title': LazyString(lambda: 'Lazy Title'), - 'version': LazyString(lambda: '99.9.9'), - 'description': LazyString(lambda: 'Hello Lazy World'), - 'termsOfService': LazyString(lambda: '/there_is_no_tos') - }, - host=LazyString(lambda: request.host), - schemes=[LazyString(lambda: 'https' if request.is_secure else 'http')], - foo=LazyString(lambda: "Bar") - ) - - Swagger(app, template=template) - - - ``` - - - The `LazyString` values will be evaluated only when `jsonify` encodes the value at runtime, so you have access to Flask `request, session, g, etc..` and also may want to access a database. - - - ## Behind a reverse proxy - - - Sometimes you're serving your swagger docs behind an reverse proxy (e.g. NGINX). When following the [Flask guidance](http://flask.pocoo.org/snippets/35/), - - the swagger docs will load correctly, but the "Try it Out" button points to the wrong place. This can be fixed with the following code: - - - ```python - - from flask import Flask, request - - from flasgger import Swagger, LazyString, LazyJSONEncoder - - - app = Flask(__name__) - - app.json_encoder = LazyJSONEncoder - - - template = dict(swaggerUiPrefix=LazyString(lambda : request.environ.get('HTTP_X_SCRIPT_NAME', ''))) - - swagger = Swagger(app, template=template) - - - ``` - - - # Customize default configurations - - - Custom configurations such as a different specs route or disabling Swagger UI can be provided to Flasgger: - - - ```python - - swagger_config = { - "headers": [ - ], - "specs": [ - { - "endpoint": 'apispec_1', - "route": '/apispec_1.json', - "rule_filter": lambda rule: True, # all in - "model_filter": lambda tag: True, # all in - } - ], - "static_url_path": "/flasgger_static", - # "static_folder": "static", # must be set by user - "swagger_ui": True, - "specs_route": "/apidocs/" - } - - - swagger = Swagger(app, config=swagger_config) - - - ``` - - - ## Extracting Definitions - - - Definitions can be extracted when `id` is found in spec, example: - - - ```python - - from flask import Flask, jsonify - - from flasgger import Swagger - - - app = Flask(__name__) - - swagger = Swagger(app) - - - @app.route('/colors//') - - def colors(palette): - """Example endpoint returning a list of colors by palette - --- - parameters: - - name: palette - in: path - type: string - enum: ['all', 'rgb', 'cmyk'] - required: true - default: all - responses: - 200: - description: A list of colors (may be filtered by palette) - schema: - id: Palette - type: object - properties: - palette_name: - type: array - items: - schema: - id: Color - type: string - examples: - rgb: ['red', 'green', 'blue'] - """ - all_colors = { - 'cmyk': ['cian', 'magenta', 'yellow', 'black'], - 'rgb': ['red', 'green', 'blue'] - } - if palette == 'all': - result = all_colors - else: - result = {palette: all_colors.get(palette)} - - return jsonify(result) - - app.run(debug=True) - - ``` - - - In this example you do not have to pass `definitions` but need to add `id` to - - your schemas. - -fotinakis/swagger-blocks: > - # Swagger::Blocks - - - [![Build Status](https://travis-ci.org/fotinakis/swagger-blocks.svg?branch=master)](https://travis-ci.org/fotinakis/swagger-blocks) - - [![Gem Version](https://badge.fury.io/rb/swagger-blocks.svg)](http://badge.fury.io/rb/swagger-blocks) - - - Swagger::Blocks is a DSL for pure Ruby code blocks that can be turned into JSON. - - - It helps you write API docs in the [Swagger](https://helloreverb.com/developers/swagger) style in Ruby and then automatically build JSON that is compatible with [Swagger UI](http://petstore.swagger.wordnik.com/#!/pet). - - - ## Features - - - * Supports **live updating** by design. Change code, refresh your API docs. - - * **Works with all Ruby web frameworks** including Rails, Sinatra, etc. - - * **100% support** for all features of the [Swagger 2.0](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md) spec. - - * Flexible—you can use Swagger::Blocks anywhere, split up blocks to fit your style preferences, etc. Since it's pure Ruby and serves definitions dynamically, you can easily use initializers/config objects to change values or even **show different APIs based on environment**. - - * 1:1 naming with the Swagger spec—block names and nesting should match almost exactly with the swagger spec, with rare exceptions to make things more convenient. - - - ## Swagger UI demo - - - http://petstore.swagger.io/ - - - ![swagger-sample](https://cloud.githubusercontent.com/assets/75300/5822830/4769805c-a08c-11e4-9efe-d57cf0f752e0.png) - - - ## Installation - - - Add this line to your application's Gemfile: - - gem 'swagger-blocks' - - Or install directly with `gem install swagger-blocks`. - - - ## Swagger 2.0 example (Rails) - - - This is a simplified example based on the objects in the Petstore [Swagger Sample App](http://petstore.swagger.wordnik.com/#!/pet). For a more complex and complete example, see the [swagger_v2_blocks_spec.rb](https://github.com/fotinakis/swagger-blocks/blob/master/spec/lib/swagger_v2_blocks_spec.rb) file. - - - Also note that **Rails is not required**, you can use Swagger::Blocks in plain Ruby objects. - - - ### PetsController - - - ```Ruby - - class PetsController < ActionController::Base - include Swagger::Blocks - - swagger_path '/pets/{id}' do - operation :get do - key :summary, 'Find Pet by ID' - key :description, 'Returns a single pet if the user has access' - key :operationId, 'findPetById' - key :tags, [ - 'pet' - ] - parameter do - key :name, :id - key :in, :path - key :description, 'ID of pet to fetch' - key :required, true - key :type, :integer - key :format, :int64 - end - response 200 do - key :description, 'pet response' - schema do - key :'$ref', :Pet - end - end - response :default do - key :description, 'unexpected error' - schema do - key :'$ref', :ErrorModel - end - end - end - end - swagger_path '/pets' do - operation :get do - key :summary, 'All Pets' - key :description, 'Returns all pets from the system that the user has access to' - key :operationId, 'findPets' - key :produces, [ - 'application/json', - 'text/html', - ] - key :tags, [ - 'pet' - ] - parameter do - key :name, :tags - key :in, :query - key :description, 'tags to filter by' - key :required, false - key :type, :array - items do - key :type, :string - end - key :collectionFormat, :csv - end - parameter do - key :name, :limit - key :in, :query - key :description, 'maximum number of results to return' - key :required, false - key :type, :integer - key :format, :int32 - end - response 200 do - key :description, 'pet response' - schema do - key :type, :array - items do - key :'$ref', :Pet - end - end - end - response :default do - key :description, 'unexpected error' - schema do - key :'$ref', :ErrorModel - end - end - end - operation :post do - key :description, 'Creates a new pet in the store. Duplicates are allowed' - key :operationId, 'addPet' - key :produces, [ - 'application/json' - ] - key :tags, [ - 'pet' - ] - parameter do - key :name, :pet - key :in, :body - key :description, 'Pet to add to the store' - key :required, true - schema do - key :'$ref', :PetInput - end - end - response 200 do - key :description, 'pet response' - schema do - key :'$ref', :Pet - end - end - response :default do - key :description, 'unexpected error' - schema do - key :'$ref', :ErrorModel - end - end - end - end - - # ... - end - - ``` - - - ### Models - - - #### Pet model - - - ```Ruby - - class Pet < ActiveRecord::Base - include Swagger::Blocks - - swagger_schema :Pet do - key :required, [:id, :name] - property :id do - key :type, :integer - key :format, :int64 - end - property :name do - key :type, :string - end - property :tag do - key :type, :string - end - end - - swagger_schema :PetInput do - allOf do - schema do - key :'$ref', :Pet - end - schema do - key :required, [:name] - property :id do - key :type, :integer - key :format, :int64 - end - end - end - end - - # ... - end - - ``` - - - #### Error model - - - ``` Ruby - - class ErrorModel # Notice, this is just a plain ruby object. - include Swagger::Blocks - - swagger_schema :ErrorModel do - key :required, [:code, :message] - property :code do - key :type, :integer - key :format, :int32 - end - property :message do - key :type, :string - end - end - end - - ``` - - - ### Docs controller - - - To integrate these definitions with Swagger UI, we need a docs controller that can serve the JSON definitions. - - - ```Ruby - - resources :apidocs, only: [:index] - - ``` - - - ```Ruby - - class ApidocsController < ActionController::Base - include Swagger::Blocks - - swagger_root do - key :swagger, '2.0' - info do - key :version, '1.0.0' - key :title, 'Swagger Petstore' - key :description, 'A sample API that uses a petstore as an example to ' \ - 'demonstrate features in the swagger-2.0 specification' - key :termsOfService, 'http://helloreverb.com/terms/' - contact do - key :name, 'Wordnik API Team' - end - license do - key :name, 'MIT' - end - end - tag do - key :name, 'pet' - key :description, 'Pets operations' - externalDocs do - key :description, 'Find more info here' - key :url, 'https://swagger.io' - end - end - key :host, 'petstore.swagger.wordnik.com' - key :basePath, '/api' - key :consumes, ['application/json'] - key :produces, ['application/json'] - end - - # A list of all classes that have swagger_* declarations. - SWAGGERED_CLASSES = [ - PetsController, - Pet, - ErrorModel, - self, - ].freeze - - def index - render json: Swagger::Blocks.build_root_json(SWAGGERED_CLASSES) - end - end - - ``` - - - The special part of this controller is this line: - - - ```Ruby - - render json: Swagger::Blocks.build_root_json(SWAGGERED_CLASSES) - - ``` - - - That is the only line necessary to build the full [root Swagger object](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schema) JSON and all definitions underneath it. You simply pass in a list of all the "swaggered" classes in your app. - - - If you want to include controllers outside the standard path just use the full class path including module names, like: - - - ```Ruby - - SWAGGERED_CLASSES = [ - Api::V1::PetsController, - self, - ] - - ``` - - - If you are receiving a "swagger_root must be declared" error make sure you are including "self" in your SWAGGERED_CLASSES definition, as shown above. - - - Now, simply point Swagger UI at `/apidocs` and everything should Just Work™. If you change any of the Swagger block definitions, you can simply refresh Swagger UI to see the changes. - - - ### Security handling - - - To support Swagger's definitions for API key auth or OAuth2, use `security_definition` in your `swagger_root`: - - - ```Ruby - swagger_root do - key :swagger, '2.0' - - # ... - - security_definition :api_key do - key :type, :apiKey - key :name, :api_key - key :in, :header - end - security_definition :petstore_auth do - key :type, :oauth2 - key :authorizationUrl, 'http://swagger.io/api/oauth/dialog' - key :flow, :implicit - scopes do - key 'write:pets', 'modify pets in your account' - key 'read:pets', 'read your pets' - end - end - end - ``` - - - You can then apply [security requirement objects](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#securityRequirementObject) to the entire `swagger_root`, or to individual operations: - - - ```Ruby - swagger_path '/pets/{id}' do - operation :get do - - # ... - - security do - key :api_key, [] - end - security do - key :petstore_auth, ['write:pets', 'read:pets'] - end - end - end - ``` - - - #### Nested complex objects - - - The `key` block simply takes the value you give and puts it directly into the final JSON object. So, if you need to set more complex objects, you can just do: - - - ```ruby - key :foo, {some_complex: {nested_object: true}} - ``` - - - #### Parameter referencing - - - It is possible to reference parameters rather than explicitly define them in every action in which they are used. - - - To define a reusable parameter, declare it within `swagger_root` - - To reference the parameter, call it within a `swagger_path` or `operation` node - - - ```ruby - - swagger_root do - key :swagger, '2.0' - # ... - parameter :species do - key :name, :species - key :description, 'Species of this pet' - end - end - - - swagger_path '/pets/' do - operation :post do - parameter :species - # ... - end - end - - ``` - - - #### Inline keys - - - It is possible to omit numerous `key` calls using inline hash keys on any block. - - - All three calls are equivalent: - - - ```ruby - - parameter do - key :paramType, :path - key :name, :petId - key :description, 'ID of pet that needs to be fetched' - key :type, :string - end - - ``` - - - ```ruby - - parameter paramType: :path, name: :petId do - key :description, 'ID of pet that needs to be fetched' - key :type, :string - end - - ``` - - - ```ruby - - parameter paramType: :path, - name: :petId, - description: 'ID of pet that needs to be fetched', - type: :string - ``` - - - These inline keys can be used on any block, not just `parameter` blocks. - - - #### Writing JSON to a file - - - If you are not serving the JSON directly and need to write it to a file for some reason, you can easily use `build_root_json` for that as well: - - - ```Ruby - - swagger_data = Swagger::Blocks.build_root_json(SWAGGERED_CLASSES) - - File.open('swagger.json', 'w') { |file| file.write(swagger_data.to_json) } - - ``` - - - #### Overriding attributes - - - If certain attributes must be customized on-the-fly, you can merge a hash containing the customized values on the returned JSON. You can wrap ```build_root_json``` inside your own method: - - - ```Ruby - - def build_and_override_root_json(overrides = {}) - Swagger::Blocks.build_root_json(SWAGGERED_CLASSES).merge(overrides) - end - - ``` - - - #### Reducing boilerplate - - - To create reusable parameters, please see [parameter referencing](#parameter-referencing). - - - Most APIs have some common responses for 401s, 404s, etc. Rather than declaring these responses over and over, you can create a reusable module. - - - ```ruby - - module SwaggerResponses - module AuthenticationError - def self.extended(base) - base.response 401 do - key :description, 'not authorized' - schema do - key :'$ref', :AuthenticationError - end - end - end - end - end - - ``` - - - Now, you just need to extend it: - - - ```ruby - - operation :post do - extend SwaggerResponses::AuthenticationError - # ... - response 200 do - # ... - end - end - - ``` - - - ## Reference - - - See the [swagger_v2_blocks_spec.rb](https://github.com/fotinakis/swagger-blocks/blob/master/spec/lib/swagger_v2_blocks_spec.rb) for examples of more complex features and declarations possible. - - - ### Swagger 1.2 - - - The old [Swagger 1.2](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md) spec is not supported in swagger-blocks >= 2.0.0, but you may use [1.4.0](https://github.com/fotinakis/swagger-blocks/tree/v1.4.0). - - - ## Contributing - - - 1. Fork it ( https://github.com/fotinakis/swagger-blocks/fork ) - - 2. Create your feature branch (`git checkout -b my-new-feature`) - - 3. Commit your changes (`git commit -am 'Add some feature'`) - - 4. Push to the branch (`git push origin my-new-feature`) - - 5. Create a new Pull Request - - - Throw a ★ on it! :) - - - ## Filing issues - - - **Please DO [file an issue](https://github.com/fotinakis/swagger-blocks/issues)**: - - - - If you find a bug or some part of the Swagger 2.0 spec that swagger-blocks does not support. - - - To propose and discuss a code change before submitting a PR for it. - - - To talk about anything related specifically to swagger-blocks, not Swagger itself. - - - **Please DO NOT file an issue**: - - - - If you have a question about Swagger or Swagger UI. We simply cannot support all Swagger-related questions. Check out the http://swagger.io/community/ for help. - - - ## Release notes - - - * v2.0.1: Bugfix to allow nested arrays of `items`. - - * v2.0.0: Code cleanup, drop support for Swagger 1.2 spec. - - * v1.4.0: Allow parameters to be defined once in swagger_root and reused. - - * v1.3.4: Fix support for fully-qualified URIs in `$ref` values. - - * v1.3.3: Bugfix to allow `parameter` inside `swagger_path`. - - * v1.3.2: Bugfix to allow `property` inside `items` for rare extended schema uses. - - * v1.3.1: Bugfix to allow nested objects via `property` nested in `property`. - - * v1.3.0: Added support for condensed syntax via inline keys on every block. - - * v1.2.0: Improved support for `$ref` Path Item Object parameters. - - * v1.1.3: Rename tags directive to tag for consistency. - - * v1.1.2: Bugfix for security definition support. - - * v1.1.1: Bugfix for tags node support. - - * v1.1: Support for Swagger 2.0 spec. - - * v1.0.1: Make backwards-compatible with Ruby 1.9.3. - - * v1.0.0: Initial major release. - - - ## Credits - - - Thanks to [@ali-graham](https://github.com/ali-graham) for contributing support for Swagger 2.0. - - - Original idea inspired by [@richhollis](https://github.com/richhollis/)'s [swagger-docs](https://github.com/richhollis/swagger-docs/) gem. -westfieldlabs/apivore: > - [![Build - Status](https://travis-ci.org/westfieldlabs/apivore.svg?branch=master)](https://travis-ci.org/westfieldlabs/apivore) - - - [![Code Climate](https://codeclimate.com/github/westfieldlabs/apivore/badges/gpa.svg)](https://codeclimate.com/github/westfieldlabs/apivore) - - # Apivore - - - Automatically tests your rails API against its OpenAPI (Swagger) description of end-points, models, and query parameters. - - - Currently supports and validates against OpenAPI 2.0, (see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) - - - ## Installation - - - To use Apivore, add the following to your Gemfile: - - gem 'apivore' - ***WARNING:*** If apivore is listed in the Gemfile _above_ rspec then some issues, specifically `NameError: uninitialized constant RSpec::Mocks`, may arise when trying to run specs. - - - ## Usage - - - Create a new request spec in spec/requests: - - ```ruby - - require 'spec_helper' - - - RSpec.describe 'the API', type: :apivore, order: :defined do - subject { Apivore::SwaggerChecker.instance_for('/swagger.json') } - - context 'has valid paths' do - # tests go here - end - - context 'and' do - it 'tests all documented routes' do - expect(subject).to validate_all_paths - end - end - end - - ``` - - using the path to your application's Swagger 2.0 documentation. The convention is `/swagger.json`. - - - This will validate the json against the Swagger 2.0 schema and allow you to add tests for each documented endpoint combination of a path, method, and expected response. - - - If your Swagger documentation contains a schema for the response model, the generated tests will test whether the response conforms to that model. - - - For paths that take parameters, listed in the Swagger docs like `/deals/{id}.json`, values need to be passed to Apivore to substitute in to access the responses generated by your test data. - - - This is accomplished by passing the params into the validates function. - - ```ruby - - context 'has valid paths' do - let(:params) { { "id" => 1 } } - specify do - expect(subject).to validate( - :get, '/deals/{id}.json', 200, params - ) - end - - # or alternatively - - it { is_expected.to validate( :get, '/deals/{id}.json', 200, params ) } - end - - ``` - - A query string can be specified with the `_query_string` key as follows: - - - ```ruby - - expect(subject).to validate( - :get '/deals', 200, {"_query_string" => "title=Hello%20World&edition=3"} - ) - - ``` - - Parameters in the query string are not validated or processed by Apivore in any way. - - - Post parameters can be specified with the `_data` key as follows: - - - ```ruby - - expect(subject).to validate( - :post '/deals', 200, {"_data" => {'title' => 'Hello World'} } - ) - - ``` - - - HTTP headers can be specified via the `_headers` key: - - - ```ruby - - expect(subject).to validate( - :get '/deals', 200, {"_headers" => {'accept' => 'application/json'} } - ) - - ``` - - - Your Swagger.json can be validated against additional custom schemata, for example to enforce organisation API documentation standards, by using the following syntax: - - - ```ruby - - it 'additionally conforms to a custom schema' do - expect(subject).to conform_to(".json") - end - - ``` - - We have included an example [here] (data/custom_schemata/westfield_api_standards.json). The file path to this custom schema is stored in `Apivore::CustomSchemaValidator::WF_SCHEMA`, if you wish to use it. - - - Run the tests as part of your normal rspec test suite, e.g., `rake spec:requests` - - - ## Useful Resources - - - * http://json-schema.org/ - - * https://github.com/OAI/OpenAPI-Specification - - * https://github.com/ruby-json-schema/json-schema - - - ## License - - - Copyright 2014 Westfield Labs Corporation - - - Licensed under the Apache License, Version 2.0 (the "License"); - - you may not use this file except in compliance with the License. - - You may obtain a copy of the License at - - - http://www.apache.org/licenses/LICENSE-2.0 - - - Unless required by applicable law or agreed to in writing, software - - distributed under the License is distributed on an "AS IS" BASIS, - - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - - See the License for the specific language governing permissions and - - limitations under the License. - - - This project includes and makes use of the [OpenAPI (Swagger) 2.0 schema json](http://swagger.io/v2/schema.json) (Copyright 2016 The Linux Foundation. Released under the [Apache License](http://www.apache.org/licenses/LICENSE-2.0)) included here as `data/swagger_2.0_schema.json` - - - It also includes a copy of http://json-schema.org/draft-04/schema, included as `data/draft04_schema.json`. These schemata are included to prevent network resource fetching and speed up validation times considerably. - - - ## Contributors - - - * Charles Horn (https://github.com/hornc) - - * Leon Dewey (https://github.com/leondewey) - - * Max Brosnahan (https://github.com/gingermusketeer) -slanatech/swagger-stats: > -

- - swagger-stats - -

- - - # swagger-stats | API Observability - - - - #### [https://swaggerstats.io](https://swaggerstats.io) | [Guide](https://swaggerstats.io/guide/) - - - [![CircleCI](https://dl.circleci.com/status-badge/img/gh/slanatech/swagger-stats/tree/master.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/slanatech/swagger-stats/tree/master) - - [![Coverage Status](https://coveralls.io/repos/github/slanatech/swagger-stats/badge.svg?branch=master&dummy)](https://coveralls.io/github/slanatech/swagger-stats?branch=master&dummy) - - [![npm version](https://badge.fury.io/js/swagger-stats.svg)](https://badge.fury.io/js/swagger-stats) - - [![npm downloads](https://img.shields.io/npm/dm/swagger-stats.svg)](https://img.shields.io/npm/dm/swagger-stats) - - [![Gitter](https://badges.gitter.im/swagger-stats/community.svg)](https://gitter.im/swagger-stats/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) - - - - #### Trace API calls and Monitor API performance, health and usage statistics in Node.js Microservices - - - ### Express, Fastify, Koa, Hapi, Restify - - - **swagger-stats** traces REST API requests and responses in Node.js Microservices, and collects statistics per API Operation. - - **swagger-stats** detects API operations based on express routes. You may also provide [Swagger (Open API) specification](https://swagger.io/specification/), - - and swagger-stats will match API requests with API Operations defined in swagger specification. - - - **swagger-stats** exposes statistics and metrics per API Operation, such as `GET /myapi/:parameter`, or `GET /pet/{petId}` - - - ### Built-In API Telemetry - - - > **swagger-stats** provides built-in Telemetry UX, so you may enable **swagger-stats** in your app, and start monitoring immediately, with no infrastructure requirements. - - > Navigate to `http:///swagger-stats/` - - - - ![swagger-stats Built-In Telemetry](screenshots/swsux.gif?raw=true) - - - - ### API Analytics with [Elasticsearch](https://www.elastic.co/) and [Kibana](https://www.elastic.co/products/kibana) - - - > **swagger-stats** stores details about each request/response in [Elasticsearch](https://www.elastic.co/), so you may use [Kibana](https://www.elastic.co/products/kibana) - - > to perform detailed analysis of API usage over time, build visualizations and dashboards - - - - ![swagger-stats Kibana Dashboard](screenshots/kibana.gif?raw=true) - - - See `dashboards/elastic6` for swagger-stats Kibana visualizations and dashboards - - - ### Monitoring and Alerting with [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) - - - > **swagger-stats** exposes metrics in [Prometheus](https://prometheus.io/) format, so you may use [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) to setup API monitoring and alerting - - - - ![swagger-stats Prometheus Dashboard](screenshots/prometheus-dashboard-2-sm.png?raw=true) - - - - See `dashboards/prometheus` for swagger-stats Grafana dashboards - - - - - With statistics and metrics exposed by **swagger-stats** you may spot problematic API endpoints, see where most of errors happens, - - catch long-running requests, analyze details of last errors, observe trends, setup alerting. - - - **swagger-stats** provides: - - * Metrics in [Prometheus](https://prometheus.io/) format, so you may use [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) to setup API monitoring and alerting - - * Storing details about each API Request/Response in [Elasticsearch](https://www.elastic.co/), so you may use [Kibana](https://www.elastic.co/products/kibana) to perform analysis of API usage over time, build visualizations and dashboards - - * Built-in API Telemetry UI, so you may enable swagger-stats in your app, and start monitoring right away, with no additional tools required - - * Exposing collected statistics via API, including: - - * Counts of requests and responses(total and by response class), processing time (total/avg/max), - - content length(total/avg/max) for requests and responses, rates for requests and errors. - - This is baseline set of stats. - - * Statistics by Request Method: baseline stats collected for each request method - - * Timeline: baseline stats collected for each 1 minute interval during last 60 minutes. Timeline helps you to analyze trends. - - * Errors: count of responses per each error code, top "not found" resources, top "server error" resources - - * Last errors: request and response details for the last 100 errors (last 100 error responses) - - * Longest requests: request and response details for top 100 requests that took longest time to process (time to send response) - - * Tracing: Request and Response details - method, URLs, parameters, request and response headers, addresses, start/stop times and processing duration, matched API Operation info - - * API Statistics: baseline stats and parameter stats per each API Operation. API operation detected based on express routes, and based on [Swagger (Open API) specification](https://swagger.io/specification/) - - * CPU and Memory Usage of Node process - - - - ## How to Use - - - - ### Install - - - ``` - - npm install swagger-stats --save - - ``` - - - If you haven't added prom-client already, you should do this now. It's a [peer dependency](https://nodejs.org/en/blog/npm/peer-dependencies) of swagger-stats as of version [0.95.19](https://github.com/slanatech/swagger-stats/releases/tag/v0.95.19). - - - ``` - - npm install prom-client@12 --save - - ``` - - - ### Enable swagger-stats middleware in your app - - - #### Express - - - ```javascript - - const swStats = require('swagger-stats'); - - const apiSpec = require('swagger.json'); - - app.use(swStats.getMiddleware({swaggerSpec:apiSpec})); - - ``` - - - #### Fastify - - - ```javascript - - const swStats = require('swagger-stats'); - - const apiSpec = require('swagger.json'); - - - const fastify = require('fastify')({ - logger: true - }); - - - // Enable swagger-stats - - fastify.register(require('fastify-express')).then(()=>{ - fastify.register(swStats.getFastifyPlugin, {swaggerSpec:apiSpec}); - }); - - - ``` - - - - #### Koa - - - [`express-to-koa`](https://github.com/kaelzhang/express-to-koa) can be used which is just a simple `Promise` wrapper. - - - ```javascript - - const swStats = require('swagger-stats'); - - const apiSpec = require('swagger.json'); - - const e2k = require('express-to-koa'); - - app.use(e2k(swStats.getMiddleware({ swaggerSpec:apiSpec }))); - - ``` - - - #### Hapi - - - ```javascript - - const swStats = require('swagger-stats'); - - const swaggerSpec = require('./petstore.json'); - - - const init = async () => { - - server = Hapi.server({ - port: 3040, - host: 'localhost' - }); - - await server.register({ - plugin: swStats.getHapiPlugin, - options: { - swaggerSpec:swaggerSpec - } - }); - - await server.start(); - console.log('Server running on %s', server.info.uri); - }; - - ```` - - - #### Restify - - - ```javascript - - const restify = require('restify'); - - const swStats = require('swagger-stats'); - - const apiSpec = require('swagger.json'); - - - const server = restify.createServer(); - - - server.pre(swStats.getMiddleware({ - swaggerSpec:apiSpec, - })); - - ``` - - - See `/examples` for sample apps - - - ### Get Statistics with API - - - - ``` - - $ curl http:///swagger-stats/stats - - { - "startts": 1501647865959, - "all": { - "requests": 7, - "responses": 7, - "errors": 3, - "info": 0, - "success": 3, - "redirect": 1, - "client_error": 2, - "server_error": 1, - "total_time": 510, - "max_time": 502, - "avg_time": 72.85714285714286, - "total_req_clength": 0, - "max_req_clength": 0, - "avg_req_clength": 0, - "total_res_clength": 692, - "max_res_clength": 510, - "avg_res_clength": 98, - "req_rate": 1.0734549915657108, - "err_rate": 0.4600521392424475 - }, - "sys": { - "rss": 59768832, - "heapTotal": 36700160, - "heapUsed": 20081776, - "external": 5291923, - "cpu": 0 - }, - "name": "swagger-stats-testapp", - "version": "0.90.1", - "hostname": "hostname", - "ip": "127.0.0.1" - } - - ``` - - - Take a look at [Documentation](https://swaggerstats.io/guide/) for more details on API and returned statistics. - - - - ### Get Prometheus Metrics - - - - ``` - - $ curl http:///swagger-stats/metrics - - # HELP api_all_request_total The total number of all API requests received - - # TYPE api_all_request_total counter - - api_all_request_total 88715 - - # HELP api_all_success_total The total number of all API requests with success response - - # TYPE api_all_success_total counter - - api_all_success_total 49051 - - # HELP api_all_errors_total The total number of all API requests with error response - - # TYPE api_all_errors_total counter - - api_all_errors_total 32152 - - # HELP api_all_client_error_total The total number of all API requests with client error response - - # TYPE api_all_client_error_total counter - - api_all_client_error_total 22986 - - - . . . . . . . . . . - - - ``` - - - #### Default Metrics - - - - To collect [prom-client default metrics](https://github.com/siimon/prom-client#default-metrics): - - - ```javascript - - const swaggerStats = require('swagger-stats'); - - const promClient = require('prom-client'); - - - promClient.collectDefaultMetrics(); - - ``` - - - Some Node.js specific metrics are included, such as event loop lag: - - - ``` - - # HELP nodejs_eventloop_lag_seconds Lag of event loop in seconds. - - # TYPE nodejs_eventloop_lag_seconds gauge - - nodejs_eventloop_lag_seconds 0.000193641 1597303877464 - - - . . . . . . . . . . - - - ``` - - - - ## Updates - - - See [Changelog](https://github.com/slanatech/swagger-stats/blob/master/CHANGELOG.md) - - - ## Enhancements and Bug Reports - - - If you find a bug, or have an enhancement in mind please post [issues](https://github.com/slanatech/swagger-stats/issues) on GitHub. - - - ## License - - MIT -notonthehighstreet/svelte: > - # Svelte - - - Svelte is a Swagger-to-Ruby object mapper. - - - It reads a Swagger specification file in JSON, and automatically generates Resource Classes with static methods to represent the various HTTP endpoints. - - - [![Code Climate](https://codeclimate.com/github/notonthehighstreet/svelte/badges/gpa.svg)](https://codeclimate.com/github/notonthehighstreet/svelte) - - [![Depfu](https://badges.depfu.com/badges/b93998f152cc3865465c6de0d7284248/overview.svg)](https://depfu.com/github/notonthehighstreet/svelte?project_id=6754) - - [![Depfu](https://badges.depfu.com/badges/b93998f152cc3865465c6de0d7284248/count.svg)](https://depfu.com/github/notonthehighstreet/svelte?project_id=6754) - - - ## Installation - - - Add this line to your application's Gemfile: - - - ```ruby - - gem "svelte" - - ``` - - - And then execute: - - $ bundle - - Or install it yourself as: - - $ gem install svelte - - ## Usage - - - Point a service at an actual API spec. - - - You may pass in a URL pointing to a Swagger spec or the JSON directly: - - - ```ruby - - service = Svelte::Service.create(url: "http://path/to/swagger/spec/resource.json", module_name: 'PetStore') - - service = Svelte::Service.create(json: "{ }", module_name: 'PetStore') - - ``` - - - This will build a dynamically generated client on top of `Svelte::Service::PetStore`. - - - The structure of the new module will be based on the API paths and their respective operations. - - Let's look at an example. Using the complete PetStore spec, we can find the following path: - - - ```json - - "/pet/findByStatus": { - "get": { - "tags": [ - "pet" - ], - "summary": "Finds Pets by status", - "description": "Multiple status values can be provided with comma separated strings", - "operationId": "findPetsByStatus", - "produces": [ - "application/xml", - "application/json" - ], - "parameters": [ - { - "name": "status", - "in": "query", - "description": "Status values that need to be considered for filter", - "required": true, - "type": "array", - "items": { - "type": "string", - "enum": [ - "available", - "pending", - "sold" - ], - "default": "available" - }, - "collectionFormat": "multi" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/Pet" - } - } - }, - "400": { - "description": "Invalid status value" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - } - } - - ``` - - - The path contains two parts: `pet` and `findByStatus`. This will generate - - the following hierarchy in the new module: - - - ```ruby - - Svelte::Service::PetStore::Pet::FindByStatus - - ``` - - - We can see the path has one `get` operation. A method will be generated in the - - `FindByStatus` module based on the `operationId` Swagger attribute, which will - - have the following signature: - - - ```ruby - - Svelte::Service::PetStore::Pet::FindByStatus.find_pets_by_status( - request_payload, - request_options = {} - ) - - ``` - - - Where `request_payload` is a `Hash` representing the parameters of the operation - - and `request_options`, defaulting to an empty `Hash`, will be a `Hash` of - - options to pass to the request. - - - In our case, the parameters would look like this: - - - ```ruby - - request_parameters = { - status: ['available', 'pending'] - } - - ``` - - - ### Responses - - - Svelte will return a [`Faraday::Request`](http://www.rubydoc.info/gems/faraday/0.9.1/Faraday/Response) object as a response to a call. - - - ### Models - - - Svelte also provides generators for Swagger models. They allow an easy way - - to programmatically create and validate requests. - - They also provide an `as_json` that will generate a valid json body for - a given request. - - Consider the definitions key of this Swagger model: - - - ```json - - { - "definitions": { - "MoneyView": { - "id": "MoneyView", - "description": "", - "required": [ - "amount", - "currencyCode" - ], - "extends": "", - "properties": { - "amount": { - "type": "number", - "format": "double", - "description": "Decimal amount" - }, - "currencyCode": { - "type": "string", - "description": "ISO 3 letter currency code" - } - } - } - } - } - - ``` - - - In Svelte you can generate the ruby mapper like this: - - - ```ruby - - class MoneyRequest - extend Svelte::ModelFactory - define_models_from_file(path_to_models_json_file) - end - - - view = MoneyRequest::MoneyView.new - - view.valid? # false - - view.validate # {"currencyCode"=>"Invalid parameter: Missing required parameter", "amount"=>"Invalid parameter: Missing required parameter"} - - view.currencyCode = "GBP" - - view.amount = 40.00 - - view.valid? # true - - view.as_json # {:currencyCode=>"GBP", :amount=>40.0} - - ``` - - - ### Service Options - - - When creating a client from the API spec, you can pass an `options` hash that will determine how the HTTP client interacts with your service. - - - ```ruby - - Svelte::Service.create( - url: "http://path/to/swagger/spec/resource.json", - module_name: 'PetStore', - options: { - host: 'somehost.com', - base_path: '/api/v1', - protocol: 'https', - auth: { - basic: { - username: "user", - password: "pass" - } - }, - headers: { - runas: 'otheruser' - } - }) - ``` - - - The available options are: - - - `host` : overrides the `host` value found in the Swagger API spec, used when making API requests - - - `base_path` : overrides the `basePath` value found in the Swagger API spec, used when making API requests - - - `protocol` : overrides the network protocol used (default value is "http" when not present) - - - `auth` : sets optional authorization headers. Possible values: - - `{ basic: { username: "value", password: "value" } }` : sets basic authentication credentials - - `{ token: "Bearer 12345" }` : sets a generic Authorization header (in this case a Bearer token `12345`) - - `headers` : a collection of arbitrary key/value pairs converted to HTTP request headers included with each outgoing request - - - - ### Request Options - - - You can specify a timeout option on a per request basis. If the request times out a `Svelte::TimeoutError` exception - - will be raised. - - - ```ruby - - begin - Svelte::Service::PetStore::Pet::FindByStatus.find_pets_by_status(request.as_json, { timeout: 10 }) - rescue Svelte::TimeoutError => e - handle_timeout_error(e) - end - - ``` - - - ## Limitations - - - Svelte is still a work in progress gem and it lacks some features that will be - - implemented in the future. Feel free to request or comment on what you'd like - - to see supported. Here is a non exhaustive list of the pitfalls we've identified - - so far: - - - * Supports `application/json` request and response types only - - * API calls return a raw [Faraday::Response] objects. We'll support returning - dynamically generated model responses based on the Swagger spec response - schema - * Request parameter validation is only done for url based parameters. - It'd be possible to add validations to all parameters of the request. - In fact the `ModelFactory` already provides that functionality, but it - requires the client to call `valid?` on the requests to perform the - validation. This should happen automatically - - ## Development - - - After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment. - - - To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). - - - ## Contributing - - - 1. Fork it ( https://github.com/notonthehighstreet/svelte/fork ) - - 2. Create your feature branch (`git checkout -b my-new-feature`) - - 3. Commit your changes (`git commit -am 'Add some feature'`) - - 4. Push to the branch (`git push origin my-new-feature`) - - 5. Create a new Pull Request -domaindrivendev/Swashbuckle.AspNetCore: > - | :mega: Important notice if you're - upgrading between major versions! | - - |--------------| - - |* If you're upgrading from 4.x to 5.x, there's several breaking changes to be aware of. See the [release notes](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/releases/tag/v5.0.0) for details
* If you're making the jump from 3.x to 4.x first, there be dragons there too. See [those release notes here](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/releases/tag/v4.0.0)| - - - Swashbuckle.AspNetCore - - ========= - - - [![Build status](https://ci.appveyor.com/api/projects/status/xpsk2cj1xn12c0r7/branch/master?svg=true)](https://ci.appveyor.com/project/domaindrivendev/ahoy/branch/master) - - - [![Nuget](https://img.shields.io/nuget/v/swashbuckle.aspnetcore)](https://www.nuget.org/packages/swashbuckle.aspnetcore/) - - - [Swagger](http://swagger.io) tooling for APIs built with ASP.NET Core. Generate beautiful API documentation, including a UI to explore and test operations, directly from your routes, controllers and models. - - - In addition to its [Swagger 2.0 and OpenAPI 3.0](http://swagger.io/specification/) generator, Swashbuckle also provides an embedded version of the awesome [swagger-ui](https://github.com/swagger-api/swagger-ui) that's powered by the generated Swagger JSON. This means you can complement your API with living documentation that's always in sync with the latest code. Best of all, it requires minimal coding and maintenance, allowing you to focus on building an awesome API. - - - And that's not all ... - - - Once you have an API that can describe itself in Swagger, you've opened the treasure chest of Swagger-based tools including a client generator that can be targeted to a wide range of popular platforms. See [swagger-codegen](https://github.com/swagger-api/swagger-codegen) for more details. - - - # Compatibility # - - - |Swashbuckle Version|ASP.NET Core|Swagger / OpenAPI Spec.|swagger-ui|ReDoc UI| - - |----------|----------|----------|----------|----------| - - |[master](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/master/README.md)|>= 2.0.0|2.0, 3.0|4.15.5|2.0.0| - - |[6.5.0](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/v6.5.0)|>= 2.0.0|2.0, 3.0|4.15.5|2.0.0| - - |[5.6.3](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/v5.6.3)|>= 2.0.0|2.0, 3.0|3.32.5|2.0.0-rc.40| - - |[4.0.0](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/v4.0.0)|>= 2.0.0, < 3.0.0|2.0|3.19.5|1.22.2| - - |[3.0.0](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/v3.0.0)|>= 1.0.4, < 3.0.0|2.0|3.17.1|1.20.0| - - |[2.5.0](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/tree/v2.5.0)|>= 1.0.4, < 3.0.0|2.0|3.16.0|1.20.0| - - - # Getting Started # - - - 1. Install the standard Nuget package into your ASP.NET Core application. - - ``` - Package Manager : Install-Package Swashbuckle.AspNetCore -Version 6.5.0 - CLI : dotnet add package --version 6.5.0 Swashbuckle.AspNetCore - ``` - - 2. In the `ConfigureServices` method of `Startup.cs`, register the Swagger generator, defining one or more Swagger documents. - - ```csharp - using Microsoft.OpenApi.Models; - ``` - - ```csharp - services.AddMvc(); - - services.AddSwaggerGen(c => - { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); - }); - ``` - - 3. Ensure your API actions and parameters are decorated with explicit "Http" and "From" bindings. - - ```csharp - [HttpPost] - public void CreateProduct([FromBody]Product product) - ... - ``` - - ```csharp - [HttpGet] - public IEnumerable SearchProducts([FromQuery]string keywords) - ... - ``` - - _NOTE: If you omit the explicit parameter bindings, the generator will describe them as "query" params by default._ - - 4. In the `Configure` method,you should expose the generated Swagger as JSON endpoint(s) by one of following method: - - - Add endpoints if you're using endpoint-based routing. - - ```csharp - app.MapEndpoints(endpoints => - { - // ... - endpoints.MapSwagger(); - }); - ``` - - - Insert middleware - - ```csharp - app.UseSwagger(); - ``` - - _At this point, you can spin up your application and view the generated Swagger JSON at "/swagger/v1/swagger.json."_ - - 5. Optionally, insert the swagger-ui middleware if you want to expose interactive documentation, specifying the Swagger JSON endpoint(s) to power it from. - - ```csharp - app.UseSwaggerUI(c => - { - c.SwaggerEndpoint("v1/swagger.json", "My API V1"); - }); - ``` - - _Now you can restart your application and check out the auto-generated, interactive docs at "/swagger"._ - - # System.Text.Json (STJ) vs Newtonsoft # - - - In versions prior to `5.0.0`, Swashbuckle will generate Schema's (descriptions of the data types exposed by an API) based on the behavior of the *Newtonsoft* serializer. This made sense because that was the serializer that shipped with ASP.NET Core at the time. However, since version `3.0.0`, ASP.NET Core introduces a new serializer *System.Text.Json (STJ)* out-of-the-box, and if you want to continue using *Newtonsoft*, you need to install a separate package and explicitly opt-in. From Swashbuckle `5.0.0` and beyond a similar pattern is used. That is, out-of-the-box Swashbuckle will assume you're using the *STJ* serializer and generate Schema's based on its behavior. If you're using *Newtonsoft*, then you'll need to install a separate Swashbuckle package and explicitly opt-in. **This is a required step, regardless of which version of ASP.NET Core you're using**. - - - In summary ... - - - If you're using **System.Text.Json (STJ)**, then the setup described above will be sufficient, and *STJ* options/attributes will be automatically honored by the Swagger generator. - - - If you're using **Newtonsoft**, then you'll need to install a separate package and explicitly opt-in to ensure that *Newtonsoft* settings/attributes are automatically honored by the Swagger generator: - - - ``` - - Package Manager : Install-Package Swashbuckle.AspNetCore.Newtonsoft -Version 6.5.0 - - CLI : dotnet add package --version 6.5.0 Swashbuckle.AspNetCore.Newtonsoft - - ``` - - - ```csharp - - services.AddMvc(); - - - services.AddSwaggerGen(c => - - { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); - }); - - services.AddSwaggerGenNewtonsoftSupport(); // explicit opt-in - needs to be placed after AddSwaggerGen() - - ``` - - - # Swashbuckle, ApiExplorer, and Routing # - - - Swashbuckle relies heavily on `ApiExplorer`, the API metadata layer that ships with ASP.NET Core. If you're using the `AddMvc` helper to bootstrap the MVC stack, then ApiExplorer will be automatically registered and SB will work without issue. However, if you're using `AddMvcCore` for a more paired-down MVC stack, you'll need to explicitly add the ApiExplorer service: - - - ```csharp - - services.AddMvcCore() - .AddApiExplorer(); - ``` - - - Additionally, if you are using _[conventional routing](https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing#conventional-routing)_ (as opposed to attribute routing), any controllers and the actions on those controllers that use conventional routing will not be represented in ApiExplorer, which means Swashbuckle won't be able to find those controllers and generate Swagger operations from them. For instance: - - - ```csharp - - app.UseMvc(routes => - - { - // SwaggerGen won't find controllers that are routed via this technique. - routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); - }); - - ``` - - - You **must** use attribute routing for any controllers that you want represented in your Swagger document(s): - - - ```csharp - - [Route("example")] - - public class ExampleController : Controller - - { - [HttpGet("")] - public IActionResult DoStuff() { /**/ } - } - - ``` - - Refer to the [routing documentation](https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing) for more information. - - - # Components # - - - Swashbuckle consists of multiple components that can be used together or individually depending on your needs. At its core, there's a Swagger generator, middleware to expose it as JSON endpoints, and a packaged version of the [swagger-ui](https://github.com/swagger-api/swagger-ui). These 3 packages can be installed with the `Swashbuckle.AspNetCore` "metapackage" and will work together seamlessly (see [Getting Started](#getting-started)) to provide beautiful API docs that are automatically generated from your code. - - - Additionally, there's add-on packages (CLI tools, [an alternate UI](https://github.com/Rebilly/ReDoc) etc.) that you can optionally install and configure as needed. - - - ## "Core" Packages (i.e. installed via Swashbuckle.AspNetCore) - - - |Package|Description| - - |---------|-----------| - - |Swashbuckle.AspNetCore.Swagger|Exposes Swagger JSON endpoints. It expects an implementation of `ISwaggerProvider` to be registered in the DI container, which it queries to retrieve `OpenAPIDocument(s)` that are then exposed as serialized JSON| - - |Swashbuckle.AspNetCore.SwaggerGen|Injects an implementation of `ISwaggerProvider` that can be used by the above component. This particular implementation generates `OpenApiDocument(s)` from your routes, controllers and models| - - |Swashbuckle.AspNetCore.SwaggerUI|Exposes an embedded version of the swagger-ui. You specify the API endpoints where it can obtain Swagger JSON, and it uses them to power interactive docs for your API| - - - ## Additional Packages ## - - - |Package|Description| - - |---------|-----------| - - |Swashbuckle.AspNetCore.Annotations|Includes a set of custom attributes that can be applied to controllers, actions and models to enrich the generated Swagger| - - |Swashbuckle.AspNetCore.Cli|Provides a command line interface for retrieving Swagger directly from a startup assembly, and writing to file| - - |Swashbuckle.AspNetCore.ReDoc|Exposes an embedded version of the ReDoc UI (an alternative to swagger-ui)| - - - ## Community Packages ## - - - These packages are provided by the open-source community. - - - |Package|Description| - - |---------|-----------| - - |[Swashbuckle.AspNetCore.Filters](https://github.com/mattfrear/Swashbuckle.AspNetCore.Filters)| Some useful Swashbuckle filters which add additional documentation, e.g. request and response examples, authorization information, etc. See its Readme for more details | - - |[Unchase.Swashbuckle.AspNetCore.Extensions](https://github.com/unchase/Unchase.Swashbuckle.AspNetCore.Extensions)| Some useful extensions (filters), which add additional documentation, e.g. hide PathItems for unaccepted roles, fix enums for client code generation, etc. See its Readme for more details | - - |[MicroElements.Swashbuckle.FluentValidation](https://github.com/micro-elements/MicroElements.Swashbuckle.FluentValidation)| Use FluentValidation rules instead of ComponentModel attributes to augment generated Swagger Schemas | - - |[MMLib.SwaggerForOcelot](https://github.com/Burgyn/MMLib.SwaggerForOcelot)| Aggregate documentations over microservices directly on Ocelot API Gateway | - - - # Configuration & Customization # - - - The steps described above will get you up and running with minimal setup. However, Swashbuckle offers a lot of flexibility to customize as you see fit. Check out the table below for the full list of options: - - - * [Swashbuckle.AspNetCore.Swagger](#swashbuckleaspnetcoreswagger) - - * [Change the Path for Swagger JSON Endpoints](#change-the-path-for-swagger-json-endpoints) - * [Modify Swagger with Request Context](#modify-swagger-with-request-context) - * [Serialize Swagger JSON in the 2.0 format](#serialize-swagger-in-the-20-format) - * [Working with Virtual Directories and Reverse Proxies](#working-with-virtual-directories-and-reverse-proxies) - - * [Swashbuckle.AspNetCore.SwaggerGen](#swashbuckleaspnetcoreswaggergen) - - * [Assign Explicit OperationIds](#assign-explicit-operationids) - * [List Operations Responses](#list-operation-responses) - * [Flag Required Parameters and Schema Properties](#flag-required-parameters-and-schema-properties) - * [Handle Forms and File Uploads](#handle-forms-and-file-uploads) - * [Handle File Downloads](#handle-file-downloads) - * [Include Descriptions from XML Comments](#include-descriptions-from-xml-comments) - * [Provide Global API Metadata](#provide-global-api-metadata) - * [Generate Multiple Swagger Documents](#generate-multiple-swagger-documents) - * [Omit Obsolete Operations and/or Schema Properties](#omit-obsolete-operations-andor-schema-properties) - * [Omit Arbitrary Operations](#omit-arbitrary-operations) - * [Customize Operation Tags (e.g. for UI Grouping)](#customize-operation-tags-eg-for-ui-grouping) - * [Change Operation Sort Order (e.g. for UI Sorting)](#change-operation-sort-order-eg-for-ui-sorting) - * [Customize Schema Id's](#customize-schema-ids) - * [Override Schema for Specific Types](#override-schema-for-specific-types) - * [Extend Generator with Operation, Schema & Document Filters](#extend-generator-with-operation-schema--document-filters) - * [Add Security Definitions and Requirements](#add-security-definitions-and-requirements) - * [Add Security Definitions and Requirements for Bearer auth](#add-security-definitions-and-requirements-bearer) - * [Inheritance and Polymorphism](#inheritance-and-polymorphism) - - * [Swashbuckle.AspNetCore.SwaggerUI](#swashbuckleaspnetcoreswaggerui) - * [Change Relative Path to the UI](#change-relative-path-to-the-ui) - * [Change Document Title](#change-document-title) - * [List Multiple Swagger Documents](#list-multiple-swagger-documents) - * [Apply swagger-ui Parameters](#apply-swagger-ui-parameters) - * [Inject Custom CSS](#inject-custom-css) - * [Customize index.html](#customize-indexhtml) - * [Enable OAuth2.0 Flows](#enable-oauth20-flows) - * [Use client-side request and response interceptors](#use-client-side-request-and-response-interceptors) - - * [Swashbuckle.AspNetCore.Annotations](#swashbuckleaspnetcoreannotations) - * [Install and Enable Annotations](#install-and-enable-annotations) - * [Enrich Operation Metadata](#enrich-operation-metadata) - * [Enrich Response Metadata](#enrich-response-metadata) - * [Enrich Parameter Metadata](#enrich-parameter-metadata) - * [Enrich RequestBody Metadata](#enrich-requestbody-metadata) - * [Enrich Schema Metadata](#enrich-schema-metadata) - * [Apply Schema Filters to Specific Types](#apply-schema-filters-to-specific-types) - * [Add Tag Metadata](#add-tag-metadata) - - * [Swashbuckle.AspNetCore.Cli](#swashbuckleaspnetcorecli) - * [Retrieve Swagger Directly from a Startup Assembly](#retrieve-swagger-directly-from-a-startup-assembly) - * [Use the CLI Tool with a Custom Host Configuration](#use-the-cli-tool-with-a-custom-host-configuration) - - * [Swashbuckle.AspNetCore.ReDoc](#swashbuckleaspnetcoreredoc) - * [Change Relative Path to the UI](#redoc-change-relative-path-to-the-ui) - * [Change Document Title](#redoc-change-document-title) - * [Apply ReDoc Parameters](#apply-redoc-parameters) - * [Inject Custom CSS](#redoc-inject-custom-css) - * [Customize index.html](#redoc-customize-indexhtml) - - ## Swashbuckle.AspNetCore.Swagger ## - - - ### Change the Path for Swagger JSON Endpoints ### - - - By default, Swagger JSON will be exposed at the following route - "/swagger/{documentName}/swagger.json". If necessary, you can change this when enabling the Swagger middleware. Custom routes MUST include the `{documentName}` parameter. - - - ```csharp - - app.UseSwagger(c => - - { - c.RouteTemplate = "api-docs/{documentName}/swagger.json"; - }) - - ``` - - - _NOTE: If you're using the SwaggerUI middleware, you'll also need to update its configuration to reflect the new endpoints:_ - - - ```csharp - - app.UseSwaggerUI(c => - - { - c.SwaggerEndpoint("/api-docs/v1/swagger.json", "My API V1"); - }) - - ``` - - - _NOTE: If you also need to update the relative path that the UI itself is available on, you'll need to follow the instructions found in [Change Relative Path to the UI](#change-relative-path-to-the-ui)._ - - - ### Modify Swagger with Request Context ### - - - If you need to set some Swagger metadata based on the current request, you can configure a filter that's executed prior to serializing the document. - - - ```csharp - - app.UseSwagger(c => - - { - c.PreSerializeFilters.Add((swagger, httpReq) => - { - swagger.Servers = new List { new OpenApiServer { Url = $"{httpReq.Scheme}://{httpReq.Host.Value}" } }; - }); - }); - - ``` - - - The `OpenApiDocument` and the current `HttpRequest` are both passed to the filter. This provides a lot of flexibility. For example, you can add an explicit API server based on the "Host" header (as shown), or you could inspect session information or an Authorization header and remove operations from the document based on user permissions. - - - ### Serialize Swagger in the 2.0 format ### - - - By default, Swashbuckle will generate and expose Swagger JSON in version 3.0 of the specification, officially called the OpenAPI Specification. However, to support backwards compatibility, you can opt to continue exposing it in the 2.0 format with the following option: - - - ```csharp - - app.UseSwagger(c => - - { - c.SerializeAsV2 = true; - }); - - ``` - - - ### Working with Virtual Directories and Reverse Proxies ### - - - Virtual directories and reverse proxies can cause issues for applications that generate links and redirects, particularly if the app returns *absolute* URLs based on the `Host` header and other information from the current request. To avoid these issues, Swashbuckle uses *relative* URLs where possible, and encourages their use when configuring the SwaggerUI and ReDoc middleware. - - - For example, to wire up the SwaggerUI middleware, you provide the URL to one or more OpenAPI/Swagger documents. This is the URL that the swagger-ui, a client-side application, will call to retrieve your API metadata. To ensure this works behind virtual directories and reverse proxies, you should express this relative to the `RoutePrefix` of the swagger-ui itself: - - - ```csharp - - app.UseSwaggerUI(c => - - { - c.RoutePrefix = "swagger"; - c.SwaggerEndpoint("v1/swagger.json", "My API V1"); - }); - - ``` - - - _NOTE: In previous versions of the docs, you may have seen this expressed as a root-relative link (e.g. `/swagger/v1/swagger.json`). This won't work if your app is hosted on an IIS virtual directory or behind a proxy that trims the request path before forwarding. If you switch to the *page-relative* syntax shown above, it should work in all cases._ - - - ## Swashbuckle.AspNetCore.SwaggerGen ## - - - ### Assign Explicit OperationIds ### - - - In Swagger, operations MAY be assigned an `operationId`. This ID MUST be unique among all operations described in the API. Tools and libraries (e.g. client generators) MAY use the operationId to uniquely identify an operation, therefore, it is RECOMMENDED to follow common programming naming conventions. - - - Auto-generating an ID that matches these requirements, while also providing a name that would be meaningful in client libraries is a non-trivial task and so, Swashbuckle omits the `operationId` by default. However, if necessary, you can assign `operationIds` by decorating individual routes OR by providing a custom strategy. - - - __Option 1) Decorate routes with a `Name` property__ - - - ```csharp - - [HttpGet("{id}", Name = "GetProductById")] - - public IActionResult Get(int id) // operationId = "GetProductById" - - ``` - - - __Option 2) Provide a custom strategy__ - - - ```csharp - - // Startup.cs - - services.AddSwaggerGen(c => - - { - ... - - // Use method name as operationId - c.CustomOperationIds(apiDesc => - { - return apiDesc.TryGetMethodInfo(out MethodInfo methodInfo) ? methodInfo.Name : null; - }); - }) - - - // ProductsController.cs - - [HttpGet("{id}")] - - public IActionResult GetProductById(int id) // operationId = "GetProductById" - - ``` - - - _NOTE: With either approach, API authors are responsible for ensuring the uniqueness of `operationIds` across all Operations_ - - - ### List Operation Responses ### - - - By default, Swashbuckle will generate a "200" response for each operation. If the action returns a response DTO, then this will be used to generate a schema for the response body. For example ... - - - ```csharp - - [HttpPost("{id}")] - - public Product GetById(int id) - - ``` - - - Will produce the following response metadata: - - - ``` - - responses: { - 200: { - description: "Success", - content: { - "application/json": { - schema: { - $ref: "#/components/schemas/Product" - } - } - } - } - } - - ``` - - - #### Explicit Responses #### - - - If you need to specify a different status code and/or additional responses, or your actions return `IActionResult` instead of a response DTO, you can explicitly describe responses with the `ProducesResponseTypeAttribute` that ships with ASP.NET Core. For example ... - - - ```csharp - - [HttpPost("{id}")] - - [ProducesResponseType(typeof(Product), 200)] - - [ProducesResponseType(typeof(IDictionary), 400)] - - [ProducesResponseType(500)] - - public IActionResult GetById(int id) - - ``` - - - Will produce the following response metadata: - - - ``` - - responses: { - 200: { - description: "Success", - content: { - "application/json": { - schema: { - $ref: "#/components/schemas/Product" - } - } - } - }, - 400: { - description: "Bad Request", - content: { - "application/json": { - schema: { - type: "object", - additionalProperties: { - type: "string" - } - } - } - } - }, - 500: { - description: "Server Error", - content: {} - } - } - - ``` - - - ### Flag Required Parameters and Schema Properties ### - - - In a Swagger document, you can flag parameters and schema properties that are required for a request. If a parameter (top-level or property-based) is decorated with the `BindRequiredAttribute` or `RequiredAttribute`, then Swashbuckle will automatically flag it as a "required" parameter in the generated Swagger: - - - ```csharp - - // ProductsController.cs - - public IActionResult Search([FromQuery, BindRequired]string keywords, [FromQuery]PagingParams pagingParams) - - { - if (!ModelState.IsValid) - return BadRequest(ModelState); - ... - } - - - // SearchParams.cs - - public class PagingParams - - { - [Required] - public int PageNo { get; set; } - - public int PageSize { get; set; } - } - - ``` - - - In addition to parameters, Swashbuckle will also honor the `RequiredAttribute` when used in a model that's bound to the request body. In this case, the decorated properties will be flagged as "required" properties in the body description: - - - ```csharp - - // ProductsController.cs - - public IActionResult Create([FromBody]Product product) - - { - if (!ModelState.IsValid) - return BadRequest(ModelState); - ... - } - - - // Product.cs - - public class Product - - { - [Required] - public string Name { get; set; } - - public string Description { get; set; } - } - - ``` - - - ### Handle Forms and File Uploads ### - - - This controller will accept two form field values and one named file upload from the same form: - - - ```csharp - - [HttpPost] - - public void UploadFile([FromForm]string description, [FromForm]DateTime clientDate, IFormFile file) - - ``` - - - > Important note: As per the [ASP.NET Core docs](https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-3.1), you're not supposed to decorate `IFormFile` parameters with the `[FromForm]` attribute as the binding source is automatically inferred from the type. In fact, the inferred value is `BindingSource.FormFile` and if you apply the attribute it will be set to `BindingSource.Form` instead, which screws up `ApiExplorer`, the metadata component that ships with ASP.NET Core and is heavily relied on by Swashbuckle. One particular issue here is that SwaggerUI will not treat the parameter as a file and so will not display a file upload button, if you do mistakenly include this attribute. - - - ### Handle File Downloads ### - - `ApiExplorer` (the ASP.NET Core metadata component that Swashbuckle is built on) *DOES NOT* surface the `FileResult` type by default and so you need to explicitly tell it to with the `Produces` attribute: - - ```csharp - - [HttpGet("{fileName}")] - - [Produces("application/octet-stream", Type = typeof(FileResult))] - - public FileResult GetFile(string fileName) - - ``` - - If you want the swagger-ui to display a "Download file" link, you're operation will need to return a **Content-Type of "application/octet-stream"** or a **Content-Disposition of "attachement"**. - - - ### Include Descriptions from XML Comments ### - - - To enhance the generated docs with human-friendly descriptions, you can annotate controller actions and models with [Xml Comments](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/xmldoc) and configure Swashbuckle to incorporate those comments into the outputted Swagger JSON: - - - 1. Open the Properties dialog for your project, click the "Build" tab and ensure that "XML documentation file" is checked, or add `true` element to the `` section of your .csproj project file. This will produce a file containing all XML comments at build-time. - - _At this point, any classes or methods that are NOT annotated with XML comments will trigger a build warning. To suppress this, enter the warning code "1591" into the "Suppress warnings" field in the properties dialog or add `1591` to the `` section of your .csproj project file._ - - 2. Configure Swashbuckle to incorporate the XML comments on file into the generated Swagger JSON: - - ```csharp - services.AddSwaggerGen(c => - { - c.SwaggerDoc("v1", - new OpenApiInfo - { - Title = "My API - V1", - Version = "v1" - } - ); - - var filePath = Path.Combine(System.AppContext.BaseDirectory, "MyApi.xml"); - c.IncludeXmlComments(filePath); - } - ``` - - 3. Annotate your actions with summary, remarks, param and response tags: - - ```csharp - /// - /// Retrieves a specific product by unique id - /// - /// Awesomeness! - /// The product id - /// Product retrieved - /// Product not found - /// Oops! Can't lookup your product right now - [HttpGet("{id}")] - [ProducesResponseType(typeof(Product), 200)] - [ProducesResponseType(404)] - [ProducesResponseType(500)] - public Product GetById(int id) - ``` - - - 4. You can also annotate types with summary and example tags: - - ```csharp - public class Product - { - /// - /// The name of the product - /// - /// Men's basketball shoes - public string Name { get; set; } - - /// - /// Quantity left in stock - /// - /// 10 - public int AvailableStock { get; set; } - - /// - /// The sizes the product is available in - /// - /// ["Small", "Medium", "Large"] - public List Sizes { get; set; } - } - ``` - - 5. Rebuild your project to update the XML Comments file and navigate to the Swagger JSON endpoint. Note how the descriptions are mapped onto corresponding Swagger fields. - - - _NOTE: You can also provide Swagger Schema descriptions by annotating your API models and their properties with summary tags. If you have multiple XML comments files (e.g. separate libraries for controllers and models), you can invoke the IncludeXmlComments method multiple times and they will all be merged into the outputted Swagger JSON._ - - - ### Provide Global API Metadata ### - - - In addition to "PathItems", "Operations" and "Responses", which Swashbuckle generates for you, Swagger also supports global metadata (see https://swagger.io/specification/#oasObject). For example, you can provide a full description for your API, terms of service or even contact and licensing information: - - - ```csharp - - c.SwaggerDoc("v1", - new OpenApiInfo - { - Title = "My API - V1", - Version = "v1", - Description = "A sample API to demo Swashbuckle", - TermsOfService = new Uri("http://tempuri.org/terms"), - Contact = new OpenApiContact - { - Name = "Joe Developer", - Email = "joe.developer@tempuri.org" - }, - License = new OpenApiLicense - { - Name = "Apache 2.0", - Url = new Uri("http://www.apache.org/licenses/LICENSE-2.0.html") - } - } - ); - - ``` - - - _TIP: Use IntelliSense to see what other fields are available._ - - - ### Generate Multiple Swagger Documents ### - - - With the setup described above, the generator will include all API operations in a single Swagger document. However, you can create multiple documents if necessary. For example, you may want a separate document for each version of your API. To do this, start by defining multiple Swagger docs in `Startup.cs`: - - - ```csharp - - services.AddSwaggerGen(c => - - { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API - V1", Version = "v1" }); - c.SwaggerDoc("v2", new OpenApiInfo { Title = "My API - V2", Version = "v2" }); - }) - - ``` - - - _Take note of the first argument to SwaggerDoc. It MUST be a URI-friendly name that uniquely identifies the document. It's subsequently used to make up the path for requesting the corresponding Swagger JSON. For example, with the default routing, the above documents will be available at "/swagger/v1/swagger.json" and "/swagger/v2/swagger.json"._ - - - Next, you'll need to inform Swashbuckle which actions to include in each document. Although this can be customized (see below), by default, the generator will use the `ApiDescription.GroupName` property, part of the built-in metadata layer that ships with ASP.NET Core, to make this distinction. You can set this by decorating individual actions OR by applying an application wide convention. - - - #### Decorate Individual Actions #### - - - To include an action in a specific Swagger document, decorate it with the `ApiExplorerSettingsAttribute` and set `GroupName` to the corresponding document name (case sensitive): - - - ```csharp - - [HttpPost] - - [ApiExplorerSettings(GroupName = "v2")] - - public void Post([FromBody]Product product) - - ``` - - - #### Assign Actions to Documents by Convention #### - - - To group by convention instead of decorating every action, you can apply a custom controller or action convention. For example, you could wire up the following convention to assign actions to documents based on the controller namespace. - - - ```csharp - - // ApiExplorerGroupPerVersionConvention.cs - - public class ApiExplorerGroupPerVersionConvention : IControllerModelConvention - - { - public void Apply(ControllerModel controller) - { - var controllerNamespace = controller.ControllerType.Namespace; // e.g. "Controllers.V1" - var apiVersion = controllerNamespace.Split('.').Last().ToLower(); - - controller.ApiExplorer.GroupName = apiVersion; - } - } - - - // Startup.cs - - public void ConfigureServices(IServiceCollection services) - - { - services.AddMvc(c => - c.Conventions.Add(new ApiExplorerGroupPerVersionConvention()) - ); - - ... - } - - ``` - - - #### Customize the Action Selection Process #### - - - When selecting actions for a given Swagger document, the generator invokes a `DocInclusionPredicate` against every `ApiDescription` that's surfaced by the framework. The default implementation inspects `ApiDescription.GroupName` and returns true if the value is either null OR equal to the requested document name. However, you can also provide a custom inclusion predicate. For example, if you're using an attribute-based approach to implement API versioning (e.g. Microsoft.AspNetCore.Mvc.Versioning), you could configure a custom predicate that leverages the versioning attributes instead: - - - ```csharp - - c.DocInclusionPredicate((docName, apiDesc) => - - { - if (!apiDesc.TryGetMethodInfo(out MethodInfo methodInfo)) return false; - - var versions = methodInfo.DeclaringType - .GetCustomAttributes(true) - .OfType() - .SelectMany(attr => attr.Versions); - - return versions.Any(v => $"v{v.ToString()}" == docName); - }); - - ``` - - - #### Exposing Multiple Documents through the UI #### - - - If you're using the `SwaggerUI` middleware, you'll need to specify any additional Swagger endpoints you want to expose. See [List Multiple Swagger Documents](#list-multiple-swagger-documents) for more. - - - ### Omit Obsolete Operations and/or Schema Properties ### - - - The [Swagger spec](http://swagger.io/specification/) includes a `deprecated` flag for indicating that an operation is deprecated and should be refrained from use. The Swagger generator will automatically set this flag if the corresponding action is decorated with the `ObsoleteAttribute`. However, instead of setting a flag, you can configure the generator to ignore obsolete actions altogether: - - - ```csharp - - services.AddSwaggerGen(c => - - { - ... - c.IgnoreObsoleteActions(); - }; - - ``` - - - A similar approach can also be used to omit obsolete properties from Schemas in the Swagger output. That is, you can decorate model properties with the `ObsoleteAttribute` and configure Swashbuckle to omit those properties when generating JSON Schemas: - - - ```csharp - - services.AddSwaggerGen(c => - - { - ... - c.IgnoreObsoleteProperties(); - }; - - ``` - - - ### Omit Arbitrary Operations ### - - - You can omit operations from the Swagger output by decorating individual actions OR by applying an application wide convention. - - - #### Decorate Individual Actions #### - - - To omit a specific action, decorate it with the `ApiExplorerSettingsAttribute` and set the `IgnoreApi` flag: - - - ```csharp - - [HttpGet("{id}")] - - [ApiExplorerSettings(IgnoreApi = true)] - - public Product GetById(int id) - - ``` - - - #### Omit Actions by Convention #### - - - To omit actions by convention instead of decorating them individually, you can apply a custom action convention. For example, you could wire up the following convention to only document GET operations: - - - ```csharp - - // ApiExplorerGetsOnlyConvention.cs - - public class ApiExplorerGetsOnlyConvention : IActionModelConvention - - { - public void Apply(ActionModel action) - { - action.ApiExplorer.IsVisible = action.Attributes.OfType().Any(); - } - } - - - // Startup.cs - - public void ConfigureServices(IServiceCollection services) - - { - services.AddMvc(c => - c.Conventions.Add(new ApiExplorerGetsOnlyConvention()) - ); - - ... - } - - ``` - - - ### Customize Operation Tags (e.g. for UI Grouping) ### - - - The [Swagger spec](http://swagger.io/specification/) allows one or more "tags" to be assigned to an operation. The Swagger generator will assign the controller name as the default tag. This is important to note if you're using the `SwaggerUI` middleware as it uses this value to group operations. - - - You can override the default tag by providing a function that applies tags by convention. For example, the following configuration will tag, and therefore group operations in the UI, by HTTP method: - - - ```csharp - - services.AddSwaggerGen(c => - - { - ... - c.TagActionsBy(api => api.HttpMethod); - }; - - ``` - - - ### Change Operation Sort Order (e.g. for UI Sorting) ### - - - By default, actions are ordered by assigned tag (see above) before they're grouped into the path-centric, nested structure of the [Swagger spec](http://swagger.io/specification). But, you can change the default ordering of actions with a custom sorting strategy: - - - ```csharp - - services.AddSwaggerGen(c => - - { - ... - c.OrderActionsBy((apiDesc) => $"{apiDesc.ActionDescriptor.RouteValues["controller"]}_{apiDesc.HttpMethod}"); - }; - - ``` - - - _NOTE: This dictates the sort order BEFORE actions are grouped and transformed into the Swagger format. So, it affects the ordering of groups (i.e. Swagger "PathItems"), AND the ordering of operations within a group, in the Swagger output._ - - - ### Customize Schema Id's ### - - - If the generator encounters complex parameter or response types, it will generate a corresponding JSON Schema, add it to the global `components/schemas` dictionary, and reference it from the operation description by unique Id. For example, if you have an action that returns a `Product` type, then the generated schema will be referenced as follows: - - - ``` - - responses: { - 200: { - description: "Success", - content: { - "application/json": { - schema: { - $ref: "#/components/schemas/Product" - } - } - } - } - } - - ``` - - - However, if it encounters multiple types with the same name but different namespaces (e.g. `RequestModels.Product` & `ResponseModels.Product`), then Swashbuckle will raise an exception due to "Conflicting schemaIds". In this case, you'll need to provide a custom Id strategy that further qualifies the name: - - - ```csharp - - services.AddSwaggerGen(c => - - { - ... - c.CustomSchemaIds((type) => type.FullName); - }; - - ``` - - - ### Override Schema for Specific Types ### - - - Out-of-the-box, Swashbuckle does a decent job at generating JSON Schemas that accurately describe your request and response payloads. However, if you're customizing serialization behavior for certain types in your API, you may need to help it out. - - - For example, you might have a class with multiple properties that you want to represent in JSON as a comma-separated string. To do this you would probably implement a custom `JsonConverter`. In this case, Swashbuckle doesn't know how the converter is implemented and so you would need to provide it with a Schema that accurately describes the type: - - - ```csharp - - // PhoneNumber.cs - - public class PhoneNumber - - { - public string CountryCode { get; set; } - - public string AreaCode { get; set; } - - public string SubscriberId { get; set; } - } - - - // Startup.cs - - services.AddSwaggerGen(c => - - { - ... - c.MapType(() => new OpenApiSchema { Type = "string" }); - }; - - ``` - - - ### Extend Generator with Operation, Schema & Document Filters ### - - - Swashbuckle exposes a filter pipeline that hooks into the generation process. Once generated, individual metadata objects are passed into the pipeline where they can be modified further. You can wire up custom filters to enrich the generated "Operations", "Schemas" and "Documents". - - - #### Operation Filters #### - - - Swashbuckle retrieves an `ApiDescription`, part of ASP.NET Core, for every action and uses it to generate a corresponding `OpenApiOperation`. Once generated, it passes the `OpenApiOperation` and the `ApiDescription` through the list of configured Operation Filters. - - - In a typical filter implementation, you would inspect the `ApiDescription` for relevant information (e.g. route info, action attributes etc.) and then update the `OpenApiOperation` accordingly. For example, the following filter lists an additional "401" response for all actions that are decorated with the `AuthorizeAttribute`: - - - ```csharp - - // AuthResponsesOperationFilter.cs - - public class AuthResponsesOperationFilter : IOperationFilter - - { - public void Apply(OpenApiOperation operation, OperationFilterContext context) - { - var authAttributes = context.MethodInfo.DeclaringType.GetCustomAttributes(true) - .Union(context.MethodInfo.GetCustomAttributes(true)) - .OfType(); - - if (authAttributes.Any()) - operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" }); - } - } - - - // Startup.cs - - services.AddSwaggerGen(c => - - { - ... - c.OperationFilter(); - }; - - ``` - - - _NOTE: Filter pipelines are DI-aware. That is, you can create filters with constructor parameters and if the parameter types are registered with the DI framework, they'll be automatically injected when the filters are instantiated_ - - - #### Schema Filters #### - - - Swashbuckle generates a Swagger-flavored [JSONSchema](http://swagger.io/specification/#schemaObject) for every parameter, response and property type that's exposed by your controller actions. Once generated, it passes the schema and type through the list of configured Schema Filters. - - - The example below adds an AutoRest vendor extension (see https://github.com/Azure/autorest/blob/master/docs/extensions/readme.md#x-ms-enum) to inform the AutoRest tool how enums should be modelled when it generates the API client. - - - ```csharp - - // AutoRestSchemaFilter.cs - - public class AutoRestSchemaFilter : ISchemaFilter - - { - public void Apply(OpenApiSchema schema, SchemaFilterContext context) - { - var type = context.Type; - if (type.IsEnum) - { - schema.Extensions.Add( - "x-ms-enum", - new OpenApiObject - { - ["name"] = new OpenApiString(type.Name), - ["modelAsString"] = new OpenApiBoolean(true) - } - ); - }; - } - } - - - // Startup.cs - - services.AddSwaggerGen(c => - - { - ... - c.SchemaFilter(); - }; - - ``` - - - The example below allows for automatic schema generation of generic `Dictionary` objects. - - Note that this only generates the swagger; `System.Text.Json` is not able to parse dictionary enums by default, - - so you will need [a special JsonConverter, like in the .NET docs](https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-5-0#sample-factory-pattern-converter) - - - ```csharp - - // DictionaryTKeyEnumTValueSchemaFilter.cs - - public class DictionaryTKeyEnumTValueSchemaFilter : ISchemaFilter - - { - public void Apply(OpenApiSchema schema, SchemaFilterContext context) - { - // Only run for fields that are a Dictionary - if (!context.Type.IsGenericType || !context.Type.GetGenericTypeDefinition().IsAssignableFrom(typeof(Dictionary<,>))) - { - return; - } - - var keyType = context.Type.GetGenericArguments()[0]; - var valueType = context.Type.GetGenericArguments()[1]; - - if (!keyType.IsEnum) - { - return; - } - - schema.Type = "object"; - schema.Properties = keyType.GetEnumNames().ToDictionary(name => name, - name => context.SchemaGenerator.GenerateSchema(valueType, - context.SchemaRepository)); - } - } - - - // Startup.cs - - services.AddSwaggerGen(c => - - { - ... - // These will be replaced by DictionaryTKeyEnumTValueSchemaFilter, but are needed to avoid an error. - // You will need one for every kind of Dictionary<,> you have. - c.MapType>>(() => new OpenApiSchema()); - c.SchemaFilter(); - }; - - ``` - - #### Document Filters #### - - - Once an `OpenApiDocument` has been generated, it too can be passed through a set of pre-configured Document Filters. This gives full control to modify the document however you see fit. To ensure you're still returning valid Swagger JSON, you should have a read through the [specification](http://swagger.io/specification/) before using this filter type. - - - The example below provides a description for any tags that are assigned to operations in the document: - - - ```csharp - - public class TagDescriptionsDocumentFilter : IDocumentFilter - - { - public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) - { - swaggerDoc.Tags = new List { - new OpenApiTag { Name = "Products", Description = "Browse/manage the product catalog" }, - new OpenApiTag { Name = "Orders", Description = "Submit orders" } - }; - } - } - - ``` - - - _NOTE: If you're using the `SwaggerUI` middleware, the `TagDescriptionsDocumentFilter` demonstrated above could be used to display additional descriptions beside each group of Operations._ - - - ### Add Security Definitions and Requirements ### - - - In Swagger, you can describe how your API is secured by defining one or more security schemes (e.g basic, api key, oauth2 etc.) and declaring which of those schemes are applicable globally OR for specific operations. For more details, take a look at the [Security Requirement Object in the Swagger spec.](https://swagger.io/specification/#securityRequirementObject). - - - In Swashbuckle, you can define schemes by invoking the `AddSecurityDefinition` method, providing a name and an instance of `OpenApiSecurityScheme`. For example you can define an [OAuth 2.0 - implicit flow](https://oauth.net/2/) as follows: - - - ```csharp - - // Startup.cs - - services.AddSwaggerGen(c => - - { - ... - - // Define the OAuth2.0 scheme that's in use (i.e. Implicit Flow) - c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme - { - Type = SecuritySchemeType.OAuth2, - Flows = new OpenApiOAuthFlows - { - Implicit = new OpenApiOAuthFlow - { - AuthorizationUrl = new Uri("/auth-server/connect/authorize", UriKind.Relative), - Scopes = new Dictionary - { - { "readAccess", "Access read operations" }, - { "writeAccess", "Access write operations" } - } - } - } - }); - }; - - ``` - - - _NOTE: In addition to defining a scheme, you also need to indicate which operations that scheme is applicable to. You can apply schemes globally (i.e. to ALL operations) through the `AddSecurityRequirement` method. The example below indicates that the scheme called "oauth2" should be applied to all operations, and that the "readAccess" and "writeAccess" scopes are required. When applying schemes of type other than "oauth2", the array of scopes MUST be empty._ - - - ```csharp - - c.AddSwaggerGen(c => - - { - ... - - c.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" } - }, - new[] { "readAccess", "writeAccess" } - } - }); - }) - - ``` - - - If you have schemes that are only applicable for certain operations, you can apply them through an Operation filter. For example, the following filter adds OAuth2 requirements based on the presence of the `AuthorizeAttribute`: - - - ```csharp - - // SecurityRequirementsOperationFilter.cs - - public class SecurityRequirementsOperationFilter : IOperationFilter - - { - public void Apply(OpenApiOperation operation, OperationFilterContext context) - { - // Policy names map to scopes - var requiredScopes = context.MethodInfo - .GetCustomAttributes(true) - .OfType() - .Select(attr => attr.Policy) - .Distinct(); - - if (requiredScopes.Any()) - { - operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" }); - operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" }); - - var oAuthScheme = new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" } - }; - - operation.Security = new List - { - new OpenApiSecurityRequirement - { - [ oAuthScheme ] = requiredScopes.ToList() - } - }; - } - } - } - - ``` - - - _NOTE: If you're using the `SwaggerUI` middleware, you can enable interactive OAuth2.0 flows that are powered by the emitted security metadata. See [Enabling OAuth2.0 Flows](#enable-oauth20-flows) for more details._ - - - ### Add Security Definitions and Requirements for Bearer auth ### - - - ```csharp - - services.AddSwaggerGen(c => - - { - c.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme - { - Type = SecuritySchemeType.Http, - Scheme = "bearer", - BearerFormat = "JWT", - Description = "JWT Authorization header using the Bearer scheme." - }); - c.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearerAuth" } - }, - new string[] {} - } - }); - }); - - ``` - - - ### Inheritance and Polymorphism ### - - - Swagger / OpenAPI defines the `allOf` and `oneOf` keywords for describing [inheritance and polymorphism](https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/) relationships in schema definitions. For example, if you're using a base class for models that share common properties you can use the `allOf` keyword to describe the inheritance hierarchy. Or, if your serializer supports polymorphic serialization/deserialization, you can use the `oneOf` keyword to document all the "possible" schemas for requests/responses that vary by subtype. - - - #### Enabling Inheritance #### - - - By default, Swashbuckle flattens inheritance hierarchies. That is, for derived models, the inherited properties are combined and listed alongside the declared properties. This can cause a lot of duplication in the generated Swagger, particularly when there's multiple subtypes. It's also problematic if you're using a client generator (e.g. NSwag) and would like to maintain the inheritance hierarchy in the generated client models. To work around this, you can apply the `UseAllOfForInheritance` setting, and this will leverage the `allOf` keyword to incorporate inherited properties by reference in the generated Swagger: - - - ``` - - Circle: { - type: "object", - allOf: [ - { - $ref: "#/components/schemas/Shape" - } - ], - properties: { - radius: { - type: "integer", - format: "int32", - } - }, - }, - - Shape: { - type: "object", - properties: { - name: { - type: "string", - nullable: true, - } - }, - } - - ``` - - - #### Enabling Polymorphism #### - - - If your serializer supports polymorphic serialization/deserialization and you would like to list the possible subtypes for an action that accepts/returns abstract base types, you can apply the `UseOneOfForPolymorphism` setting. As a result, the generated request/response schemas will reference a collection of "possible" schemas instead of just the base class schema: - - - ``` - - requestBody: { - content: { - application/json: { - schema: { - oneOf: [ - { - $ref: "#/components/schemas/Rectangle" - }, - { - $ref: "#/components/schemas/Circle" - }, - ], - } - } - } - - ``` - - - #### Detecting Subtypes #### - - - As inheritance and polymorphism relationships can often become quite complex, not just in your own models but also within the .NET class library, Swashbuckle is selective about which hierarchies it does and doesn't expose in the generated Swagger. By default, it will pick up any subtypes that are defined in the same assembly as a given base type. If you'd like to override this behavior, you can provide a custom selector function: - - - ```csharp - - services.AddSwaggerGen(c => - - { - ... - - c.UseAllOfForInheritance(); - - c.SelectSubTypesUsing(baseType => - { - return typeof(Startup).Assembly.GetTypes().Where(type => type.IsSubclassOf(baseType)); - }) - }); - - ``` - - - _NOTE: If you're using the [Swashbuckle Annotations library](#swashbuckleaspnetcoreannotations), it contains a custom selector that's based on the presence of `SwaggerSubType` attributes on base class definitions. This way, you can use simple attributes to explicitly list the inheritance and/or polymorphism relationships you want to expose. To enable this behavior, check out the [Annotations docs](#list-known-subtypes-for-inheritance-and-polymorphism)._ - - - #### Describing Discriminators #### - - - In conjunction with the `oneOf` and/or `allOf` keywords, Swagger / OpenAPI supports a `discriminator` field on base schema definitions. This keyword points to the property that identifies the specific type being represented by a given payload. In addition to the property name, the discriminator description MAY also include a `mapping` which maps discriminator values to specific schema definitions. - - - For example, the Newtonsoft serializer supports polymorphic serialization/deserialization by emitting/accepting a "$type" property on JSON instances. The value of this property will be the [assembly qualified type name](https://docs.microsoft.com/en-us/dotnet/api/system.type.assemblyqualifiedname?view=netcore-3.1) of the type represented by a given JSON instance. So, to explicitly describe this behavior in Swagger, the corresponding request/response schema could be defined as follows: - - - ``` - - components: { - schemas: { - Shape: { - required: [ - "$type" - ], - type: "object", - properties: { - $type: { - type": "string" - }, - discriminator: { - propertyName: "$type", - mapping: { - Rectangle: "#/components/schemas/Rectangle", - Circle: "#/components/schemas/Circle" - } - } - }, - Rectangle: { - type: "object", - allOf: [ - { - "$ref": "#/components/schemas/Shape" - } - ], - ... - }, - Circle: { - type: "object", - allOf: [ - { - "$ref": "#/components/schemas/Shape" - } - ], - ... - } - } - } - - ``` - - - If `UseAllOfForInheritance` or `UseOneOfForPolymorphism` is enabled, and your serializer supports (and has enabled) emitting/accepting a discriminator property, then Swashbuckle will automatically generate the corresponding `discriminator` metadata on base schema definitions. - - - Alternatively, if you've customized your serializer to support polymorphic serialization/deserialization, you can provide some custom selector functions to determine the discriminator name and corresponding mapping: - - - ```csharp - - services.AddSwaggerGen(c => - - { - ... - - c.UseOneOfForInheritance(); - - c.SelectDiscriminatorNameUsing((baseType) => "TypeName"); - c.SelectDiscriminatorValueUsing((subType) => subType.Name); - }); - - ``` - - - _NOTE: If you're using the [Swashbuckle Annotations library](#swashbuckleaspnetcoreannotations), it contains custom selector functions that are based on the presence of `SwaggerDiscriminator` and `SwaggerSubType` attributes on base class definitions. This way, you can use simple attributes to explicitly provide discriminator metadata. To enable this behavior, check out the [Annotations docs](#enrich-polymorphic-base-classes-with-discriminator-metadata)._ - - - ## Swashbuckle.AspNetCore.SwaggerUI ## - - - ### Change Relative Path to the UI ### - - - By default, the Swagger UI will be exposed at "/swagger". If necessary, you can alter this when enabling the SwaggerUI middleware: - - - ```csharp - - app.UseSwaggerUI(c => - - { - c.RoutePrefix = "api-docs" - ... - } - - ``` - - - ### Change Document Title ### - - - By default, the Swagger UI will have a generic document title. When you have multiple Swagger pages open, it can be difficult to tell them apart. You can alter this when enabling the SwaggerUI middleware: - - - ```csharp - - app.UseSwaggerUI(c => - - { - c.DocumentTitle = "My Swagger UI"; - ... - } - - ``` - - - ### List Multiple Swagger Documents ### - - - When enabling the middleware, you're required to specify one or more Swagger endpoints (fully qualified or relative to the UI page) to power the UI. If you provide multiple endpoints, they'll be listed in the top right corner of the page, allowing users to toggle between the different documents. For example, the following configuration could be used to document different versions of an API. - - - ```csharp - - app.UseSwaggerUI(c => - - { - c.SwaggerEndpoint("/swagger/v1/swagger.json", "V1 Docs"); - c.SwaggerEndpoint("/swagger/v2/swagger.json", "V2 Docs"); - } - - ``` - - - ### Apply swagger-ui Parameters ### - - - The swagger-ui ships with its own set of configuration parameters, all described here https://github.com/swagger-api/swagger-ui/blob/v3.8.1/docs/usage/configuration.md#display. In Swashbuckle, most of these are surfaced through the SwaggerUI middleware options: - - - ```csharp - - app.UseSwaggerUI(c => - - { - c.DefaultModelExpandDepth(2); - c.DefaultModelRendering(ModelRendering.Model); - c.DefaultModelsExpandDepth(-1); - c.DisplayOperationId(); - c.DisplayRequestDuration(); - c.DocExpansion(DocExpansion.None); - c.EnableDeepLinking(); - c.EnableFilter(); - c.MaxDisplayedTags(5); - c.ShowExtensions(); - c.ShowCommonExtensions(); - c.EnableValidator(); - c.SupportedSubmitMethods(SubmitMethod.Get, SubmitMethod.Head); - c.UseRequestInterceptor("(request) => { return request; }"); - c.UseResponseInterceptor("(response) => { return response; }"); - }); - - ``` - - - _NOTE: The `InjectOnCompleteJavaScript` and `InjectOnFailureJavaScript` options have been removed because the latest version of swagger-ui doesn't expose the necessary hooks. Instead, it provides a [flexible customization system](https://github.com/swagger-api/swagger-ui/blob/master/docs/customization/overview.md) based on concepts and patterns from React and Redux. To leverage this, you'll need to provide a custom version of index.html as described [below](#customize-indexhtml)._ - - - The [custom index sample app](test/WebSites/CustomUIIndex/Swagger/index.html) demonstrates this approach, using the swagger-ui plugin system provide a custom topbar, and to hide the info component. - - - ### Inject Custom CSS ### - - - To tweak the look and feel, you can inject additional CSS stylesheets by adding them to your `wwwroot` folder and specifying the relative paths in the middleware options: - - - ```csharp - - app.UseSwaggerUI(c => - - { - ... - c.InjectStylesheet("/swagger-ui/custom.css"); - } - - ``` - - - ### Customize index.html ### - - - To customize the UI beyond the basic options listed above, you can provide your own version of the swagger-ui index.html page: - - - ```csharp - - app.UseSwaggerUI(c => - - { - c.IndexStream = () => GetType().Assembly - .GetManifestResourceStream("CustomUIIndex.Swagger.index.html"); // requires file to be added as an embedded resource - }); - - ``` - - - _To get started, you should base your custom index.html on the [default version](src/Swashbuckle.AspNetCore.SwaggerUI/index.html)_ - - - ### Enable OAuth2.0 Flows ### - - - The swagger-ui has built-in support to participate in OAuth2.0 authorization flows. It interacts with authorization and/or token endpoints, as specified in the Swagger JSON, to obtain access tokens for subsequent API calls. See [Adding Security Definitions and Requirements](#add-security-definitions-and-requirements) for an example of adding OAuth2.0 metadata to the generated Swagger. - - - If your Swagger endpoint includes the appropriate security metadata, the UI interaction should be automatically enabled. However, you can further customize OAuth support in the UI with the following settings below. See https://github.com/swagger-api/swagger-ui/blob/v3.10.0/docs/usage/oauth2.md for more info: - - - ```csharp - - app.UseSwaggerUI(c => - - { - ... - - c.OAuthClientId("test-id"); - c.OAuthClientSecret("test-secret"); - c.OAuthRealm("test-realm"); - c.OAuthAppName("test-app"); - c.OAuthScopeSeparator(" "); - c.OAuthAdditionalQueryStringParams(new Dictionary { { "foo", "bar" }}); - c.OAuthUseBasicAuthenticationWithAccessCodeGrant(); - }); - - ``` - - - ### Use client-side request and response interceptors ### - - - To use custom interceptors on requests and responses going through swagger-ui you can define them as javascript functions in the configuration: - - - ```csharp - - app.UseSwaggerUI(c => - - { - ... - - c.UseRequestInterceptor("(req) => { req.headers['x-my-custom-header'] = 'MyCustomValue'; return req; }"); - c.UseResponseInterceptor("(res) => { console.log('Custom interceptor intercepted response from:', res.url); return res; }"); - }); - - ``` - - - This can be useful in a range of scenarios where you might want to append local xsrf tokens to all requests for example: - - - ```csharp - - app.UseSwaggerUI(c => - - { - ... - - c.UseRequestInterceptor("(req) => { req.headers['X-XSRF-Token'] = localStorage.getItem('xsrf-token'); return req; }"); - }); - - ``` - - - ## Swashbuckle.AspNetCore.Annotations ## - - - ### Install and Enable Annotations ### - - - 1. Install the following Nuget package into your ASP.NET Core application. - - ``` - Package Manager : Install-Package Swashbuckle.AspNetCore.Annotations - CLI : dotnet add package Swashbuckle.AspNetCore.Annotations - ``` - - 2. In the `ConfigureServices` method of `Startup.cs`, enable annotations within in the Swagger config block: - - ```csharp - services.AddSwaggerGen(c => - { - ... - - c.EnableAnnotations(); - }); - ``` - - ### Enrich Operation Metadata ### - - - Once annotations have been enabled, you can enrich the generated Operation metadata by decorating actions with a `SwaggerOperationAttribute`. - - - ```csharp - - [HttpPost] - - - [SwaggerOperation( - Summary = "Creates a new product", - Description = "Requires admin privileges", - OperationId = "CreateProduct", - Tags = new[] { "Purchase", "Products" } - )] - - public IActionResult Create([FromBody]Product product) - - ``` - - - ### Enrich Response Metadata ### - - - ASP.NET Core provides the `ProducesResponseTypeAttribute` for listing the different responses that can be returned by an action. These attributes can be combined with XML comments, as described [above](#include-descriptions-from-xml-comments), to include human friendly descriptions with each response in the generated Swagger. If you'd prefer to do all of this with a single attribute, and avoid the use of XML comments, you can use `SwaggerResponseAttribute`s instead: - - - ```csharp - - [HttpPost] - - [SwaggerResponse(201, "The product was created", typeof(Product))] - - [SwaggerResponse(400, "The product data is invalid")] - - public IActionResult Create([FromBody]Product product) - - ``` - - - ### Enrich Parameter Metadata ### - - - You can annotate "path", "query" or "header" bound parameters or properties (i.e. decorated with `[FromRoute]`, `[FromQuery]` or `[FromHeader]`) with a `SwaggerParameterAttribute` to enrich the corresponding `Parameter` metadata that's generated by Swashbuckle: - - - ```csharp - - [HttpGet] - - public IActionResult GetProducts( - [FromQuery, SwaggerParameter("Search keywords", Required = true)]string keywords) - ``` - - - ### Enrich RequestBody Metadata ### - - - You can annotate "body" bound parameters or properties (i.e. decorated with `[FromBody]`) with a `SwaggerRequestBodyAttribute` to enrich the corresponding `RequestBody` metadata that's generated by Swashbuckle: - - - ```csharp - - [HttpPost] - - public IActionResult CreateProduct( - [FromBody, SwaggerRequestBody("The product payload", Required = true)]Product product) - ``` - - - ### Enrich Schema Metadata ### - - - You can annotate classes or properties with a `SwaggerSchemaAttribute` to enrich the corresponding `Schema` metadata that's generated by Swashbuckle: - - - ```csharp - - [SwaggerSchema(Required = new[] { "Description" })] - - public class Product - - { - [SwaggerSchema("The product identifier", ReadOnly = true)] - public int Id { get; set; } - - [SwaggerSchema("The product description")] - public string Description { get; set; } - - [SwaggerSchema("The date it was created", Format = "date")] - public DateTime DateCreated { get; set; } - } - - ``` - - - _NOTE: In Swagger / OpenAPI, serialized objects AND contained properties are represented as `Schema` instances, hence why this annotation can be applied to both classes and properties. Also worth noting, "required" properties are specified as an array of property names on the top-level schema as opposed to a flag on each individual property._ - - - ### Apply Schema Filters to Specific Types ### - - - The `SwaggerGen` package provides several extension points, including Schema Filters ([described here](#extend-generator-with-operation-schema--document-filter)) for customizing ALL generated Schemas. However, there may be cases where it's preferable to apply a filter to a specific Schema. For example, if you'd like to include an example for a specific type in your API. This can be done by decorating the type with a `SwaggerSchemaFilterAttribute`: - - - ```csharp - - // Product.cs - - [SwaggerSchemaFilter(typeof(ProductSchemaFilter))] - - public class Product - - { - ... - } - - - // ProductSchemaFilter.cs - - public class ProductSchemaFilter : ISchemaFilter - - { - public void Apply(OpenApiSchema schema, SchemaFilterContext context) - { - schema.Example = new OpenApiObject - { - [ "Id" ] = new OpenApiInteger(1), - [ "Description" ] = new OpenApiString("An awesome product") - }; - } - } - - ``` - - - ### Add Tag Metadata - - - By default, the Swagger generator will tag all operations with the controller name. This tag is then used to drive the operation groupings in the swagger-ui. If you'd like to provide a description for each of these groups, you can do so by adding metadata for each controller name tag via the `SwaggerTagAttribute`: - - - ```csharp - - [SwaggerTag("Create, read, update and delete Products")] - - public class ProductsController - - { - ... - } - - ``` - - - _NOTE: This will add the above description specifically to the tag named "Products". Therefore, you should avoid using this attribute if you're tagging Operations with something other than controller name - e.g. if you're customizing the tagging behavior with `TagActionsBy`._ - - - ### List Known Subtypes for Inheritance and Polymorphism ### - - - If you want to use Swashbuckle's [inheritance and/or polymorphism behavior](#inheritance-and-polymorphism), you can use annotations to _explicitly_ indicate the "known" subtypes for a given base type. This will override the default selector function, which selects _all_ subtypes in the same assembly as the base type, and therefore needs to be explicitly enabled when you enable Annotations: - - - ```csharp - - // Startup.cs - - services.AddSwaggerGen(c => - - { - c.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: true); - }); - - - // Shape.cs - - [SwaggerSubType(typeof(Rectangle))] - - [SwaggerSubType(typeof(Circle))] - - public abstract class Shape - - { - - } - - ``` - - - ### Enrich Polymorphic Base Classes with Discriminator Metadata ### - - - If you're using annotations to _explicitly_ indicate the "known" subtypes for a polymorphic base type, you can combine the `SwaggerDiscriminatorAttribute` with the `SwaggerSubTypeAttribute` to provide additional metadata about the "discriminator" property, which will then be incorporated into the generated schema definition: - - - - ```csharp - - // Startup.cs - - services.AddSwaggerGen(c => - - { - c.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: true); - }); - - - // Shape.cs - - [SwaggerDiscriminator("shapeType")] - - [SwaggerSubType(typeof(Rectangle), DiscriminatorValue = "rectangle")] - - [SwaggerSubType(typeof(Circle), DiscriminatorValue = "circle")] - - public abstract class Shape - - { - public ShapeType { get; set; } - } - - ``` - - - This indicates that the corresponding payload will have a "shapeType" property to discriminate between subtypes, and that property will have a value of "rectangle" if the payload represents a `Rectangle` type and a value of "circle" if it represents a `Circle` type. This detail will be described in the generated schema definition as follows: - - - ``` - - schema: { - oneOf: [ - { - $ref: "#/components/schemas/Rectangle" - }, - { - $ref: "#/components/schemas/Circle" - }, - ], - discriminator: { - propertyName: shapeType, - mapping: { - rectangle: "#/components/schemas/Rectangle", - circle: "#/components/schemas/Circle", - } - } - } - - ``` - - - ## Swashbuckle.AspNetCore.Cli ## - - - ### Retrieve Swagger Directly from a Startup Assembly ### - - - Once your application has been setup with Swashbuckle (see [Getting Started](#getting-started)), you can use the Swashbuckle CLI tool to retrieve Swagger / OpenAPI JSON directly from your application's startup assembly, and write it to file. This can be useful if you want to incorporate Swagger generation into a CI/CD process, or if you want to serve it from static file at run-time. - - - It's packaged as a [.NET Core Tool](https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools) that can be installed and used via the dotnet SDK. - - - > :warning: The tool needs to load your Startup DLL and its dependencies at runtime. Therefore, you should use a version of the `dotnet` SDK that is compatible with your application. For example, if your app targets `netcoreapp2.1`, then you should use version 2.1 of the SDK to run the CLI tool. If it targets `netcoreapp3.0`, then you should use version 3.0 of the SDK and so on. - - - #### Using the tool with the .NET Core 2.1 SDK - - - 1. Install as a [global tool](https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools#install-a-global-tool) - - ``` - dotnet tool install -g --version 6.5.0 Swashbuckle.AspNetCore.Cli - ``` - - 2. Verify that the tool was installed correctly - - ``` - swagger tofile --help - ``` - - 3. Generate a Swagger/ OpenAPI document from your application's startup assembly - - ``` - swagger tofile --output [output] [startupassembly] [swaggerdoc] - ``` - - Where ... - * [output] is the relative path where the Swagger JSON will be output to - * [startupassembly] is the relative path to your application's startup assembly - * [swaggerdoc] is the name of the swagger document you want to retrieve, as configured in your startup class - - #### Using the tool with the .NET Core 3.0 SDK or later - - - 1. In your project root, create a tool manifest file: - - ``` - dotnet new tool-manifest - ``` - - 2. Install as a [local tool](https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools#install-a-local-tool) - - ``` - dotnet tool install --version 6.5.0 Swashbuckle.AspNetCore.Cli - ``` - - 3. Verify that the tool was installed correctly - - ``` - dotnet swagger tofile --help - ``` - - 4. Generate a Swagger / OpenAPI document from your application's startup assembly - - ``` - dotnet swagger tofile --output [output] [startupassembly] [swaggerdoc] - ``` - - Where ... - * [output] is the relative path where the Swagger JSON will be output to - * [startupassembly] is the relative path to your application's startup assembly - * [swaggerdoc] is the name of the swagger document you want to retrieve, as configured in your startup class - - ### Use the CLI Tool with a Custom Host Configuration - - - Out-of-the-box, the tool will execute in the context of a "default" web host. However, in some cases you may want to bring your own host environment, for example if you've configured a custom DI container such as Autofac. For this scenario, the Swashbuckle CLI tool exposes a convention-based hook for your application. - - - That is, if your application contains a class that meets either of the following naming conventions, then that class will be used to provide a host for the CLI tool to run in. - - - - `public class SwaggerHostFactory`, containing a public static method called `CreateHost` with return type `IHost` - - - `public class SwaggerWebHostFactory`, containing a public static method called `CreateWebHost` with return type `IWebHost` - - - For example, the following class could be used to leverage the same host configuration as your application: - - - ```csharp - - public class SwaggerHostFactory - - { - public static IHost CreateHost() - { - return Program.CreateHostBuilder(new string[0]).Build(); - } - } - - ``` - - - ## Swashbuckle.AspNetCore.ReDoc ## - - -

Change Relative Path to the UI

- - - By default, the ReDoc UI will be exposed at "/api-docs". If necessary, you can alter this when enabling the ReDoc middleware: - - - ```csharp - - app.UseReDoc(c => - - { - c.RoutePrefix = "docs" - ... - } - - ``` - - -

Change Document Title

- - - By default, the ReDoc UI will have a generic document title. You can alter this when enabling the ReDoc middleware: - - - ```csharp - - app.UseReDoc(c => - - { - c.DocumentTitle = "My API Docs"; - ... - } - - ``` - - - ### Apply ReDoc Parameters ### - - - ReDoc ships with its own set of configuration parameters, all described here https://github.com/Rebilly/ReDoc/blob/master/README.md#redoc-options-object. In Swashbuckle, most of these are surfaced through the ReDoc middleware options: - - - ```csharp - - app.UseReDoc(c => - - { - c.SpecUrl("/v1/swagger.json"); - c.EnableUntrustedSpec(); - c.ScrollYOffset(10); - c.HideHostname(); - c.HideDownloadButton(); - c.ExpandResponses("200,201"); - c.RequiredPropsFirst(); - c.NoAutoAuth(); - c.PathInMiddlePanel(); - c.HideLoading(); - c.NativeScrollbars(); - c.DisableSearch(); - c.OnlyRequiredInSamples(); - c.SortPropsAlphabetically(); - }); - - ``` - - - _Using `c.SpecUrl("/v1/swagger.json")` multiple times within the same `UseReDoc(...)` will not add multiple urls._ - - -

Inject Custom CSS

- - - To tweak the look and feel, you can inject additional CSS stylesheets by adding them to your `wwwroot` folder and specifying the relative paths in the middleware options: - - - ```csharp - - app.UseReDoc(c => - - { - ... - c.InjectStylesheet("/redoc/custom.css"); - } - - ``` - - - It is also possible to modify the theme by using the `AdditionalItems` property, see https://github.com/Rebilly/ReDoc/blob/master/README.md#redoc-options-object for more information. - - - ```csharp - - app.UseReDoc(c => - - { - ... - c.ConfigObject.AdditionalItems = ... - } - - ``` - - -

Customize index.html

- - - To customize the UI beyond the basic options listed above, you can provide your own version of the ReDoc index.html page: - - - ```csharp - - app.UseReDoc(c => - - { - c.IndexStream = () => GetType().Assembly - .GetManifestResourceStream("CustomIndex.ReDoc.index.html"); // requires file to be added as an embedded resource - }); - - ``` - - - _To get started, you should base your custom index.html on the [default version](src/Swashbuckle.AspNetCore.ReDoc/index.html)_ -z0mt3c/hapi-swaggered: > - # hapi-swaggered 3.x - - Yet another hapi plugin providing swagger compliant API specifications (swagger specs 2.0) based on routes and joi schemas to be used with swagger-ui. - - - Supports hapi 17.x and up - - - For earlier versions check [hapi-swaggered 2.x](https://github.com/z0mt3c/hapi-swaggered/blob/2.x/README.md) (current default/latest `npm install hapi-swaggered --save`) - - - [![Build Status](https://img.shields.io/travis/z0mt3c/hapi-swaggered/master.svg)](https://travis-ci.org/z0mt3c/hapi-swaggered) - - [![Coverage Status](https://img.shields.io/coveralls/z0mt3c/hapi-swaggered/master.svg)](https://coveralls.io/r/z0mt3c/hapi-swaggered?branch=master) - - [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard) - - [![npm downloads](https://img.shields.io/npm/dm/hapi-swaggered.svg)](https://www.npmjs.com/package/hapi-swaggered) - - - ## Install - - ```bash - - npm install hapi-swaggered@next --save - - ``` - - - ## Similar swagger-projects for hapi - - [krakenjs/swaggerize-hapi](https://github.com/krakenjs/swaggerize-hapi) follows a design driven approach (swagger-schema first) for building APIs. In other words: it supports you to implement an api behind a specific swagger-schema while you have to create and maintain the swagger-schema yourself (or a third-party). In contrast with hapi-swaggered you will have to design your api through hapi route defintions and joi schemas (or did already) and hapi-swaggered will generate it's swagger specifications up on that (Of course not as beautiful and shiny structured as done by hand). Based on this you are able to get beautiful hands-on swagger-ui documentation (like [this](http://petstore.swagger.io/)) for your api up and running (e.g. through [hapi-swaggered-ui](https://github.com/z0mt3c/hapi-swaggered-ui)). - - - ## Swagger-UI - - This plugin does not include the [swagger-ui](https://github.com/wordnik/swagger-ui) interface. It just serves a bare swagger 2.0 compliant json feed. If you are looking for an easy swagger-ui plugin to drop-in? You should have a look at: - - * [hapi-swaggered-ui](https://github.com/z0mt3c/hapi-swaggered-ui) - - - ## Plugin Configuration - - * `requiredTags`: an array of strings, only routes with all of the specified tags will be exposed, defaults to: `['api']` - - * `produces`: an array of mime type strings, defaults to: `[ 'application/json' ]` - - * `consumes`: an array of mime type strings, defaults to: `[ 'application/json' ]` - - * `endpoint`: route path to the swagger specification, defaults to: `'/swagger'` - - * `routeTags`: an array of strings, all routes exposed by hapi-swaggered will be tagged as specified, defaults to `['swagger']` - - * `stripPrefix`: a path prefix which should be stripped from the swagger specifications. E.g. your root resource are located under `/api/v12345678/resource` you might want to strip `/api/v12345678`, defaults to null - - * `basePath`: string, optional url base path (e.g. used to fix reverse proxy routes) - - * `supportedMethods`: array of http methods, only routes with mentioned methods will be exposed, in case of a wildcard * a route will be generated for each method, defaults to `['get', 'put', 'post', 'delete', 'patch']` - - * `host`: string, overwrite requests host (e.g. domain.tld:1337) - - * `schemes`: array of allowed schemes e.g. `['http', 'https', 'ws', 'wss']` (optional) - - * `info`: exposed swagger api informations, defaults to null (optional) - * `title`: string (required) - * `description`: string (required) - * `termsOfService`: string - * `contact`: object (optional) - * `name`: string - * `url`: string - * `email`: string - * `license`: object (optional) - * `name`: string: string - * `url`: string: string - * `version`: version string of your api, which will be exposed (required) - * `tagging`: Options used for grouping routes - * `mode`: string, can be `path` (routes will be grouped by its path) or `tags` (routes will be grouped by its tags), default is `path` - * `pathLevel` integer, in case of mode `path` it defines on which level the path grouping will take place (default is 1) - * `stripRequiredTags` boolean, in case of mode `tags` it defines if the `requiredTags` will not be exposed (default is true) - * `tags`: object (or array with objects according to the [swagger specs](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#tagObject)) for defining tag / group descriptions. E.g. you two endpoints `/get/this` and `/get/that` and the tagging mode is set to path (with pathLevel: 1) they will be groupped unter /get and you are able to define a description through this object as `{ 'get': 'get this and that' }`, defaults to null - - * `cors`: boolean or object with cors configuration as according to the [hapijs documentation](https://github.com/hapijs/hapi/blob/master/API.md#route-options) (defaults to false) - - * `cache`: caching options for the swagger schema generation as specified in [`server.method()`](https://github.com/hapijs/hapi/blob/master/API.md#servermethodname-method-options) of hapi, defaults to: `{ expiresIn: 15 * 60 * 1000 }` - - * `responseValidation`: boolean, turn response validation on and off for hapi-swaggered routes, defaults to false - - * `auth`: authentication configuration [hapijs documentation](https://github.com/hapijs/hapi/blob/master/API.md#route-options) (default to undefined) - - * `securityDefinitions`: security definitions according to [swagger specs](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md] - - - ## Example - - Example configuration for hapi-swaggered + hapi-swaggered-ui - - - ```js - - const Hapi = require('hapi'); - - - (async () => { - const server = await new Hapi.Server({ - port: 8000 - }) - - await server.register([ - require('inert'), - require('vision'), - { - plugin: require('hapi-swaggered'), - options: { - tags: { - 'foobar/test': 'Example foobar description' - }, - info: { - title: 'Example API', - description: 'Powered by node, hapi, joi, hapi-swaggered, hapi-swaggered-ui and swagger-ui', - version: '1.0' - } - } - }, - { - plugin: require('hapi-swaggered-ui'), - options: { - title: 'Example API', - path: '/docs', - authorization: { - field: 'apiKey', - scope: 'query', // header works as well - // valuePrefix: 'bearer '// prefix incase - defaultValue: 'demoKey', - placeholder: 'Enter your apiKey here' - }, - swaggerOptions: { - validatorUrl: null - } - } - } - ]) - - server.route({ - path: '/', - method: 'GET', - handler (request, h) { - return h.response().redirect('/docs') - } - }) - - try { - await server.start() - console.log('Server running at:', server.info.uri) - } catch (err) { - console.log(err) - } - })() - - ``` - - - Demo Routes - - ```js - - server.route({ - path: '/foobar/test', - method: 'GET', - options: { - tags: ['api'], - description: 'My route description', - notes: 'My route notes', - handler () { - return {}; - } - } - }); - - - server.route({ - path: '/foobar/{foo}/{bar}', - method: 'GET', - options: { - tags: ['api'], - validate: { - params: { - foo: Joi.string().required().description('test'), - bar: Joi.string().required() - } - }, - handler () { - return {}; - } - } - }); - - ``` - - - ## Features - - ### Model naming - - To assign custom names to your Models use the Joi.meta() option (in previous joi versions Joi.options() may be used) - - - ```js - - Joi.object({}).meta({ className: 'FooBar' }); - - ``` - - - ### Model description - - To assign a description to your Models use the Joi.meta() option like above - - - ```js - - Joi.object({}).meta({ description: 'A description of FooBar' }); - - ``` - - - ### Type naming - - To override the type a Joi model should be interpreted as, use the Joi.meta() option like above. This is especially useful when utilizing the extend and coerce features of Joi schema definition - - - ```js - - Joi.object({}).meta({ swaggerType: string }); - - ``` - - - ### Document responses - - There are 2 and a half different ways of documenting responses of routes: - - - The hapi way: - - - ```js - - { - options: { - response: { - schema: Joi.object({ - bar: Joi.string().description('test').required() - }).description('test'), - status: { - 500: Joi.object({ - bar: Joi.string().description('test').required() - }) - } - } - } - } - - ``` - - - The plugin way without schemas: - - - ```js - - { - options: { - plugins: { - 'hapi-swaggered': { - responses: { - default: {description: 'Bad Request'}, - 500: {description: 'Internal Server Error'} - } - } - }, - response: { - schema: Joi.object({ - bar: Joi.string().required() - }).description('test') - } - } - } - - ``` - - - The plugin way with schemas: - - - ```js - - { - options: { - plugins: { - 'hapi-swaggered': { - responses: { - default: { - description: 'Bad Request', schema: Joi.object({ - bar: Joi.string().description('test').required() - }) - }, - 500: {description: 'Internal Server Error'} - } - } - } - } - } - - ``` - - - Specify an operationId for a route: - - - ```js - - { - options: { - plugins: { - 'hapi-swaggered': { - operationId: 'testRoute' - } - } - } - } - - ``` - - - Specify an security options to a route / operation: - - - ```js - - { - options: { - plugins: { - 'hapi-swaggered': { - security: {} - } - } - } - } - - ``` - - - ### Tag filtering - - Routes can be filtered for tags through the tags query parameter beside the requiredTags property which is always required to be present. - - - For example: - - - * `?tags=public,beta (equal to ?tags=+public,+beta)` - * will only show apis and routes with tag public AND/OR beta. - * `?tags=public,-beta (equal to ?tags=+public,-beta)` - * will only show apis and routes with tag public AND NOT beta. - - ## Known issues - - ### No response types - - The routes response schemas which hapi-swaggered is parsing will be dropped by hapi whenever the response validation is disabled. In this case hapi-swaggered will not be able to show any response types. A very low sampling rate is sufficient to keep the repsonse types. -jfinkhaeuser/prance: >+ - |Posix Build Status| |Windows Build Status| |Docs| - |License| - - |PyPI| |Python Versions| |Package Format| |Package Status| |FOSSA Status| |Liberapay| - - - |Logo| - - - Prance provides parsers for `Swagger/OpenAPI - - 2.0 and 3.0 `__ API specifications in Python. - - It uses `openapi\_spec\_validator `__, - - `swagger\_spec\_validator `__ or - - `flex `__ - - to validate specifications, but additionally resolves `JSON - - references `__ - - in accordance with the OpenAPI spec. - - - Mostly the latter involves handling non-URI references; OpenAPI is fine - - with providing relative file paths, whereas JSON references require URIs - - at this point in time. - - - Prance is `up for adoption `__. - - - Usage - - ===== - - - Installation - - ------------ - - - Prance is available from PyPI, and can be installed via pip: - - - .. code:: bash - - $ pip install prance - - Note that this will install the code, but additional subpackages must be specified - - to unlock various pieces of functionality. At minimum, a parsing backend must be - - installed. For the CLI functionality, you need further dependencies. - - - The recommended installation installs the CLI, uses ICU and installs one validation - - backend: - - - .. code:: bash - - $ pip install prance[osv,icu,cli] - - Make sure you have `ICU Unicode Library `__ installed, - - as well as Python dev library before running the commands above. If not, use the - - following commands: - - - **Ubuntu** - - - .. code:: bash - - $ sudo apt-get install libicu-dev - $ sudo apt-get install python3-dev - - - Command Line Interface - - ---------------------- - - - After installing prance, a CLI is available for validating (and resolving - - external references in) specs: - - - .. code:: bash - - # Validates with resolving - $ prance validate path/to/swagger.yml - - # Validates without resolving - $ prance validate --no-resolve path/to/swagger.yml - - # Fetch URL, validate and resolve. - $ prance validate http://petstore.swagger.io/v2/swagger.json - Processing "http://petstore.swagger.io/v2/swagger.json"... - -> Resolving external references. - Validates OK as Swagger/OpenAPI 2.0! - - Validation is not the only feature of prance. One of the side effects of - - resolving is that from a spec with references, one can create a fully resolved - - output spec. In the past, this was done via options to the ``validate`` command, - - but now there's a specific command just for this purpose: - - - .. code:: bash - - # Compile spec - $ prance compile path/to/input.yml path/to/output.yml - - - Lastly, with the arrival of OpenAPI 3.0.0, it becomes useful for tooling to - - convert older specs to the new standard. Instead of re-inventing the wheel, - - prance just provides a CLI command for passing specs to the web API of - - `swagger2openapi `__ - a working - - internet connection is therefore required for this command: - - - .. code:: bash - - # Convert spec - $ prance convert path/to/swagger.yml path/to/openapi.yml - - - Code - - ---- - - - Most likely you have spec file and want to parse it: - - - .. code:: python - - from prance import ResolvingParser - parser = ResolvingParser('path/to/my/swagger.yaml') - parser.specification # contains fully resolved specs as a dict - - Prance also includes a non-resolving parser that does not follow JSON - - references, in case you prefer that. - - - .. code:: python - - from prance import BaseParser - parser = BaseParser('path/to/my/swagger.yaml') - parser.specification # contains specs as a dict still containing JSON references - - On Windows, the code reacts correctly if you pass posix-like paths - - (``/c:/swagger``) or if the path is relative. If you pass absolute - - windows path (like ``c:\swagger.yaml``), you can use - - ``prance.util.fs.abspath`` to convert them. - - - URLs can also be parsed: - - - .. code:: python - - parser = ResolvingParser('http://petstore.swagger.io/v2/swagger.json') - - Largely, that's it. There is a whole slew of utility code that you may - - or may not find useful, too. Look at the `full documentation - - `__ for details. - - - - Compatibility - - ------------- - - - *Python Versions* - - - Version 0.16.2 is the last version supporting Python 2. It was released on - - Nov 12th, 2019. Python 2 reaches end of life at the end of 2019. If you wish - - for updates to the Python 2 supported packages, please contact the maintainer - - directly. - - - Until fairly recently, we also tested with `PyPy `__. - - Unfortunately, Travis isn't very good at supporting this. So in the absence - - of spare time, they're disabled. `Issue 50 `__ - - tracks progress on that. - - - Similarly, but less critically, Python 3.4 is no longer receiving a lot of - - love from CI vendors, so automated builds on that version are no longer - - supported. - - - *Backends* - - - Different validation backends support different features. - - - +------------------------+----------------+-----------------+-------------+-------------------------------------------------------+----------------+-----------------------------------------------------------------------------------+ - - | Backend | Python Version | OpenAPI Version | Strict Mode | Notes | Available From | Link | - - +========================+================+=================+=============+=======================================================+================+===================================================================================+ - - | swagger-spec-validator | 2 and 3 | 2.0 only | yes | Slow; does not accept integer keys (see strict mode). | prance 0.1 | `swagger\_spec\_validator `__ | - - +------------------------+----------------+-----------------+-------------+-------------------------------------------------------+----------------+-----------------------------------------------------------------------------------+ - - | flex | 2 and 3 | 2.0 only | n/a | Fastest; unfortunately deprecated. | prance 0.8 | `flex `__ | - - +------------------------+----------------+-----------------+-------------+-------------------------------------------------------+----------------+-----------------------------------------------------------------------------------+ - - | openapi-spec-validator | 2 and 3 | 2.0 and 3.0 | yes | Slow; does not accept integer keys (see strict mode). | prance 0.11 | `openapi\_spec\_validator `__ | - - +------------------------+----------------+-----------------+-------------+-------------------------------------------------------+----------------+-----------------------------------------------------------------------------------+ - - - You can select the backend in the constructor of the parser(s): - - - .. code:: python - - parser = ResolvingParser('http://petstore.swagger.io/v2/swagger.json', backend = 'openapi-spec-validator') - - - No backend is included in the dependencies; they are detected at run-time. If you install them, - - they can be used: - - - .. code:: bash - - $ pip install openapi-spec-validator - $ pip install prance - $ prance validate --backend=openapi-spec-validator path/to/spec.yml - - *A note on flex usage:* While flex is the fastest validation backend, unfortunately it is no longer - - maintained and there are issues with its dependencies. For one thing, it depends on a version of `PyYAML` - - that contains security flaws. For another, it depends explicitly on older versions of `click`. - - - If you use the flex subpackage, therefore, you do so at your own risk. - - - *Compatibility* - - - See `COMPATIBILITY.rst `__ - - for a list of known issues. - - - - Partial Reference Resolution - - ---------------------------- - - - It's possible to instruct the parser to only resolve some kinds of references. - - This allows e.g. resolving references from external URLs, whilst keeping local - - references (i.e. to local files, or file internal) intact. - - - .. code:: python - - from prance import ResolvingParser - from prance.util.resolver import RESOLVE_HTTP - - parser = ResolvingParser('/path/to/spec', resolve_types = RESOLVE_HTTP) - - - Multiple types can be specified by OR-ing constants together: - - - .. code:: python - - from prance import ResolvingParser - from prance.util.resolver import RESOLVE_HTTP, RESOLVE_FILES - - parser = ResolvingParser('/path/to/spec', resolve_types = RESOLVE_HTTP | RESOLVE_FILES) - - - Extensions - - ---------- - - - Prance includes the ability to reference outside swagger definitions - - in outside Python packages. Such a package must already be importable - - (i.e. installed), and be accessible via the - - `ResourceManager API `__ - - (some more info `here `__). - - - For example, you might create a package ``common_swag`` with the file - - ``base.yaml`` containing the definition - - - .. code:: yaml - - definitions: - Severity: - type: string - enum: - - INFO - - WARN - - ERROR - - FATAL - - In the ``setup.py`` for ``common_swag`` you would add lines such as - - - .. code:: python - - packages=find_packages('src'), - package_dir={'': 'src'}, - package_data={ - '': '*.yaml' - } - - Then, having installed ``common_swag`` into some application, you could - - now write - - - .. code:: yaml - - definitions: - Message: - type: object - properties: - severity: - $ref: 'python://common_swag/base.yaml#/definitions/Severity' - code: - type: string - summary: - type: string - description: - type: string - required: - - severity - - summary - - Contributing - - ============ - - - See `CONTRIBUTING.md `__ for details. - - - Professional support is available through `finkhaeuser consulting `__. - - - License - - ======= - - - Licensed under MITNFA (MIT +no-false-attribs) License. See the - - `LICENSE.txt `__ file for details. - - - "Prancing unicorn" logo image Copyright (c) Jens Finkhaeuser. - - Made by `Moreven B `__. Use of the logo is permitted under - - the `Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International license `__. - - - .. |Posix Build Status| image:: https://travis-ci.org/jfinkhaeuser/prance.svg?branch=master - :target: https://travis-ci.org/jfinkhaeuser/prance - .. |Windows Build Status| image:: https://ci.appveyor.com/api/projects/status/ic7lo8r95mkee7di/branch/master?svg=true - :target: https://ci.appveyor.com/project/jfinkhaeuser/prance - .. |Docs| image:: https://img.shields.io/badge/docs-passing-brightgreen.svg - :target: https://jfinkhaeuser.github.io/prance/ - .. |License| image:: https://img.shields.io/pypi/l/prance.svg - :target: https://pypi.python.org/pypi/prance/ - .. |PyPI| image:: https://img.shields.io/pypi/v/prance.svg - :target: https://pypi.python.org/pypi/prance/ - .. |Package Format| image:: https://img.shields.io/pypi/format/prance.svg - :target: https://pypi.python.org/pypi/prance/ - .. |Python Versions| image:: https://img.shields.io/pypi/pyversions/prance.svg - :target: https://pypi.python.org/pypi/prance/ - .. |Package Status| image:: https://img.shields.io/pypi/status/prance.svg - :target: https://pypi.python.org/pypi/prance/ - .. |FOSSA Status| image:: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fjfinkhaeuser%2Fprance.svg?type=shield - :target: https://app.fossa.io/projects/git%2Bgithub.com%2Fjfinkhaeuser%2Fprance?ref=badge_shield - .. |Liberapay| image:: http://img.shields.io/liberapay/receives/jfinkhaeuser.svg?logo=liberapay - :target: https://liberapay.com/jfinkhaeuser/donate - .. |Logo| image:: https://raw.githubusercontent.com/jfinkhaeuser/prance/master/docs/images/prance_logo_256.png - -swimlane/qswag: > - # qswag - - - Fast & Light Swagger generator for .NET Core. For more information, checkout the [documentation](https://swimlane.gitbooks.io/qswag/content/) - - - ## Example - - - ```csharp - - using System; - - using System.Collections.Generic; - - using System.IO; - - using System.Linq; - - using System.Net.Http; - - using System.Reflection; - - using System.Text; - - using Microsoft.AspNetCore.Authorization; - - using Microsoft.AspNetCore.Mvc; - - using Newtonsoft.Json; - - using QSwagGenerator; - - using QSwagSchema; - - - namespace Controllers - - { - /// - /// Swagger spec controller. - /// - /// - public class SwaggerController : Controller - { - private readonly List _types; - - /// - /// Initializes a new instance of the class. - /// - public SwaggerController() - { - _types = new List - { - typeof(GroupsController), - typeof(SettingsController) - - }; - } - /// - /// Gets the swagger. - /// - /// Swagger specification Json - /// - [HttpGet("/swagger")] - public ActionResult GetSwagger(params string[] type) - { - var types = type == null || type.Length <= 0 ? _types : type.Select(GetTypeFromString); - var httpRequest = HttpContext?.Request; - - var generatorSettings = new GeneratorSettings(httpRequest) - { - DefaultUrlTemplate = "/[controller]/{id?}", - IgnoreObsolete = true, - Info = new Info() { Title = "Swimlane API", Version = "3.0" }, - XmlDocPath = Path.ChangeExtension(Assembly.GetEntryAssembly().Location, "xml"), - SecurityDefinitions = new Dictionary() - { - { - "jwt_token", - new SecurityDefinition("Authorization", SecuritySchemeType.ApiKey) {In = Location.Header} - } - }, - JsonSchemaLicense = "YourJsonSchemaLicense" - }; - - generatorSettings.Security.Add(new SecurityRequirement("jwt_token")); - var generateForControllers = WebApiToSwagger.GenerateForControllers(types, generatorSettings, nameof(GetSwagger)); - - return new FileContentResult(Encoding.UTF8.GetBytes(generateForControllers), "application/json"); - } - - private Type GetTypeFromString(string type) - { - var typeFromString = Type.GetType(type); - if (typeFromString != null) - return typeFromString; - if (!type.Contains(".")) - return GetTypeFromString(string.Join(".", GetType().Namespace, type)); - if (!type.EndsWith("controller", StringComparison.CurrentCultureIgnoreCase)) - return GetTypeFromString(string.Concat(type, "Controller")); - return null; - } - } - } - - ``` - - - ## Building Locally - - Before running tests locally you must set an an environment variable called `Newtonsoft` that contains the your Newtonsoft JSONSchema key. Tests will not execute successfully without this key. - - - ## Build Job Details - - Before merging to master the semver version attrbutes (major, minor, or patch) must be updated to reflect the type of change made. The publish to NuGet upon merging to master will fail if the version is not updated. - - - ### Stages - - [Dotnet Restore] - Restore 3rd party NuGet packages for all projects - - [Dotnet Build] - Build all projects in release mode - - [Run Tests] - Run all tests - - [Publish] - Publishes QSwagGenerator and QSwagSchema to NuGet if a master branch build - - - ## Credits - - `qswag` is a [Swimlane](http://swimlane.com) open-source project; we believe in giving back to the open-source community by sharing some of the projects we build for our application. Swimlane is an automated cyber security operations and incident response platform that enables cyber security teams to leverage threat intelligence, speed up incident response and automate security operations. -frankiesardo/pedestal-swagger: > - # route-swagger - - - [![Build status](https://circleci.com/gh/frankiesardo/route-swagger.svg?style=shield)](https://circleci.com/gh/frankiesardo/route-swagger) - - - Generate Swagger documentation from pedestal (or tripod) routes - - - - [Demo](https://pedestal-swagger.herokuapp.com) - - - ## For old pedestal-swagger users - - - This project now focuses solely on route transformation and schema validation and thus is pedestal-agnostic. - - - Route-swagger is a much lower level library. Everything the old pedestal-swagger did is still possible (look at the example repo) but requires a bit more boilerplate. The major breaking difference is that now route-swagger uses ring specific keys for describing the schema rather than swagger ones, e.g. - - - ```clj - - {:parameters {:body-params .. - :form-params .. - :query-params .. - :path-params .. - :headers ..} - :responses {500 {:body .. :headers ..}}} - ``` - - - Instead of `body`, `formData`, `query`, `schema`, etc. That should make it much more user friendly for clojure users. - - - For a nicer integration with pedestal, extra features and easier migration path from the old pedestal-swagger check out [pedestal-api](https://github.com/oliyh/pedestal-api). - - - ## Download - - - [![Clojars Project](http://clojars.org/frankiesardo/route-swagger/latest-version.svg)](http://clojars.org/frankiesardo/route-swagger) - - - ## Usage - - - Have a look at the project under the example folder for a working pedestal app - - - ## License - - - Copyright © 2015 Frankie Sardo - - - Distributed under the Eclipse Public License either version 1.0 or (at - - your option) any later version. -gengo/grpc-gateway: > - # grpc-gateway - - - [![release](https://img.shields.io/github/release/grpc-ecosystem/grpc-gateway.svg?style=flat-square)](https://github.com/grpc-ecosystem/grpc-gateway/releases) [![CircleCI](https://img.shields.io/circleci/project/github/grpc-ecosystem/grpc-gateway/master.svg?style=flat-square)](https://circleci.com/gh/grpc-ecosystem/grpc-gateway) [![fuzzit](https://app.fuzzit.dev/badge?org_id=grpc-gateway)](https://app.fuzzit.dev/orgs/grpc-gateway/dashboard) [![coverage](https://img.shields.io/codecov/c/github/grpc-ecosystem/grpc-gateway/master.svg?style=flat-square)](https://codecov.io/gh/grpc-ecosystem/grpc-gateway) [![license](https://img.shields.io/github/license/grpc-ecosystem/grpc-gateway.svg?style=flat-square)](LICENSE.txt) - - - The grpc-gateway is a plugin of the Google protocol buffers compiler - - [protoc](https://github.com/protocolbuffers/protobuf). - - It reads protobuf service definitions and generates a reverse-proxy server which - - 'translates a RESTful HTTP API into gRPC. This server is generated according to the - - [`google.api.http`](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto#L46) - - annotations in your service definitions. - - - This helps you provide your APIs in both gRPC and RESTful style at the same time. - - - ![architecture introduction diagram](https://docs.google.com/drawings/d/12hp4CPqrNPFhattL_cIoJptFvlAqm5wLQ0ggqI5mkCg/pub?w=749&h=370) - - - ## Check out our [documentation](https://grpc-ecosystem.github.io/grpc-gateway/)! - - - ## Background - - gRPC is great -- it generates API clients and server stubs in many programming - - languages, it is fast, easy-to-use, bandwidth-efficient and its design is - - combat-proven by Google. However, you might still want to provide a traditional - - RESTful JSON API as well. Reasons can range from maintaining - - backwards-compatibility, supporting languages or clients not well supported by - - gRPC, to simply maintaining the aesthetics and tooling involved with a RESTful - - JSON architecture. - - - This project aims to provide that HTTP+JSON interface to your gRPC service. - - A small amount of configuration in your service to attach HTTP semantics is all - - that's needed to generate a reverse-proxy with this library. - - - ## Installation - - - The grpc-gateway requires a local installation of the Google protocol buffers - - compiler `protoc` v3.0.0 or above. Please install this via your local package - - manager or by downloading one of the releases from the official repository: - - - https://github.com/protocolbuffers/protobuf/releases - - - The following instructions assume you are using - - [Go Modules](https://github.com/golang/go/wiki/Modules) for dependency - - management. Use a - - [tool dependency](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module) - - to track the versions of the following executable packages: - - - ```go - - // +build tools - - - package tools - - - import ( - _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway" - _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger" - _ "github.com/golang/protobuf/protoc-gen-go" - ) - - ``` - - - Run `go mod tidy` to resolve the versions. Install by running - - - ```sh - - $ go install \ - github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway \ - github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger \ - github.com/golang/protobuf/protoc-gen-go - ``` - - - This will place three binaries in your `$GOBIN`; - - - * `protoc-gen-grpc-gateway` - - * `protoc-gen-swagger` - - * `protoc-gen-go` - - - Make sure that your `$GOBIN` is in your `$PATH`. - - - ## Usage - - - 1. Define your [gRPC](https://grpc.io/docs/) service using protocol buffers - - `your_service.proto`: - ```protobuf - syntax = "proto3"; - package example; - message StringMessage { - string value = 1; - } - - service YourService { - rpc Echo(StringMessage) returns (StringMessage) {} - } - ``` - - 2. Add a [`google.api.http`](https://github.com/googleapis/googleapis/blob/master/google/api/http.proto#L46) - - annotation to your .proto file - - `your_service.proto`: - ```diff - syntax = "proto3"; - package example; - + - +import "google/api/annotations.proto"; - + - message StringMessage { - string value = 1; - } - - service YourService { - - rpc Echo(StringMessage) returns (StringMessage) {} - + rpc Echo(StringMessage) returns (StringMessage) { - + option (google.api.http) = { - + post: "/v1/example/echo" - + body: "*" - + }; - + } - } - ``` - - See [a_bit_of_everything.proto](examples/internal/proto/examplepb/a_bit_of_everything.proto) - for examples of more annotations you can add to customize gateway behavior - and generated Swagger output. - - If you do not want to modify the proto file for use with grpc-gateway you can - alternatively use an external - [gRPC Service Configuration](https://cloud.google.com/endpoints/docs/grpc/grpc-service-config) file. - [Check our documentation](https://grpc-ecosystem.github.io/grpc-gateway/docs/grpcapiconfiguration.html) - for more information. - - 3. Generate gRPC stub - - The following generates gRPC code for Golang based on `path/to/your_service.proto`: - ```sh - protoc -I/usr/local/include -I. \ - -I$GOPATH/src \ - -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ - --go_out=plugins=grpc:. \ - path/to/your_service.proto - ``` - - It will generate a stub file `path/to/your_service.pb.go`. - - 4. Implement your service in gRPC as usual - - 1. (Optional) Generate gRPC stub in the [other programming languages](https://grpc.io/docs/). - - For example, the following generates gRPC code for Ruby based on `path/to/your_service.proto`: - ```sh - protoc -I/usr/local/include -I. \ - -I$GOPATH/src \ - -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ - --ruby_out=. \ - path/to/your_service.proto - - protoc -I/usr/local/include -I. \ - -I$GOPATH/src \ - -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ - --plugin=protoc-gen-grpc=grpc_ruby_plugin \ - --grpc-ruby_out=. \ - path/to/your_service.proto - ``` - 2. Add the googleapis-common-protos gem (or your language equivalent) as a dependency to your project. - 3. Implement your gRPC service stubs - - 5. Generate reverse-proxy using `protoc-gen-grpc-gateway` - - ```sh - protoc -I/usr/local/include -I. \ - -I$GOPATH/src \ - -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ - --grpc-gateway_out=logtostderr=true:. \ - path/to/your_service.proto - ``` - - It will generate a reverse proxy `path/to/your_service.pb.gw.go`. - - 6. Write an entrypoint for the HTTP reverse-proxy server - - ```go - package main - - import ( - "context" // Use "golang.org/x/net/context" for Golang version <= 1.6 - "flag" - "net/http" - - "github.com/golang/glog" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "google.golang.org/grpc" - - gw "path/to/your_service_package" // Update - ) - - var ( - // command-line options: - // gRPC server endpoint - grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:9090", "gRPC server endpoint") - ) - - func run() error { - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - // Register gRPC server endpoint - // Note: Make sure the gRPC server is running properly and accessible - mux := runtime.NewServeMux() - opts := []grpc.DialOption{grpc.WithInsecure()} - err := gw.RegisterYourServiceHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts) - if err != nil { - return err - } - - // Start HTTP server (and proxy calls to gRPC server endpoint) - return http.ListenAndServe(":8081", mux) - } - - func main() { - flag.Parse() - defer glog.Flush() - - if err := run(); err != nil { - glog.Fatal(err) - } - } - ``` - - 7. (Optional) Generate swagger definitions using `protoc-gen-swagger` - - ```sh - protoc -I/usr/local/include -I. \ - -I$GOPATH/src \ - -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ - --swagger_out=logtostderr=true:. \ - path/to/your_service.proto - ``` - - ## Video intro - - - This GopherCon UK 2019 presentation from our maintainer - - [@JohanBrandhorst](https://github.com/johanbrandhorst) provides a good intro to - - using the grpc-gateway. It uses the following boilerplate repo as a base: - - https://github.com/johanbrandhorst/grpc-gateway-boilerplate. - - - [![gRPC-Gateway presentation](https://img.youtube.com/vi/Pq1paKC-fXk/0.jpg)](https://www.youtube.com/watch?v=Pq1paKC-fXk) - - - ## Parameters and flags - - - During code generation with `protoc`, flags to grpc-gateway tools must be passed - - through protoc using the `--_out=:` pattern, for - - example: - - - ```sh - - --grpc-gateway_out=logtostderr=true,repeated_path_param_separator=ssv:. - - --swagger_out=logtostderr=true,repeated_path_param_separator=ssv:. - - ``` - - - `protoc-gen-grpc-gateway` supports custom mapping from Protobuf `import` to - - Golang import paths. They are compatible to - - [the parameters with same names in `protoc-gen-go`](https://github.com/golang/protobuf#parameters) - - (except `source_relative`). - - - In addition we also support the `request_context` parameter in order to use the - - `http.Request`'s Context (only for Go 1.7 and above). This parameter can be - - useful to pass request scoped context between the gateway and the gRPC service. - - - `protoc-gen-grpc-gateway` also supports some more command line flags to control - - logging. You can give these flags together with parameters above. Run - - `protoc-gen-grpc-gateway --help` for more details about the flags. - - - Similarly, `protoc-gen-swagger` supports command-line flags to control Swagger - - output (for example, `json_names_for_fields` to output JSON names for fields - - instead of protobuf names). Run `protoc-gen-swagger --help` for more flag - - details. Further Swagger customization is possible by annotating your `.proto` - - files with options from - - [openapiv2.proto](protoc-gen-swagger/options/openapiv2.proto) - see - - [a_bit_of_everything.proto](examples/internal/proto/examplepb/a_bit_of_everything.proto) - - for examples. - - - ## More Examples - - More examples are available under `examples` directory. - - * `proto/examplepb/echo_service.proto`, `proto/examplepb/a_bit_of_everything.proto`, `proto/examplepb/unannotated_echo_service.proto`: service definition - * `proto/examplepb/echo_service.pb.go`, `proto/examplepb/a_bit_of_everything.pb.go`, `proto/examplepb/unannotated_echo_service.pb.go`: [generated] stub of the service - * `proto/examplepb/echo_service.pb.gw.go`, `proto/examplepb/a_bit_of_everything.pb.gw.go`, `proto/examplepb/uannotated_echo_service.pb.gw.go`: [generated] reverse proxy for the service - * `proto/examplepb/unannotated_echo_service.yaml`: gRPC API Configuration for ```unannotated_echo_service.proto``` - * `server/main.go`: service implementation - - * `main.go`: entrypoint of the generated reverse proxy - - - To use the same port for custom HTTP handlers (e.g. serving `swagger.json`), - - gRPC-gateway, and a gRPC server, see - - [this example by CoreOS](https://github.com/philips/grpc-gateway-example/blob/master/cmd/serve.go) - - (and its accompanying [blog post](https://coreos.com/blog/grpc-protobufs-swagger.html)). - - - ## Features - - - ### Supported - - - * Generating JSON API handlers. - - * Method parameters in request body. - - * Method parameters in request path. - - * Method parameters in query string. - - * Enum fields in path parameter (including repeated enum fields). - - * Mapping streaming APIs to newline-delimited JSON streams. - - * Mapping HTTP headers with `Grpc-Metadata-` prefix to gRPC metadata (prefixed with `grpcgateway-`) - - * Optionally emitting API definitions for - - [OpenAPI (Swagger) v2](https://swagger.io/docs/specification/2-0/basic-structure/). - - * Setting [gRPC timeouts](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests) - - through inbound HTTP `Grpc-Timeout` header. - - * Partial support for [gRPC API Configuration](https://cloud.google.com/endpoints/docs/grpc/grpc-service-config) - - files as an alternative to annotation. - - * Automatically translating PATCH requests into Field Mask gRPC requests. See - - [the docs](https://grpc-ecosystem.github.io/grpc-gateway/docs/patch.html) - - for more information. - - - ### No plan to support - - But patch is welcome. - - * Method parameters in HTTP headers. - - * Handling trailer metadata. - - * Encoding request/response body in XML. - - * True bi-directional streaming. - - - # Mapping gRPC to HTTP - - - * [How gRPC error codes map to HTTP status codes in the response](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/runtime/errors.go#L15). - - * HTTP request source IP is added as `X-Forwarded-For` gRPC request header. - - * HTTP request host is added as `X-Forwarded-Host` gRPC request header. - - * HTTP `Authorization` header is added as `authorization` gRPC request header. - - * Remaining Permanent HTTP header keys (as specified by the IANA - - [here](http://www.iana.org/assignments/message-headers/message-headers.xhtml) - - are prefixed with `grpcgateway-` and added with their values to gRPC request - - header. - - * HTTP headers that start with 'Grpc-Metadata-' are mapped to gRPC metadata - - (prefixed with `grpcgateway-`). - - * While configurable, the default {un,}marshaling uses - - [jsonpb](https://godoc.org/github.com/golang/protobuf/jsonpb) with - - `OrigName: true`. - - - # Contribution - - See [CONTRIBUTING.md](http://github.com/grpc-ecosystem/grpc-gateway/blob/master/CONTRIBUTING.md). - - - # License - - grpc-gateway is licensed under the BSD 3-Clause License. - - See [LICENSE.txt](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt) for more details. -BigstickCarpet/swagger-express-middleware: > - Swagger Express Middleware - - ============================ - - ### Swagger 2.0 middleware and mocks for Express.js - - - [![Cross-Platform Compatibility](https://apitools.dev/img/badges/os-badges.svg)](https://github.com/APIDevTools/swagger-express-middleware/blob/master/.github/workflows/CI-CD.yaml) - - [![Build Status](https://github.com/APIDevTools/swagger-express-middleware/workflows/CI-CD/badge.svg?branch=master)](https://github.com/APIDevTools/swagger-express-middleware/blob/master/.github/workflows/CI-CD.yaml) - - - [![Coverage Status](https://coveralls.io/repos/github/APIDevTools/swagger-express-middleware/badge.svg?branch=master)](https://coveralls.io/github/APIDevTools/swagger-express-middleware) - - [![Tested on APIs.guru](https://api.apis.guru/badges/tested_on.svg)](https://apis.guru/browse-apis/) - - [![Dependencies](https://david-dm.org/APIDevTools/swagger-express-middleware.svg)](https://david-dm.org/APIDevTools/swagger-express-middleware) - - - [![npm](https://img.shields.io/npm/v/@apidevtools/swagger-express-middleware.svg)](https://www.npmjs.com/package/@apidevtools/swagger-express-middleware) - - [![License](https://img.shields.io/npm/l/@apidevtools/swagger-express-middleware.svg)](LICENSE) - - [![Buy us a tree](https://img.shields.io/badge/Treeware-%F0%9F%8C%B3-lightgreen)](https://plant.treeware.earth/APIDevTools/swagger-express-middleware) - - - - - Features - - -------------------------- - - - **Supports Swagger 2.0 specs in JSON or YAML**
- - Swagger Express Middleware uses [Swagger-Parser](https://github.com/APIDevTools/swagger-parser) to parse, validate, and dereference Swagger files. You can even split your spec into multiple different files using `$ref` pointers. - - - - **Thoroughly tested**
- - Over 1,000 unit tests and integration tests with 100% code coverage. Tested on [**over 1,000 real-world APIs**](https://apis.guru/browse-apis/) from Google, Instagram, Spotify, etc. All tests are run on Mac, Linux, and Windows using all LTS versions of Node. - - - - [**Mock middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/mock.html)
- - **Fully-functional mock** implementations for every operation in your API, including data persistence, all with **zero code!** This is a great way to test-drive your API as you write it, or for quick demos and POCs. You can even extend the mock middleware with your own logic and data to fill in any gaps. - - - - [**Metadata middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/metadata.html)
- - Annotates each request with all the relevant information from the Swagger definition. The path, the operation, the parameters, the security requirements - they're all easily accessible at `req.swagger`. - - - - [**Parse Request middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/parseRequest.html)
- - Parses incoming requests and converts everything into the correct data types, according to your Swagger API definition. - - - - [**Validate Request middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/validateRequest.html)
- - Ensures that every request complies with your Swagger API definition, or returns the appropriate HTTP error codes if needed. Of course, you can catch any validation errors and handle them however you want. - - - - [**CORS middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/CORS.html)
- - Adds the appropriate CORS headers to each request and automatically responds to CORS preflight requests, all in compliance with your Swagger API definition. - - - - [**Files middleware**](https://apitools.dev/swagger-express-middleware/docs/middleware/files.html)
- - Serves the Swagger API file(s) in JSON or YAML format so they can be used with front-end tools like [Swagger UI](http://www.swagger.io), [Swagger Editor](http://editor.swagger.io), and [Postman](http://getpostman.com). - - - - - Installation and Use - - -------------------------- - - Install using [npm](https://docs.npmjs.com/about-npm/). - - - ```bash - - npm install @apidevtools/swagger-express-middleware - - ``` - - Then use it in your [Node.js](http://nodejs.org/) script like this: - - - ```javascript - - const express = require('express'); - - const createMiddleware = require('@apidevtools/swagger-express-middleware'); - - - let app = express(); - - - createMiddleware('PetStore.yaml', app, function(err, middleware) { - // Add all the Swagger Express Middleware, or just the ones you need. - // NOTE: Some of these accept optional options (omitted here for brevity) - app.use( - middleware.metadata(), - middleware.CORS(), - middleware.files(), - middleware.parseRequest(), - middleware.validateRequest(), - middleware.mock() - ); - - app.listen(8000, function() { - console.log('The PetStore sample is now running at http://localhost:8000'); - }); - }); - - ``` - - - - - Samples & Walkthroughs - - -------------------------- - - Swagger Express Middleware comes two samples that use the [Swagger Pet Store API](https://github.com/APIDevTools/swagger-express-middleware/blob/master/samples/PetStore.yaml). - - - #### Sample 1 - - This sample demonstrates the most simplistic usage of Swagger Express Middleware. It simply creates a new Express Application and adds all of the Swagger middleware without changing any options, and without adding any custom middleware. - - - * [Source Code](https://github.com/APIDevTools/swagger-express-middleware/blob/master/samples/sample1.js) - - * [Walkthrough](https://apitools.dev/swagger-express-middleware/docs/walkthroughs/running.html) - - - - #### Sample 2 - - This sample demonstrates a few more advanced features of Swagger Express Middleware, such as setting a few options, initializing the mock data store, and adding custom middleware logic. - - - * [Source Code](https://github.com/APIDevTools/swagger-express-middleware/blob/master/samples/sample2.js) - - * [Walkthrough](https://apitools.dev/swagger-express-middleware/docs/walkthroughs/walkthrough2.html) - - - - - Contributing - - -------------------------- - - I welcome any contributions, enhancements, and bug-fixes. [File an issue](https://github.com/APIDevTools/swagger-express-middleware/issues) on GitHub and [submit a pull request](https://github.com/APIDevTools/swagger-express-middleware/pulls). - - - #### Building/Testing - - To build/test the project locally on your computer: - - - 1. **Clone this repo**
- - `git clone https://github.com/APIDevTools/swagger-express-middleware.git` - - - 2. **Install dependencies**
- - `npm install` - - - 3. **Run the tests**
- - `npm test` - - - 4. **Run the sample app**
- - `npm start` - - - - - License - - -------------------------- - - Swagger Express Middleware is 100% free and open-source, under the [MIT license](LICENSE). Use it however you want. - - - This package is [Treeware](http://treeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https://plant.treeware.earth/APIDevTools/swagger-express-middleware) to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats. - - - - - Big Thanks To - - -------------------------- - - Thanks to these awesome companies for their support of Open Source developers ❤ - - - [![Travis CI](https://jstools.dev/img/badges/travis-ci.svg)](https://travis-ci.com) - - [![SauceLabs](https://jstools.dev/img/badges/sauce-labs.svg)](https://saucelabs.com) - - [![Coveralls](https://jstools.dev/img/badges/coveralls.svg)](https://coveralls.io) -RobWin/swagger2markup-gradle-plugin: > - = Swagger2Markup Gradle Plugin - - :author: Robert Winkler - - :hardbreaks: - - - image:https://travis-ci.org/Swagger2Markup/swagger2markup-gradle-plugin.svg?branch=master["Build Status", link="https://travis-ci.org/Swagger2Markup/swagger2markup-gradle-plugin"] image:https://coveralls.io/repos/Swagger2Markup/swagger2markup-gradle-plugin/badge.svg["Coverage Status", link="https://coveralls.io/r/Swagger2Markup/swagger2markup-gradle-plugin"] image:https://api.bintray.com/packages/swagger2markup/Maven/swagger2markup-gradle-plugin/images/download.svg[link="https://bintray.com/swagger2markup/Maven/swagger2markup-gradle-plugin/_latestVersion"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"] image:https://img.shields.io/badge/Twitter-rbrtwnklr-blue.svg["Twitter", link="https://twitter.com/rbrtwnklr"] image:https://badges.gitter.im/Join%20Chat.svg[link="https://gitter.im/Swagger2Markup/swagger2markup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"] - - - == Reference documentation - - - The documentation can be found at https://github.com/Swagger2Markup/swagger2markup#reference-documentation[Reference documentation] - - - == License - - - Copyright 2015 Robert Winkler - - - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -raphael/goa: > - # - - - ![Goa logo](https://goa.design/img/goa-logo.svg "Goa") - - - Goa is a framework for building micro-services and APIs in Go using a unique - - design-first approach. - - - --- - - [![Build Status](https://travis-ci.org/goadesign/goa.svg?branch=v3)](https://travis-ci.org/goadesign/goa) - - [![Windows Build status](https://ci.appveyor.com/api/projects/status/vixp37loj5i6qmaf/branch/v3?svg=true)](https://ci.appveyor.com/project/RaphaelSimon/goa-oqtis/branch/v3) - - [![Godoc](https://godoc.org/goa.design/goa?status.svg)](https://godoc.org/goa.design/goa) - - [![Slack](https://img.shields.io/badge/slack-gophers-orange.svg?style=flat)](https://gophers.slack.com/messages/goa/) - - - ## Overview - - - Goa takes a different approach to building services by making it possible to - - describe the *design* of the service API using a simple Go DSL. Goa uses the - - description to generate specialized service helper code, client code and - - documentation. Goa is extensible via plugins, for example the - - [goakit](https://github.com/goadesign/plugins/tree/v3/goakit) plugin - - generates code that leverage the Go kit library. - - - The service design describes the transport independent layer of the services in - - the form of simple methods that accept a context and a payload and return a - - result and an error. The design also describes how the payloads, results and - - errors are serialized in the transport (HTTP or gRPC). For example a service - - method payload may be built from an HTTP request by extracting values from the - - request path, headers and body. This clean separation of layers makes it - - possible to expose the same service using multiple transports. It also promotes - - good design where the service business logic concerns are expressed and - - implemented separately from the transport logic. - - - The Goa DSL consists of Go functions so that it may be extended easily to avoid - - repetition and promote standards. The design code itself can easily be shared - - across multiple services by simply importing the corresponding Go package again - - promoting reuse and standardization across services. - - - ## Code Generation - - - The Goa tool accepts the Go design package import path as input and produces the - - interface as well as the glue that binds the service and client code with the - - underlying transport. The code is specific to the API so that for example there - - is no need to cast or "bind" any data structure prior to using the request - - payload or response result. The design may define validations in which case the - - generated code takes care of validating the incoming request payload prior to - - invoking the service method on the server, and validating the response prior to - - invoking the client code. - - - ## Installation - - - Assuming you have a working [Go](https://golang.org) setup, and are in a - - directory where a `go.mod` file is present: - - - ```bash - - export GO111MODULE=on - - go get -u goa.design/goa/v3 - - go get -u goa.design/goa/v3/... - - ``` - - - If you don't have a `go.mod` file present, and only want to install the - - Goa command globally: - - - ```bash - - go get -u goa.design/goa/v3/cmd/goa - - ``` - - - Alternatively, when NOT using Go modules (this installs Goa v2, see below): - - - ```bash - - go get -u goa.design/goa/... - - ``` - - - ### Goa Versions and Go Module Support - - - Goa v2 and Goa v3 are functionally the exact same. The only addition provided by - - Goa v3 is Go module support. Goa v3 requires Go v1.11 or above, it also requires - - projects that use Goa to be within modules. - - - Projects that use Goa v3 use `goa.design/goa/v3` as root package import path - - while projects that use v2 use `goa.design/goa` (projects that use v1 use - - `github.com/goadesign/goa`). - - - Note that the Goa v3 tool is backwards compatible and can generate code for v2 - - designs. This means that you don't need to swap the tool to generate code for - - designs using v2 or v3 (designs using v1 use a different tool altogether). - - - ### Vendoring - - - Since Goa generates and compiles code vendoring tools are not able to - - automatically identify all the dependencies. In particular the `generator` - - package is only used by the generated code. To alleviate this issue simply add - - `goa.design/goa/codegen/generator` as a required package to the vendor manifest. - - For example if you are using `dep` add the following line to `Gopkg.toml`: - - - ``` toml - - required = ["goa.design/goa/codegen/generator"] - - ``` - - - This only applies to Goa v2 as vendoring is not used together with Go modules. - - - ### Stable Versions - - - Goa follows [Semantic Versioning](http://semver.org/) which is a fancy way of - - saying it publishes releases with version numbers of the form `vX.Y.Z` and makes - - sure that your code can upgrade to new versions with the same `X` component - - without having to make changes. - - - Releases are tagged with the corresponding version number. There is also a - - branch for each major version (`v1`, `v2` and `v3`). - - - Current Release: `v3.0.7` - - - ## Teaser - - - Note: the instructions below assume Goa v3. - - - ### 1. Design - - - Create a new Goa project: - - - ```bash - - mkdir -p calcsvc/design - - cd calcsvc - - go mod init calcsvc - - ``` - - - Create the file `design.go` in the `design` directory with the following - - content: - - - ```go - - package design - - - import . "goa.design/goa/v3/dsl" - - - // API describes the global properties of the API server. - - var _ = API("calc", func() { - Title("Calculator Service") - Description("HTTP service for adding numbers, a goa teaser") - Server("calc", func() { - Host("localhost", func() { URI("http://localhost:8088") }) - }) - }) - - - // Service describes a service - - var _ = Service("calc", func() { - Description("The calc service performs operations on numbers") - // Method describes a service method (endpoint) - Method("add", func() { - // Payload describes the method payload - // Here the payload is an object that consists of two fields - Payload(func() { - // Attribute describes an object field - Attribute("a", Int, "Left operand") - Attribute("b", Int, "Right operand") - // Both attributes must be provided when invoking "add" - Required("a", "b") - }) - // Result describes the method result - // Here the result is a simple integer value - Result(Int) - // HTTP describes the HTTP transport mapping - HTTP(func() { - // Requests to the service consist of HTTP GET requests - // The payload fields are encoded as path parameters - GET("/add/{a}/{b}") - // Responses use a "200 OK" HTTP status - // The result is encoded in the response body - Response(StatusOK) - }) - }) - }) - - ``` - - - This file contains the design for a `calc` service which accepts HTTP GET - - requests to `/add/{a}/{b}` where `{a}` and `{b}` are placeholders for integer - - values. The API returns the sum of `a` and `b` in the HTTP response body. - - - ### 2. Implement - - - Now that the design is done, let's run `goa` on the design package. - - In the `calcsvc` directory run: - - - ``` bash - - goa gen calcsvc/design - - ``` - - - This produces a `gen` directory with the following directory structure: - - - ``` text - - gen - - ├── calc - - │   ├── client.go - - │   ├── endpoints.go - - │   └── service.go - - └── http - ├── calc - │   ├── client - │   │   ├── cli.go - │   │   ├── client.go - │   │   ├── encode_decode.go - │   │   ├── paths.go - │   │   └── types.go - │   └── server - │   ├── encode_decode.go - │   ├── paths.go - │   ├── server.go - │   └── types.go - ├── cli - │   └── calc - │   └── cli.go - ├── openapi.json - └── openapi.yaml - - 7 directories, 15 files - - ``` - - - * `calc` contains the service endpoints and interface as well as a service - client. - * `http` contains the HTTP transport layer. This layer maps the service - endpoints to HTTP handlers server side and HTTP client methods client side. - The `http` directory also contains a complete - [OpenAPI 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) - spec for the service. - - The `goa` tool can also generate example implementations for both the service - - and client. These examples provide a good starting point: - - - ``` text - - goa example calcsvc/design - - - calc.go - - cmd/calc-cli/http.go - - cmd/calc-cli/main.go - - cmd/calc/http.go - - cmd/calc/main.go - - ``` - - - The tool generated the `main` functions for two commands: one that runs the - - server and one the client. The tool also generated a dummy service - - implementation that prints a log message. Again note that the `example` command - - is intended to generate just that: an *example*, in particular it is not - - intended to be re-run each time the design changes (as opposed to the `gen` - - command which should be re-run each time the design changes). - - - Let's implement our service by providing a proper implementation for the `add` - - method. Goa generated a payload struct for the `add` method that contains both - - fields. Goa also generated the transport layer that takes care of decoding the - - request so all we have to do is to perform the actual sum. Edit the file - - `calc.go` and change the code of the `add` function as follows: - - - ```go - - // Add returns the sum of attributes a and b of p. - - func (s *calcsrvc) Add(ctx context.Context, p *calc.AddPayload) (res int, err error) { - return p.A + p.B, nil - } - - ``` - - - That's it! we have now a full-fledged HTTP service with a corresponding OpenAPI - - specification and a client tool. - - - ### 3. Run - - - Now let's compile and run the service: - - - ```bash - - cd cmd/calc - - go build - - ./calc - - [calcapi] 16:10:47 HTTP "Add" mounted on GET /add/{a}/{b} - - [calcapi] 16:10:47 HTTP server listening on "localhost:8088" - - ``` - - - Open a new console and compile the generated CLI tool: - - - ```bash - - cd calcsvc/cmd/calc-cli - - go build - - ``` - - - and run it: - - - ```bash - - ./calc-cli calc add -a 1 -b 2 - - 3 - - ``` - - - The tool includes contextual help: - - - ``` bash - - ./calc-cli --help - - ``` - - - Help is also available on each command: - - - ``` bash - - ./calc-cli calc add --help - - ``` - - - Now let's see how robust our code is and try to use non integer values: - - - ``` bash - - ./calc-cli calc add -a 1 -b foo - - invalid value for b, must be INT - - run './calccli --help' for detailed usage. - - ``` - - - The generated code validates the command line arguments against the types - - defined in the design. The server also validates the types when decoding - - incoming requests so that your code only has to deal with the business logic. - - - ### 4. Document - - - The `http` directory contains the OpenAPI 2.0 specification in both YAML and - - JSON format. - - - The specification can easily be served from the service itself using a file - - server. The [Files](http://godoc.org/goa.design/goa/dsl/http.go#Files) DSL - - function makes it possible to server static file. Edit the file - - `design/design.go` and add: - - - ```go - - var _ = Service("openapi", func() { - // Serve the file with relative path ../../gen/http/openapi.json for - // requests sent to /swagger.json. - Files("/swagger.json", "../../gen/http/openapi.json") - }) - - ``` - - - Re-run `goa gen calcsvc/design` and note the new directory `gen/openapi` and - - `gen/http/openapi` which contain the implementation for a HTTP handler that - - serves the `openapi.json` file. - - - All we need to do is mount the handler on the service mux. Add the corresponding - - import statement to `cmd/calc/http.go`: - - - ```go - - import openapisvr "calcsvc/gen/http/openapi/server" - - ``` - - - and mount the handler by adding the following line in the same file and after - - the mux creation (e.g. one the line after the `// Configure the mux.` comment): - - - ```go - - openapisvr.Mount(mux) - - ``` - - - That's it! we now have a self-documenting service. Stop the running service - - with CTRL-C. Rebuild and re-run it then make requests to the newly added - - `/swagger.json` endpoint: - - - ``` bash - - ^C[calcapi] 16:17:37 exiting (interrupt) - - [calcapi] 16:17:37 shutting down HTTP server at "localhost:8088" - - [calcapi] 16:17:37 exited - - go build - - ./calc - - ``` - - - In a different console: - - - ``` bash - - curl localhost:8088/swagger.json - - {"swagger":"2.0","info":{"title":"Calculator Service","description":... - - ``` - - - ## Resources - - - Consult the following resources to learn more about Goa. - - - ### Docs - - - See the [goa.design](https://goa.design) website. - - - ### Examples - - - The [examples](https://github.com/goadesign/examples) directory - - contains simple examples illustrating basic concepts. - - - ## Contributing - - - See [CONTRIBUTING](https://github.com/goadesign/goa/blob/v3/CONTRIBUTING.md). -BigstickCarpet/swagger-parser#swagger-parser: '{"id":25453221,"node_id":"MDEwOlJlcG9zaXRvcnkyNTQ1MzIyMQ==","name":"swagger-parser","full_name":"APIDevTools/swagger-parser","private":false,"owner":{"login":"APIDevTools","id":43750074,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQzNzUwMDc0","avatar_url":"https://avatars0.githubusercontent.com/u/43750074?v=4","gravatar_id":"","url":"https://api.github.com/users/APIDevTools","html_url":"https://github.com/APIDevTools","followers_url":"https://api.github.com/users/APIDevTools/followers","following_url":"https://api.github.com/users/APIDevTools/following{/other_user}","gists_url":"https://api.github.com/users/APIDevTools/gists{/gist_id}","starred_url":"https://api.github.com/users/APIDevTools/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/APIDevTools/subscriptions","organizations_url":"https://api.github.com/users/APIDevTools/orgs","repos_url":"https://api.github.com/users/APIDevTools/repos","events_url":"https://api.github.com/users/APIDevTools/events{/privacy}","received_events_url":"https://api.github.com/users/APIDevTools/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/APIDevTools/swagger-parser","description":"Swagger - 2.0 and OpenAPI 3.0 - parser/validator","fork":false,"url":"https://api.github.com/repos/APIDevTools/swagger-parser","forks_url":"https://api.github.com/repos/APIDevTools/swagger-parser/forks","keys_url":"https://api.github.com/repos/APIDevTools/swagger-parser/keys{/key_id}","collaborators_url":"https://api.github.com/repos/APIDevTools/swagger-parser/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/APIDevTools/swagger-parser/teams","hooks_url":"https://api.github.com/repos/APIDevTools/swagger-parser/hooks","issue_events_url":"https://api.github.com/repos/APIDevTools/swagger-parser/issues/events{/number}","events_url":"https://api.github.com/repos/APIDevTools/swagger-parser/events","assignees_url":"https://api.github.com/repos/APIDevTools/swagger-parser/assignees{/user}","branches_url":"https://api.github.com/repos/APIDevTools/swagger-parser/branches{/branch}","tags_url":"https://api.github.com/repos/APIDevTools/swagger-parser/tags","blobs_url":"https://api.github.com/repos/APIDevTools/swagger-parser/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/APIDevTools/swagger-parser/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/APIDevTools/swagger-parser/git/refs{/sha}","trees_url":"https://api.github.com/repos/APIDevTools/swagger-parser/git/trees{/sha}","statuses_url":"https://api.github.com/repos/APIDevTools/swagger-parser/statuses/{sha}","languages_url":"https://api.github.com/repos/APIDevTools/swagger-parser/languages","stargazers_url":"https://api.github.com/repos/APIDevTools/swagger-parser/stargazers","contributors_url":"https://api.github.com/repos/APIDevTools/swagger-parser/contributors","subscribers_url":"https://api.github.com/repos/APIDevTools/swagger-parser/subscribers","subscription_url":"https://api.github.com/repos/APIDevTools/swagger-parser/subscription","commits_url":"https://api.github.com/repos/APIDevTools/swagger-parser/commits{/sha}","git_commits_url":"https://api.github.com/repos/APIDevTools/swagger-parser/git/commits{/sha}","comments_url":"https://api.github.com/repos/APIDevTools/swagger-parser/comments{/number}","issue_comment_url":"https://api.github.com/repos/APIDevTools/swagger-parser/issues/comments{/number}","contents_url":"https://api.github.com/repos/APIDevTools/swagger-parser/contents/{+path}","compare_url":"https://api.github.com/repos/APIDevTools/swagger-parser/compare/{base}...{head}","merges_url":"https://api.github.com/repos/APIDevTools/swagger-parser/merges","archive_url":"https://api.github.com/repos/APIDevTools/swagger-parser/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/APIDevTools/swagger-parser/downloads","issues_url":"https://api.github.com/repos/APIDevTools/swagger-parser/issues{/number}","pulls_url":"https://api.github.com/repos/APIDevTools/swagger-parser/pulls{/number}","milestones_url":"https://api.github.com/repos/APIDevTools/swagger-parser/milestones{/number}","notifications_url":"https://api.github.com/repos/APIDevTools/swagger-parser/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/APIDevTools/swagger-parser/labels{/name}","releases_url":"https://api.github.com/repos/APIDevTools/swagger-parser/releases{/id}","deployments_url":"https://api.github.com/repos/APIDevTools/swagger-parser/deployments","created_at":"2014-10-20T06:14:51Z","updated_at":"2020-04-06T17:57:45Z","pushed_at":"2020-04-01T13:01:11Z","git_url":"git://github.com/APIDevTools/swagger-parser.git","ssh_url":"git@github.com:APIDevTools/swagger-parser.git","clone_url":"https://github.com/APIDevTools/swagger-parser.git","svn_url":"https://github.com/APIDevTools/swagger-parser","homepage":"https://apitools.dev/swagger-parser","size":32415,"stargazers_count":584,"watchers_count":584,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":93,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":41,"license":{"key":"mit","name":"MIT - License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":93,"open_issues":41,"watchers":584,"default_branch":"master","permissions":{"admin":false,"push":false,"pull":true},"temp_clone_token":"","organization":{"login":"APIDevTools","id":43750074,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQzNzUwMDc0","avatar_url":"https://avatars0.githubusercontent.com/u/43750074?v=4","gravatar_id":"","url":"https://api.github.com/users/APIDevTools","html_url":"https://github.com/APIDevTools","followers_url":"https://api.github.com/users/APIDevTools/followers","following_url":"https://api.github.com/users/APIDevTools/following{/other_user}","gists_url":"https://api.github.com/users/APIDevTools/gists{/gist_id}","starred_url":"https://api.github.com/users/APIDevTools/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/APIDevTools/subscriptions","organizations_url":"https://api.github.com/users/APIDevTools/orgs","repos_url":"https://api.github.com/users/APIDevTools/repos","events_url":"https://api.github.com/users/APIDevTools/events{/privacy}","received_events_url":"https://api.github.com/users/APIDevTools/received_events","type":"Organization","site_admin":false},"network_count":93,"subscribers_count":17}' -kogosoftwarellc/express-openapi: > - # @open-api [![Build - Status][travis-image]][travis-url] [![Coveralls - Status][coveralls-image]][coveralls-url] [![Gitter - chat][gitter-image]][gitter-url] [![Greenkeeper - badge](https://badges.greenkeeper.io/kogosoftwarellc/open-api.svg)](https://greenkeeper.io/) - - > A Monorepo of various packages to power OpenAPI in node. - - - ## Quick Start Express - - - * See [express-openapi](https://github.com/kogosoftwarellc/open-api/tree/master/packages/express-openapi)   [![express-openapi Downloads][express-openapi-downloads-image]][express-openapi-npm-url] - - - ## Quick Start Koa - - * See [koa-openapi](https://github.com/kogosoftwarellc/open-api/tree/master/packages/koa-openapi)   [![koa-openapi Downloads][koa-openapi-downloads-image]][koa-openapi-npm-url] - - - ## Packages - - * [express-openapi](https://github.com/kogosoftwarellc/open-api/tree/master/packages/express-openapi) - - * [fetch-openapi](https://github.com/kogosoftwarellc/open-api/tree/master/packages/fetch-openapi) - - * [fs-routes](https://github.com/kogosoftwarellc/open-api/tree/master/packages/fs-routes) - - * [openapi-default-setter](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-default-setter) - - * [openapi-framework](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-framework) - - * [openapi-jsonschema-parameters](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-jsonschema-parameters) - - * [openapi-request-coercer](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-request-coercer) - - * [openapi-request-validator](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-request-validator) - - * [openapi-response-validator](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-response-validator) - - * [openapi-schema-validator](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-schema-validator) - - * [openapi-types](https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-types) - - - ## Development - - - _Note: One of the goals of this monorepo is to support independent package versions. The author has used other popular options out there (like lerna), and has found independent versioning to behave strangely with them. Another goal with the current approach is to reduce boilerplate code as much as possible (something tools like lerna don't help with). The inspiration for the current approach came from [boennemann/alle](https://github.com/boennemann/alle). The author isn't - - married to the current approach, so if you have ideas on how to simplify the development of this monorepo by all means please [open an issue](https://github.com/kogosoftwarellc/open-api/issues/new)._ - - - ### Typical Workflow for Contributors - - - Let's say you're working on a package under [./packages](https://github.com/kogosoftwarellc/open-api/tree/master/packages). Here's what you do: - - - 1. `cd open-api` - - 1. `./bin/test packages/` - - 1. Make your changes. - 1. _Do not bump the version in package.json._ A maintainer will handle that once your PR is merged. - 1. Once you're satisfied with your changes: - 1. Create a new branch `git checkout -b my-branch` (in case you haven't done so already). - 1. `./bin/commit packages/ 'commit message describing your change. can be multi line here. just close with a single quote like so:'` - 1. Push your change to your fork - 1. Open a PR. - - ### bin - - - Several scripts have been created to aid in the development of this monorepo (see [./bin](./bin)). They assume that your `$PWD` is the root of the repository. Here is a brief summary of common actions: - - - * Testing - * (Note: `./bin/test` will run `npm i` in the package _prior_ to running the tests) - * Test a single package - `./bin/test packages/` (starts the test in watch mode) - * Test all packages - `./bin/test` - * Commit changes to a package - `./bin/commit packages/ 'Commit message'` (the commit message will be prepended with the package name e.g. `: Commit message` - - - #### dev-tools - - Scripts in this directory wrap common tools, like `nyc`, `tsc`, and `mocha`. They reduce boilerplate and are called from npm scripts. - - - ## LICENSE - - - ``` - - The MIT License (MIT) - - - Copyright (c) 2018 Kogo Software LLC - - - Permission is hereby granted, free of charge, to any person obtaining a copy - - of this software and associated documentation files (the "Software"), to deal - - in the Software without restriction, including without limitation the rights - - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - - copies of the Software, and to permit persons to whom the Software is - - furnished to do so, subject to the following conditions: - - - The above copyright notice and this permission notice shall be included in - - all copies or substantial portions of the Software. - - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - - THE SOFTWARE. - - ``` - - - [express-openapi-downloads-image]: http://img.shields.io/npm/dm/express-openapi.svg - - [express-openapi-npm-url]: https://npmjs.org/package/express-openapi - - [koa-openapi-downloads-image]: http://img.shields.io/npm/dm/koa-openapi.svg - - [koa-openapi-npm-url]: https://npmjs.org/package/koa-openapi - - - [travis-url]: https://travis-ci.org/kogosoftwarellc/open-api - - [travis-image]: https://api.travis-ci.org/kogosoftwarellc/open-api.svg?branch=master - - - [coveralls-url]: https://coveralls.io/r/kogosoftwarellc/open-api - - [coveralls-image]: https://coveralls.io/repos/github/kogosoftwarellc/open-api/badge.svg?branch=master - - - [gitter-url]: https://gitter.im/kogosoftwarellc/open-api - - [gitter-image]: https://badges.gitter.im/kogosoftwarellc/open-api.png -inaka/cowboy-swagger: > - - - - # cowboy-swagger - - [Swagger](http://swagger.io/) integration for [Cowboy](https://github.com/ninenines/cowboy) (built on [trails](https://github.com/inaka/cowboy-trails)). - - - ## Contact Us - - If you find any **bugs** or have a **problem** while using this library, please - - [open an issue](https://github.com/inaka/elvis/issues/new) in this repo - - (or a pull request :)). - - - ## Requirements - - Cowboy Swagger requires Erlang 18+ after 0.1.0 version - - - ## Why Cowboy Swagger? - - Simple, because there isn't a tool in Erlang to document Cowboy RESTful APIs easy and fast, - - and to improve development productivity. - - - With `cowboy_swagger` is possible to integrate Swagger to your Erlang projects that use Cowboy as a web server. - - It is extremely easy to use, and with just a few steps you'll have a nice Web documentation for your RESTful APIs. - - - To learn a bit more about Swagger, please check this [blog post](http://inaka.net/blog/2015/06/23/erlang-swagger-2015/). - - - ## How to Use it? - - This is the best part. It is extremely easy. - - - ### 1. Document each Cowboy Handler - - Because `cowboy_swagger` runs on top of `trails`, the first thing that you have to do - - is document all about your handler within the trails metadata. Keep in mind that - - all fields defined within each method into the metadata must be compliant with the - - [Swagger specification](http://swagger.io/specification). - - - For example, suppose that you have `example_echo_handler`, so it must implement the `trails/0` - - callback from `trails_handler` behaviour: - - - ```erlang - - trails() -> - Metadata = - #{get => - #{tags => ["echo"], - description => "Gets echo var from the server", - produces => ["text/plain"] - }, - put => - #{tags => ["echo"], - description => "Sets echo var in the server", - produces => ["text/plain"], - parameters => [ - #{name => <<"echo">>, - description => <<"Echo message">>, - in => <<"path">>, - required => false, - type => <<"string">>} - ] - } - }, - [trails:trail("/message/[:echo]", example_echo_handler, [], Metadata)]. - ``` - - - To get a better idea of how your handler should look like, please check [here](./example/src/example_echo_handler.erl). - - - ### 2. Include cowboy_swagger in your app - - First, you need to include `cowboy_swagger_handler` module in your list of trails to be compiled. - - - ```erlang - - % Include cowboy_swagger_handler in the trails list - - Trails = trails:trails([example_echo_handler, - example_description_handler, - cowboy_swagger_handler]), - % store them - - trails:store(Trails), - - % and then compile them - - Dispatch = trails:single_host_compile(Trails), - - ``` - - - The snippet of code above is usually placed when you start `cowboy`. Check it [here](./example/src/example.erl#L31). - - - Then add `cowboy_swagger` to the list of apps to be loaded in your `*.app.src` file. - - - ```erlang - - {application, example, - [ - {description, "Cowboy Swagger Basic Example."}, - {vsn, "0.1"}, - {applications, - [kernel, - stdlib, - jsx, - cowboy, - trails, - cowboy_swagger - ]}, - {modules, []}, - {mod, {example, []}}, - {registered, []}, - {start_phases, [{start_trails_http, []}]} - ] - }. - - ``` - - - And that's it, you got it. Now start your application and then you will have access to the API docs - - under the path `/api-docs`. Supposing that you're running the app on `localhost:8080`, - - that will be [http://localhost:8080/api-docs](http://localhost:8080/api-docs). - - - ## Configuration - - - Additionally, `cowboy_swagger` can be configured/customized from a `*.config` file: - - - ### app.config - - - ```erlang - - [ - %% Other apps ... - - %% cowboy_swagger config - {cowboy_swagger, - [ - %% `static_files`: Static content directory. This is where Swagger-UI - %% is located. Default: `priv/swagger`. - %% Remember that Swagger-UI is embedded into `cowboy-swagger` project, - %% within `priv/swagger` folder. BUT you have to reference that path, - %% and depending on how you're using `cowboy-swagger` it will be different. - %% For example, assuming that you want to run your app which has - %% `cowboy-swagger` as dependency from the console, `static_files` will be: - {static_files, "./deps/cowboy_swagger/priv/swagger"}, - - %% `global_spec`: Global fields for Swagger specification. - %% If these fields are not set, `cowboy_swagger` will set default values. - {global_spec, - #{swagger => "2.0", - info => #{title => "Example API"}, - basePath => "/api-docs" - } - } - ] - } - ]. - - ``` - - - ### Definitions - - - [Definitions](http://swagger.io/specification/#definitionsObject) can be used for describing - - [parameters](http://swagger.io/specification/#parametersDefinitionsObject), - - [responses](http://swagger.io/specification/#responsesDefinitionsObject) and - - [security](http://swagger.io/specification/#securityDefinitionsObject) schemas. - - - For adding definitions to your app, you have 2 choices: - - - 1. Add a `definitions` key to your cowboy_swagger `global_spec` map. - - 2. Add them by calling `cowboy_swagger:add_definition/2` and send the - definition's name and properties. - - Let's say you want to describe a `POST` call to a `newspapers` endpoint that requires - - `name` and `description` fields only, you can do it like this: - - - **Option 1:** - - ```erlang - - [ ... % other configurations - - , { cowboy_swagger - , [ { global_spec - , #{ swagger => "2.0" - , info => #{title => "My app API"} - , definitions => #{ - "RequestBody" => - #{ "name" => - #{ "type" => "string" - , "description" => "Newspaper name" - } - , "description" => - #{ "type" => "string" - , "description" => "Newspaper description" - } - } - } - } - } - ] - } - ] - - ``` - - - **Option 2:** - - - For the second choice, you can do it for example in one or several `start_phases`, - - directly in your handler or any other place you want. - - - ```erlang - - -spec trails() -> trails:trails(). - - trails() -> - DefinitionName = <<"RequestBody">>, - DefinitionProperties = - #{ <<"name">> => - #{ type => <<"string">> - , description => <<"Newspaper name">> - } - , <<"description">> => - #{ type => <<"string">> - , description => <<"Newspaper description">> - } - }, - % Add the definition - ok = cowboy_swagger:add_definition(DefinitionName, DefinitionProperties), - ... - ``` - - - - Now in your handler's trails callback function you can use it: - - - ```erlang - - ... - RequestBody = - #{ name => <<"request body">> - , in => body - , description => <<"request body (as json)">> - , required => true - % Use the previously created `RequestBody' definition - , schema => cowboy_swagger:schema(<<"RequestBody">>) - }, - Metadata = - #{ get => - #{ tags => ["newspapers"] - , description => "Returns the list of newspapers" - , produces => ["application/json"] - } - , post => - # { tags => ["newspapers"] - , description => "Creates a new newspaper" - , consumes => ["application/json"] - , produces => ["application/json"] - , parameters => [RequestBody] % and then use that parameter here - } - }, - Path = "/newspapers", - Options = #{path => Path}, - [trails:trail(Path, newspapers_handler, Options, Metadata)]. - ``` - - - What this does for you is add a nice `response`, `parameter` or `security` - - model in swagger-ui, so client developers will know exactly what parameters - - the API expects for every endpoint. - - - ## Example - - For more information about `cowboy_swagger` and how to use it, please check this [Example](./example). -gedaiu/swaggarize: > - # OpenApi - - - I will not mantain this project in the future. Please have a loog at this fork: [https://github.com/gedaiu/OpenApi](https://github.com/gedaiu/OpenApi) -tjwebb/sails-swagger: > - # sails-swagger - - - [![NPM version][npm-image]][npm-url] - - [![Build status][ci-image]][ci-url] - - [![Dependency Status][daviddm-image]][daviddm-url] - - [![Code Climate][codeclimate-image]][codeclimate-url] - - - - [swagger.io](http://swagger.io/) (v2.0) hook for Sails. The application's models, controllers, and routes are aggregated and transformed into a Swagger Document. Supports the Swagger 2.0 specification. - - - ## Install - - - ```sh - - $ npm install sails-swagger --save - - ``` - - - ## Configuration - - ```js - - // config/swagger.js - - module.exports.swagger = { - /** - * require() the package.json file for your Sails app. - */ - pkg: require('../package'), - ui: { - url: 'http://swagger.balderdash.io' - } - }; - - ``` - - - ## Usage - - After installing and configuring swagger, you can find the docs output on the [/swagger/doc](http://localhost:1337/swagger/doc) route. - - - You may also specify additional swagger endpoints by specifying the swagger spec in config/routes.js - - - ``` - - /** - * Route Mappings - * @file config/routes.js - * (sails.config.routes) - * - * Your routes map URLs to views and controllers. - */ - - module.exports.routes = { - - /*************************************************************************** - * * - * Make the view located at `views/homepage.ejs` (or `views/homepage.jade`, * - * etc. depending on your default view engine) your home page. * - * * - * (Alternatively, remove this and add an `index.html` file in your * - * `assets` directory) * - * * - ***************************************************************************/ - - '/': { - view: 'homepage' - }, - - /*************************************************************************** - * * - * Custom routes here... * - * * - * If a request to a URL doesn't match any of the custom routes above, it * - * is matched against Sails route blueprints. See `config/blueprints.js` * - * for configuration options and examples. * - * * - ***************************************************************************/ - 'get /groups/:id': { - controller: 'GroupController', - action: 'test', - skipAssets: 'true', - //swagger path object - swagger: { - methods: ['GET', 'POST'], - summary: ' Get Groups ', - description: 'Get Groups Description', - produces: [ - 'application/json' - ], - tags: [ - 'Groups' - ], - responses: { - '200': { - description: 'List of Groups', - schema: 'Group', // api/model/Group.js, - type: 'array' - } - }, - parameters: [] - - } - }, - 'put /groups/:id': { - controller: 'GroupController', - action: 'test', - skipAssets: 'true', - //swagger path object - swagger: { - methods: ['PUT', 'POST'], - summary: 'Update Groups ', - description: 'Update Groups Description', - produces: [ - 'application/json' - ], - tags: [ - 'Groups' - ], - responses: { - '200': { - description: 'Updated Group', - schema: 'Group' // api/model/Group.js - } - }, - parameters: [ - 'Group' // api/model/Group.js - ] - - } - } - }; - - - - ``` - - - ## License - - MIT - - - ## Maintained By - - [](http://langa.io) - - - [sails-version-image]: https://goo.gl/gTUV5x - - [sails-url]: http://sailsjs.org - - [npm-image]: https://img.shields.io/npm/v/sails-swagger.svg?style=flat - - [npm-url]: https://npmjs.org/package/sails-swagger - - [ci-image]: https://img.shields.io/travis/langateam/sails-swagger/master.svg?style=flat - - [ci-url]: https://travis-ci.org/langateam/sails-swagger - - [daviddm-image]: http://img.shields.io/david/langateam/sails-swagger.svg?style=flat - - [daviddm-url]: https://david-dm.org/langateam/sails-swagger - - [codeclimate-image]: https://img.shields.io/codeclimate/github/langateam/sails-swagger.svg?style=flat - - [codeclimate-url]: https://codeclimate.com/github/langateam/sails-swagger -sarnowski/swagger1st: > - ## swagger1st: A Swagger-First Clojure Ring handler - - - ![Maven Central](https://img.shields.io/maven-central/v/org.zalando/swagger1st.svg) - - [![Build Status](https://travis-ci.org/zalando-stups/swagger1st.svg?branch=master)](https://travis-ci.org/zalando-stups/swagger1st) - - [![codecov](https://codecov.io/gh/zalando-stups/swagger1st/branch/master/graph/badge.svg)](https://codecov.io/gh/zalando-stups/swagger1st) - - - swagger1st is a Clojure [Ring](https://github.com/ring-clojure/ring) handler that parses, validates and routes requests - - based on your [Swagger](http://swagger.io/)/OpenAPI definition. It takes the opposite approach of [ring-swagger](https://github.com/metosin/ring-swagger)—which enables you to generate your Swagger spec from your Clojure code—by allowing you to use your Swagger spec to generate Clojure code. - - - Instead of defining routes and validation rules in your code, you can use swagger1st along with [Swagger/OpenAPI's great tool set](http://editor.swagger.io/) to specify your API according to the [Swagger/Open API 2.0 Specification](https://github.com/swagger-api/swagger-spec). This enables you to specify your API in an API-First, technology-independent format. The resulting definition is the ultimate format for publishing, sharing and reviewing your API. - - - #### Compatibility Overview - - swagger1st aims to implement all of the Swagger/OpenAPI spec's features, so that you only have to write your business logic. [This document](https://github.com/zalando-stups/swagger1st/blob/master/comp-2.0.md) shows which aspects of the spec it currently supports. - - - swagger1st will use the Swagger definition of your API as a configuration file for processing incoming requests—ensuring that your implementation and specification always remain in sync. During runtime, you can inspect and easily test - - your API with the built-in [Swagger UI](http://petstore.swagger.io/). You can also extend the interpretation of - - your definition according to your own needs. - - - Imagine a simple API definition like this: - - - ```yaml - - swagger: '2.0' - - - info: - title: Example API - version: '0.1' - - paths: - /helloworld: - get: - summary: Returns a greeting. - operationId: example.api/generate-greeting - parameters: - - name: firstname - in: query - type: string - pattern: "^[A-Z][a-z]+" - responses: - 200: - description: say hello - ``` - - - By default, this definition is connected to your business logic via the `operationId`, which might be defined like so: - - - ```clojure - - (ns example.api - (:require [ring.util.response :as r])) - - (defn generate-greeting [request] - (let [firstname (-> request :parameters :query :firstname)] - (-> (r/response (str "Hello " firstname "!")) - (r/content-type "plain/text")))) - ``` - - - This is all you need to do to define and implement your API. Only fully validated requests get to your function, - - so you can rely on swagger1st to properly check all input parameters according to your definition. The function itself - - is a normal Clojure function without any dependencies to swagger1st - simple as that. - - - ### Quickstart - - - The following provides instructions for simple, complex and manual setups. For all three approaches you'll need to install [Leiningen](http://leiningen.org/) as the build tool. - - - #### Simple Setup - - If you're bootstrapping a completely new project, or just want to try out swagger1st, you can use this Leiningen template: - - - ``` - - $ lein new swagger1st myproject - - $ cd myproject - - $ lein ring server-headless - - ``` - - - This will run a local web server on port 3000, so you can interact with the API at . Also, you might want to have a look at for a graphical interface to explore and experiment with your API (using [Swagger UI](http://petstore.swagger.io/)). - - - ### Complex Setup - - - To see how you can handle dependency injection with swagger1st, generate a project setup that includes Stuart Sierra's - - [component](https://github.com/stuartsierra/component) framework: - - - ``` - - $ lein new swagger1st myproject +component - - $ cd myproject - - $ lein run -m myproject.core - - ``` - - - As with the simple setup above, this will launch a local web server on port 3000. - - - ### Manual Setup - - - The following steps describe how to manually set up swagger1st in a Clojure project. This is especially useful if you want to integrate it into an existing project or cannot use the provided template for other reasons. - - - Use the following dependency in your [Leiningen](http://leiningen.org/) project: - - [org.zalando/swagger1st ""] - - This creates a Ring-compliant handler: - - - ```clojure - - (ns example - (:require [io.sarnowski.swagger1st.core :as s1st] - [io.sarnowski.swagger1st.util.security :as s1stsec])) - - (def app - (-> (s1st/context :yaml-cp "my-swagger-api.yaml") - (s1st/discoverer) - (s1st/mapper) - (s1st/parser) - (s1st/protector {"oauth2" (s1stsec/allow-all)}) - (s1st/executor))) - ``` - - - ### Commands for Development - - - ```shell - - # get the source - - $ git clone https://github.com/zalando-stups/swagger1st.git - - $ cd swagger1st - - - # run the tests - - $ lein test - - - # run all tests, including performance benchmarks - - $ lein test :all - - - # build an own artifact for local development - - $ lein install - - - # release a new version - - $ lein release :minor - - ``` - - - For interactive development, you can start a REPL by typing `lein repl`. - - - ### Projects Using Swagger1st in Production - - - - [Friboo](https://github.com/zalando/friboo), a utility library for writing microservices in Clojure, with support for Swagger and OAuth. It uses swagger1st at its base for RESTful HTTP endpoints and also integrates with the [component](https://github.com/stuartsierra/component) framework. - - - [STUPS.io](https://stups.io/) components [Kio](https://github.com/zalando-stups/kio), [PierOne](https://github.com/zalando-stups/pierone) (a complete Docker registry based on S3), [Essentials](https://github.com/zalando-stups/essentials), [TWINTIP](https://github.com/zalando-stups/twintip-storage) and [mint](https://github.com/zalando-stups/mint-storage) - - - ### The Ring Handler in Detail - - - * `s1st/context` (required) - * Creates a new context from a given definition. This context will be used by the next steps to prepare the - execution of requests. - * `s1st/discoverer` (optional) - * The discoverer enables certain HTTP endpoints, that makes it easy to work with your API. In particular, this - enables the Swagger UI under the path `/ui/` and exposes the Swagger definition under `/swagger.json`. - * `s1st/mapper` (required) - * The mapper denormalizes the given definition (e.g. resolves all `$ref`s) and figures out, which request definition - maps to the actual incoming request. After this function, your `request` map contains the `:swagger` key, which - contains a `:request` key containing the denormalized definition of the request and a `:key` key which can be used - to uniquely identify a request. - * `s1st/parser` (required) - * The parser parses the incoming request according to the definition and validates all inputs. - * `s1st/protector` (optional) - * The protector can enforce all security definitions for you. As the security check implementations vary depending - on your environment, this is only a framework to hook into the system and define callbacks for the actual checks. - * `s1st/executor` (required) - * The executor executes your defined function in the end. At this point, the whole definition was validated and only - valid requests make it up until here. You can also specify an own function resolver function in order to hook into - your own framework. - - ### License - - - Copyright (c) 2015, Tobias Sarnowski - - Copyright (c) 2016, Zalando SE - - - Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, - - provided that the above copyright notice and this permission notice appear in all copies. - - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF - - THIS SOFTWARE. -lucybot/api-spec-converter: > - # api-spec-converter - - [![Share on Twitter][twitter-image]][twitter-link] - - - [![Chat on gitter][gitter-image]][gitter-link] - - [![NPM version][npm-image]][npm-link] - - [![Build status][travis-image]][travis-link] - - - [![Dependency status][deps-image]][deps-link] - - [![devDependency status][devdeps-image]][devdeps-link] - - - Convert between API description formats such as [Swagger](http://swagger.io/) and [RAML](http://raml.org/) - - - **Currently only supports conversion to OpenAPI(fka Swagger) 2.0 format, and from OpenAPI 2.0 to OpenAPI 3.0.x** - - - You can also use the online version at https://lucybot-inc.github.io/api-spec-converter/. - - - ## Installation - - - ### Command Line - - > Problems? See [issue #132](https://github.com/LucyBot-Inc/api-spec-converter/issues/132) - - ```bash - - npm install -g api-spec-converter - - ``` - - - ### NodeJS/Browser - - ```bash - - npm install --save api-spec-converter - - ``` - - - ## Usage - - - ### Command Line - - ```bash - - $ api-spec-converter -h - - Usage: api-spec-converter [options] - - Convert API descriptions between popular formats. - - Supported formats: - * swagger_1 - * swagger_2 - * openapi_3 - * api_blueprint - * io_docs - * google - * raml - * wadl - - Options: - - -h, --help output usage information - -V, --version output the version number - -f, --from Specifies format to convert - -t, --to Specifies output format - -s, --syntax [syntax] Specifies output data syntax: json or yaml. Defaults to json - -o, --order [sortOrder] Specifies top fields ordering: openapi or alpha. Defaults to openapi - -c, --check Check if result is valid spec - -d, --dummy Fill missing required fields with dummy data - ``` - - - Example: - - ```bash - - $ api-spec-converter --from=swagger_1 --to=swagger_2 --syntax=yaml --order=alpha https://raw.githubusercontent.com/LucyBot-Inc/api-spec-converter/master/test/input/swagger_1/petstore/pet.json > swagger.json - - ``` - - - ### NodeJS - - - ### Options - - * `from` - source format (see formats below) - - * `to` - desired format (see formats below) - - * `source` - Filename, URL, or JS object for the source - - ### Simple example: - - ```js - - var Converter = require('api-spec-converter'); - - - Converter.convert({ - from: 'swagger_1', - to: 'swagger_2', - source: 'https://api.gettyimages.com/swagger/api-docs', - }, function(err, converted) { - console.log(converted.stringify()); - // For yaml and/or OpenApi field order output replace above line - // with an options object like below - // var options = {syntax: 'yaml', order: 'openapi'} - // console.log(converted.stringify(options)); - }) - - ``` - - ### Callback vs Promises - - This library has full support for both callback and promises. - - All async functions return promises but also will execute callback if provided. - - - ```js - - var Converter = require('api-spec-converter'); - - - Converter.convert({ - from: 'swagger_1', - to: 'swagger_2', - source: 'https://api.gettyimages.com/swagger/api-docs', - }) - - .then(function(converted) { - console.log(converted.stringify()); - }); - - ``` - - ### Advanced features: - - ```js - - var Converter = require('api-spec-converter'); - - Converter.convert({ - from: 'swagger_1', - to: 'swagger_2', - source: 'https://api.gettyimages.com/swagger/api-docs', - }) - .then(function(converted) { - // [Optional] Fill missing fields with dummy values - converted.fillMissing(); - - // [Optional] Validate converted spec - return converted.validate() - .then(function (result) { - if (result.errors) - return console.error(JSON.stringify(errors, null, 2)); - if (result.warnings) - return console.error(JSON.stringify(warnings, null, 2)); - - fs.writeFileSync('swagger2.json', converted.stringify()); - }); - }); - ``` - - - ### Browser - - ```js - - - - APISpecConverter.convert(...) - - ``` - - - ## Supported Formats - - - * [Swagger 1.x](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/1.2.md) (swagger_1) - - * [OpenAPI(fka Swagger) 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) (swagger_2) - - * [OpenAPI 3.0.x](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md) (openapi_3) - - * [I/O Docs](https://github.com/mashery/iodocs) (io_docs) - - * [API Blueprint](https://github.com/apiaryio/api-blueprint/blob/master/API%20Blueprint%20Specification.md) (api_blueprint) - - * [Google API Discovery](https://developers.google.com/discovery/v1/reference/apis) (google) - - * [RAML](http://raml.org/spec.html) (raml) - - * [WADL](http://www.w3.org/Submission/wadl/) (wadl) - - - - ## Conversion Table - - - |from: |swagger_1|swagger_2|openapi_3|io_docs|api_blueprint|google|raml|wadl| - - -------------------|:-------:|:-------:|:-----:|:-----:|:-----------:|:----:|:--:|:--:| - - |to swagger_1 | n/a | | | | | | | | - - |to swagger_2 | :white_check_mark: | n/a | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | - - |to openapi_3 | :eight_spoked_asterisk: | :white_check_mark: | n/a | :eight_spoked_asterisk: | :eight_spoked_asterisk: | :eight_spoked_asterisk: | :eight_spoked_asterisk: | :eight_spoked_asterisk: | - - |to io_docs | | | | n/a | | | | | - - |to api_blueprint | | | | | n/a | | | | - - |to google | | | | | | n/a | | | - - |to raml | | | | | | | n/a| | - - |to wadl | | | | | | | | n/a| - - - #### Key - - * :white_check_mark: - direct conversion - - * :eight_spoked_asterisk: - conversion via swagger_2 - - - ## Contributing - - Contributions are welcome and encouraged. - - - ### Testing - - Please add a test case if you're adding features or fixing bugs. To run the tests: - - - ```bash - - WRITE_GOLDEN=true npm test - - ``` - - - ### Releases - - ``` - - npm run browserify - - git commit -a -m "Build browser distribution" - - npm version minor # or major/patch - - npm publish - - git push --follow-tags - - ``` - - - [twitter-image]: https://img.shields.io/twitter/url/http/lucybot.github.io/api-spec-converter.svg?style=social - - [twitter-link]: https://twitter.com/intent/tweet?text=Convert+between+API+description+formats+such+as+Swagger+and+RAML:&url=http%3A%2F%2Flucybot.github.io%2Fapi-spec-converter - - [gitter-image]: https://img.shields.io/gitter/room/lucybot/api-spec-converter.svg - - [gitter-link]: https://gitter.im/lucybot/api-spec-converter - - [npm-image]: https://img.shields.io/npm/v/api-spec-converter.svg - - [npm-link]: https://npmjs.org/package/api-spec-converter - - [travis-image]: https://img.shields.io/travis/LucyBot-Inc/api-spec-converter.svg - - [travis-link]: https://travis-ci.org/LucyBot-Inc/api-spec-converter - - [deps-image]: https://img.shields.io/david/lucybot/api-spec-converter.svg - - [deps-link]: https://david-dm.org/lucybot/api-spec-converter - - [devdeps-image]: https://img.shields.io/david/dev/lucybot/api-spec-converter.svg - - [devdeps-link]: https://david-dm.org/lucybot/api-spec-converter#info=devDependencies -zalando/play-swagger: > - ## The Play-Swagger plugin is now renamed - [api-first-hand](https://github.com/zalando/api-first-hand). This version is - no longer under active development. - - ## Api-First-Hand is actively mantained and offers full functionality of Play-Swagger with an exception of Play 2.4 support. Please navigate to [api-first-hand](https://github.com/zalando/api-first-hand) if you'd like to check out Play-Swagger or create an issue. - - - -- - - -- - - -- - - -- - - - - # Play-Swagger - - - [![Build Status](https://travis-ci.org/zalando/play-swagger.svg)](https://travis-ci.org/zalando/play-swagger) - - [![codecov](https://codecov.io/gh/zalando/play-swagger/branch/master/graph/badge.svg)](https://codecov.io/gh/zalando/play-swagger) - - [![Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/zalando/play-swagger?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - - - ## Compatibility - - - - Play 2.4 - - - Swagger (OpenAPI) 2.0 - - - ## Status - - - This plugin should be enabled using the [play-swagger-service](http://www.typesafe.com/activator/template/play-swagger-service) activator template - - as the version in this repository is under active development. The status of this software is beta, - - an end-to-end functional release intended to demonstrate the possibility to generate following from a Swagger specification: - - - - Play route files - - - Generators of random test data - - - Wrappers for Play route files to convert semantics from http-related to domain-related (controller_base) - - - Skeletons for the domain-driven controller implementation - - - Model classes and validation rules - - - Unit tests for invalid and valid parameter sets - - - Security extractors (if needed) - - - Skeletons for custom deserializers (if needed) - - - We benefit from community feedback. All comments are welcome! - - - # Play-Swagger Tutorial - - - This tutorial is based on the [play-swagger-service](http://www.typesafe.com/activator/template/play-swagger-service) activator template. - - - ```bash - - $ activator new playground play-swagger-service - - ``` - - - The template project contains following: - - - - `tutorial` folder with HTML tutorial - - - `public/swagger` folder containing static files needed for swagger UI - - - `project` folder containing pre-configured `plugins.sbt` file with a definition of all required resolvers and plugins - - - `conf` folder with following customized contents: - * `routes` file with route configuration for Swagger UI, example specification and commented out links to other examples - * `example.yaml`, a demo Swagger specification. The specification has a dummy implementation in `app` folder. - * `examples` folder containing other different Swagger specification examples. Each specification in this folder represents some aspect of the Play-Swagger plugin in more details. - For the specification to be picked up by the plugin it must be moved into the `conf` folder. It is allowed to have multiple Swagger specifications in the `conf` folder at the same time. - - `app` directory with following template implementations: - * `controllers/Swagger.scala` - a backend side of the Swagger UI - * `generated_controllers/example.yaml.scala` - a dummy implementation of the example controller. Will be (re)generated if deleted - * `security/example.yaml.scala` - a marshaller for OAuth2 tokens. Will not be regenerated until - a) deleted or renamed - b) explicitly requested by issuing a `apiFirstSecurity` command - - - ## Welcome to Play-Swagger - - - Congratulations, you just created a new Play-Swagger application! - - - The [Play Framework](http://www.playframework.com/) with the [Play-Swagger](https://github.com/zalando/play-Swagger/) - - plugin make it easy to build RESTful web services from a Swagger API specification as the single source of truth. - - Play is based on a lightweight, stateless, web-friendly architecture. Built on [Akka](http://akka.io), - - Play provides predictable and minimal resource consumption for highly-scalable applications. - - The Play-Swagger plugin takes Swagger API definitions and treats them as the single source of truth of your REST services. - - - Play-Swagger supports round-trip regeneration and compilation of: - - - - Play routes definitions (managed). - - - Swagger domain model definitions and parameters onto Scala case classes (managed). - - - Swagger domain model constraints onto Play validations (managed). - - - Generators for random test data generation of parameter values (managed). - - - Unit tests for validating your service at the API boundary (managed). - - - Swagger path definitions onto skeletons for Play controller implementations (unmanaged). - - - In the list above, "(managed)" means that the code is managed by sbt. The code is not controlled - - and altered by you, the programmer of the REST service. The plugin takes your Swagger API definition as the single - - source of truth and regenerates these code parts in a consistent manner. - - You'll instead be focusing on implementing the service business logic in an (unmanaged) Play controller class - - that is generated once. Subsequent regenerations keep the code that you have added, either by commenting out the - - parts that are no longer valid, or by adding parts that are needed because you have made a change to the API. - - - Manual generation and compilation of: - - - - Security extractors - - - Unmarshallers for custom content types - - - is supported in the case if - - - a) No security extractor or unmarshaller with the same name already exists - - b) The developer issues `apiFirstSecurity` or `apiFirstMarshallers` sbt command - - - ## Run Your Application - - - Before we go any further, let's run the application. - - - - Open a shell and `cd` into your service project directory. - - - Start `sbt` and `run` the service. - - - View the running application at [http://localhost:9000](http://localhost:9000). - - - The service template comes with the Swagger UI frontend included, - - run statically from the within Play, which provides a sandbox for your service. - - The template is configured with a template Swagger API definition called `example.yaml` - - and located in the `conf` directory of the Play application. - - - The `example.yaml` definition provides an example [API description](https://github.com/zalando/play-swagger-service/blob/master/conf/example.yaml) - - - This definition contains three end points: - - - the `/token` path, which accept the `GET` and `POST` methods - - - the `/todos/{user_id}`, which accepts the `GET` method. - - - The `GET /token` API plays a role of an authentication server and is used by the Swagger UI for OAuth token requests. - - The `POST /token` API represents an authorization server and is used by the security part of the - - generated code to validate OAuth tokens. - - The `GET /todos/{user_id}` takes a path parameter `user_id` and returns a TODO list for given user. - - For the client to be allowed to access this endpoint, it must provide an OAuth token with the scope `admin:org`. - - The token can be requested using the Swagger UI. - - - Try it out for yourself: - - - Click the [default](http://localhost:9000/) button to expand the API definition in the Swagger UI. - - - - # Play Routes Integration - - - As a Play application developer, you are used to defining your endpoints in the `conf/routes` file. - - Not so with the Play-Swagger plugin! Swagger API specifications already define endpoints as `path` definitions, - - as seen in the example above. So why do the work twice, right? Instead, the Play-Swagger plugin requires you to - - link your API definition in the routes file ones—making all Swagger API-defined endpoints available as children - - of one single path context location, and generating Play route definitions from them (as shown below): - - - ``` - - -> /example example.yaml.Routes - - ``` - - - Note that the `conf/routes` file provided by this activator template also contains a couple of additional `GET` - - mappings required for the the Swagger UI sandbox. - - - There are a couple of commented out links to other examples. If you activate some specification by moving it from - - the `examples` folder into the `conf` folder, you'll need to uncomment an appropriate line in the `routes` file in - - order for play to be able to find it. - - - - ## Swagger Domain Definitions - - - Scala domain model definitions are generated for all data types defined as Swagger parameters in an API specification. - - Swagger parameters can be of path, query, header, form or body types, and consist of either primitive data types or - - more complex types composed from objects and arrays with primitives as leaves. - - - Both primitive types and complex types are mapped to scala. - - - As an example, let's look at the Swagger API specification file [`simple.petstore.api.yaml`](https://github.com/zalando/play-swagger-service/blob/master/conf/examples/simple.petstore.api.yaml), - - which defines the API of a simple pet store. It contains a model definition for a pet. - - - ```yaml - - definitions: - pet: - required: - - id - - name - properties: - id: - type: integer - format: int64 - name: - type: string - tag: - type: string - ``` - - - This definition consists of an object `pet` containing the required properties `id` and `name` - - and the optional property `tag`. The Swagger primitive types of these properties are a 64-bit `integer` - - and (twice) a `string`, successively. The Play-Swagger plugin will map this definition on to a generated Scala model. - - - ```scala - - package simple.petstore.api - - - package object yaml { - - type PetTag = Option[String] - - case class Pet(id: Long, name: String, tag: PetTag) - } - - ``` - - - This generated model contains a type definition `PetTag`, which declares a type alias for the optional `tag` property, - - and a `Pet` case class with the properties as named in the Swagger API definition and mapped on the subsequent - - Scala primitive or declared types. The case class and type alias are generated in an package object `yaml`, - - this package object itself is contained in the package `simple.petstore.api` so that full object name corresponds - - to the API filename. - - - Note that models are generated within a Play application as _managed_ code in the target folder. - - Generated model code is not intended to be altered. We should instead look upon the Swagger definition as the single - - source of truth, and as the source code that defines our model. - - The Swagger specification file of our API is, in that sense, part of the codebase. - - Even though the generated `Pet` case class is managed by the plugin, and not us, it can (of course) - - be used in our application codebase after being imported. - - - ```scala - - import simple.petstore.api.yaml._ - - - val pet = Pet(0L, "Tucker", Some("Greyhound")) - - ``` - - - ## Specification Cross-References - - - A `$ref` element of the specification is allowed to contain a name of file as it's part. Because of this, it is possible to split - - a single specification into multiple files as shown in [`cross_spec_references.yaml`](https://github.com/zalando/play-swagger-service/blob/master/conf/examples/cross_spec_references.yaml) - - example. It is also possible to reference a definition in one specification from another specification. - - In this case for each reference an independent copy of the class definition will be created for each referencing specification. - - The definition is then placed into the appropriate package for each specification. - - - Thus, even if multiple classes with the same name and structure might be generated, they all will coexist in their - - own separate namespaces and won't be interchangeable. - - - - ## Primitive Types - - - Swagger version 2.0 allows for primitive data types based on the types defined by - - [JSON-Schema](http://json-schema.org/latest/json-schema-core.html#anchor8). - - - When generated as Scala, the following mapping applies: - - - | Common Name | Swagger Type | Swagger Format | Scala Type | - - |-------------|--------------|----------------|---------------------------------------------| - - | integer | integer | int32 | scala.Int | - - | long | integer | int64 | scala.Long | - - | float | number | float | scala.Float | - - | double | number | double | scala.Double | - - | big int | integer | | scala.math.BigInt | - - | big decimal | number | | scala.math.BigDecimal | - - | boolean | boolean | | scala.Boolean | - - | string | string | | scala.String | - - | byte | string | byte | de.zalando.play.controllers.Base64String | - - | binary | string | binary | de.zalando.play.controllers.BinaryString | - - | date | string | date | org.joda.time.LocalDate | - - | datetime | string | date-time | org.joda.time.DateTime | - - | password | string | password | scala.String | - - | file | file | | java.io.File | - - - Additionally, if a validation of type "enum" is defined for some primitive type, a trait and a set of case objects forming an ADT - - will be generated for this enum. - - - ## Complex Types - - - Complex types are made up of primitive objects, or nested objects. - - - ### Objects - - - Complex object types are defined in Swagger model definitions as either objects or arrays. - - - Objects are, again, based on the [JSON-Schema](http://json-schema.org/latest/json-schema-core.html#anchor8) specification - - and defined as Swagger [Schema Objects](https://github.com/Swagger-api/Swagger-spec/blob/master/versions/2.0.md#schema-object) - - for parameter definitions of `type: "object"`. - - For example, given a Swagger API definition file `api.yaml` containing a model that defines a `person` as an object - - with the properties `name` and `age` of the primitive types `string` and `integer` subsequently, - - this object will be mapped on a Scala case class, and generated in a Scala package object (namespace) with the same name - - as the extension of the file the specification is read from and in a package with the same name as the - - Swagger definition file in which the model is defined—that is, `api` - - - ```yaml - - definitions: - person: - type: object - required: - - name - - age - properties: - name: - type: string - age: - type: integer - format: int32 - ``` - - - Is generated into: - - - ```scala - - package api - - package object yaml { - case class Person(name: String, age: Int) - } - - ``` - - - ### Nested Objects - - - Nested objects are generated adjourned but referenced hierarchically. E.g. - - - ```yaml - - definitions: - parent: - type: object - required: - - child - properties: - child: - type: object - required: - - name - properties: - name: - type: string - ``` - - - Is generated into: - - - ```scala - - package api - - package object yaml { - case class Parent(child: ParentChild) - case class ParentChild(name: String) - } - - - ``` - - - ### Optionality - - - Swagger, by default, defines object properties to be optional, which can be overridden by providing a list of `required` - - object properties as already used in the examples above. Optional properties are mapped upon Scala's `Option` type, - - for which a type alias is generated for each property that is optional. E.g. - - - ```yaml - - definitions: - product: - required: - - name - properties: - name: - type: string - tag: - type: string - ``` - - - Which is generated as: - - - ```scala - - package api - - package object yaml { - type ProductTag = Option[String] - case class Product(name: String, tag: ProductTag) - } - - - ``` - - - As objects can be nested, so can object property optionality. To facilitate for nested optionality, we generate a nested scala `Option` type alias. E.g. - - - ```yaml - - definitions: - Basic: - properties: - optional: - type: object - properties: - nested: - type: string - ``` - - - Which is generated as: - - - ```scala - - package api - - package object yaml { - type BasicOptional = Option[BasicOptionalOpt] - type BasicOptionalNested = Option[String] - - case class BasicOptionalOpt(nested: BasicOptionalNested) - case class Basic(optional: BasicOptional) - } - - ``` - - - - ### Parameter optionality - - - As object properties can be optional, so can be query, header, body or form parameters. - - In the case if they are not required, they are mapped to the Scala's `Option` type. - - - Path parameters are _must_ be declared as required. - - - In the case, if a parameter is _not_ required, it is allowed to have a default value. - - - - ### Extension - - - Objects can extend other objects via employment of Swagger's `allOff` property. In the example below, the `ExtendedErrorModel` inherits _all of_ the properties of the `ErrorModel` which it refers to—that is, the properties `message` and `code`—and _extends_ this model with the property `rootCause`. Swagger object extension is mapped by duplicating inherited properties in the object that extends. E.g. - - - ```yaml - - definitions: - ErrorModel: - type: object - required: - - message - - code - properties: - message: - type: string - code: - type: integer - ExtendedErrorModel: - allOf: - - $ref: '#/definitions/ErrorModel' - - type: object - required: - - rootCause - properties: - rootCause: - type: string - ``` - - - Which is generated as: - - - ```scala - - package api - - package object yaml { - import scala.math.BigInt - case class ErrorModel(message: String, code: BigInt) - case class ExtendedErrorModel(message: String, code: BigInt, rootCause: String) - } - - - ``` - - - ### Polymorphism - - - Polymorphic object definitions are possible through employment of the Swagger `discriminator` property. - - In the example definition below, an abstract `Pet` defines what concrete `Cat` and `Dog`s have in common. - - Swagger object models define data, so a discriminator property is required to distinguish concrete cat and dog - - instances as they are serialised to and from the API. In this sense, the discriminator property works - - in the same way as a discriminator column works in ORM frameworks when mapping a class hierarchy onto a single table. - - It simply contains a value that maps onto one of the concrete types—for example, `petType: "Cat"` or `petType: "Dog"`. - - - ```yaml - - definitions: - Pet: - discriminator: petType - properties: - name: - type: string - petType: - type: string - required: - - name - - petType - Cat: - allOf: - - $ref: '#/definitions/Pet' - - properties: - huntingSkill: - type: string - default: lazy - enum: - - clueless - - lazy - - adventurous - - aggressive - required: - - huntingSkill - Dog: - allOf: - - $ref: '#/definitions/Pet' - - properties: - packSize: - type: integer - format: int32 - required: - - packSize - ``` - - - Which is generated as: - - - ```scala - - package api - - - package object yaml { - - trait IPet { - def name: String - def petType: String - } - - case class Cat(name: String, petType: String, huntingSkill: CatHuntingSkill) extends IPet - case class Dog(name: String, petType: String, packSize: Int) extends IPet - case class Pet(name: String, petType: String) extends IPet - - sealed trait CatHuntingSkill { def value: String } - case object Clueless extends CatHuntingSkill { val value = "clueless" } - case object Lazy extends CatHuntingSkill { val value = "lazy" } - case object Adventurous extends CatHuntingSkill { val value = "adventurous" } - case object Aggressive extends CatHuntingSkill { val value = "aggressive" } - implicit def stringToCatHuntingSkill(in: String): CatHuntingSkill = in match { - case "clueless" => Clueless - case "lazy" => Lazy - case "adventurous" => Adventurous - case "aggressive" => Aggressive - } - } - - - ``` - - - Please note how the enumeration of cat's `huntingSkill`'s get's translated into the ADT with a sealed trait `CatHuntingSkill` - - and four case objects implementing that trait. - - - ### Additional Properties - - - Swagger's model language allows objects' additional properties to be loosely defined employing the `additionalProperties` annotation - - in order to model dictionaries. These dictionaries are mapped to Scala's `Map` type, for which a type alias is - - generated following the same (by now) well-known pattern as for optional properties, with the map's key parameter type being a Scala `String`. - - - A Swagger additional property definition takes as its type property the element type of the dictionary, - - which can be of primitive or complex type and which is mapped on Scala as the map's value parameter type. - - Swagger allows for one `additionalProperties` annotation per object definition, so we can generate this Scala parameter - - with the static name `additionalProperties`. - - - In the following example we define a Swagger model object definition `KeyedArray` that uses the `additionalProperties` - - annotation to provide the object with a set of key value mappings from string to array. E.g. - - - ```yaml - - definitions: - KeyedArrays: - type: object - additionalProperties: - type: array - items: - type: integer - ``` - - - Which is generated as: - - - ```scala - - package api - - - package object yaml { - - import de.zalando.play.controllers.ArrayWrapper - import scala.math.BigInt - import scala.collection.immutable.Map - - type KeyedArraysAdditionalPropertiesCatchAll = ArrayWrapper[BigInt] - type KeyedArraysAdditionalProperties = Map[String, KeyedArraysAdditionalPropertiesCatchAll] - case class KeyedArrays(additionalProperties: KeyedArraysAdditionalProperties) - } - - ``` - - - ## Arrays - - - Swagger's `array` is used to define properties that hold sets or lists of model values—possibly of a primitive type, - - but complex element types are also allowed. Depending on the place where the array definition appears, Swagger array can be mapped to one of two Scala types, parametrised for the element type that it contains: - - - if an array only defined inline as a part of the response definition, it is translated to a `Seq` type - - - otherwise (array appears in the parameter definition or in the `definitions` part of the specification) it is - - defined as a `de.zalando.play.controllers.ArrayWrapper` - - - For example, in the snippet below, an `Activity` object definition is referred to as an item element in the - - `messages` property of `type: array` of the containing object definition `Example`. - - A Scala type alias will be generated for the array type (just as we've seen before with optional properties), - - after which the array-containing property can be generated within the case class as being of this alias type. - - E.g. in the Swagger definition and code - - - ```yaml - - definitions: - Activity: - type: object - required: - - actions - properties: - actions: - type: string - Example: - type: object - required: - - messages - properties: - messages: - type: array - items: - $ref: '#/definitions/Activity' - ``` - - - Which is generated as: - - - ```scala - - package api - - - package object yaml { - - import de.zalando.play.controllers.ArrayWrapper - - type ExampleMessages = ArrayWrapper[Activity] - - case class Activity(actions: String) - case class Example(messages: ExampleMessages) - } - - - ``` - - - If the description of the same array is inlined as a part of the response definition like that: - - - ```yaml - - paths: - /api: - get: - responses: - 200: - schema: - type: object - required: - - messages - properties: - messages: - type: array - items: - $ref: '#/definitions/Activity' - description: array payload - definitions: - Activity: - type: object - required: - - actions - properties: - actions: - type: string - ``` - - - than the `Seq` scala type will be used: - - ```scala - - package api - - package object yaml { - type ApiGetResponses200Messages = Seq[Activity] - case class Activity(actions: String) - case class ApiGetResponses200(messages: ApiGetResponses200Messages) - } - - ``` - - - - ### Nested Arrays - - - Array definition types can be nested and are possibly optional. - - The following (contrived) snippet depicts the generated Scala code when both definition types are - - employed in a somewhat non-useful manner. The intent of this example is to show that the case - - class definitions are rather concisely generated, even though a stack of type aliases is needed - - to make sure that we still refer in Scala code to an aptly named Swagger definition—especially - - in conjunction with the object properties being optional. Next to its benefits, - - type safety against `null` pointers does have an associated cost as well. - - - ```yaml - - definitions: - Activity: - type: object - properties: - actions: - type: string - Example: - type: object - properties: - messages: - type: array - items: - type: array - items: - $ref: '#/definitions/Activity' - nested: - type: array - items: - type: array - items: - type: array - items: - type: array - items: - type: string - ``` - - - Which is generated as: - - - ```scala - - package api - - - package object yaml { - - import de.zalando.play.controllers.ArrayWrapper - - type ExampleMessagesOpt = ArrayWrapper[ExampleMessagesOptArr] - type ExampleMessages = Option[ExampleMessagesOpt] - type ExampleNested = Option[ExampleNestedOpt] - type ExampleMessagesOptArr = ArrayWrapper[Activity] - type ExampleNestedOptArrArrArr = ArrayWrapper[String] - type ExampleNestedOptArrArr = ArrayWrapper[ExampleNestedOptArrArrArr] - type ActivityActions = Option[String] - type ExampleNestedOptArr = ArrayWrapper[ExampleNestedOptArrArr] - type ExampleNestedOpt = ArrayWrapper[ExampleNestedOptArr] - - case class Activity(actions: ActivityActions) - case class Example(messages: ExampleMessages, nested: ExampleNested) - } - - - ``` - - - ## Swagger Validations - - - Swagger API definitions allow for constraints to be put on parameter types. - - We have already seen the `required` constraint, used to mark a parameter or specific field within - - a domain definition to be required upon input. Additional constraints, as defined by the - - [Parameter Object](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#parameterObject), - - can be added to your API definition. The Play-Swagger plugin will generate validations for these parameter - - constraints and make sure that your controller methods are only called if the input of your service - - complies to those constraints. - - - In the example below, the API definition of the `token` parameter of - - type `Base64String`, as the form parameter, contains validation rules for the lenght of the perameter as well as a regexp pattern the value of the parameter must confirm to. - - The parameter is also required. - - - ```yaml - - ... - - parameters: - - name: token - in: formData - description: oauth2 token - type: string - format: byte - pattern: "[A-Za-z0-9]*" - minLength: 5 - maxLength: 100 - required: true - ... - - ``` - - - Let's take another example: - - - ```yaml - - ... - get: - parameters: - - name: state - in: query - description: Any application state to be forwarded back to the frontend - type: string - minLength: 1 - maxLength: 110 - required: false - ... - - ``` - - - The `state` parameter is of type string, is not required and has no default value. - - It is also only allowed to have a state of length between 1 and 110, otherwise it won't pass validation. - - For the demo purposes, let's change it's type to `integer` and make it required. - - - As the parameter is required now, the `default` value cannot be present. The `maxLength` and `maxLength` validations - - are not allowed for integer parameters, therefore let's replace them with `minimum` and `maximum` values: - - ```yaml - - ... - get: - parameters: - - name: state - in: query - description: Any application state to be forwarded back to the frontend - type: integer - format: int32 - required: true - minimum: 2000 - maximum: 2100 - ... - - ``` - - - - As we just changed the parameter type, refreshing Swagger UI will, in addition to generating validations - - for that parameter type, also force a regeneration of the model consistent with the validation. - - That's nice, but note that it will break the current implementation of the controller class, as the - - implementation of the `postAction` expects `state` to be of type `String`. - - - ![Validation screenshot](/docs/validations-01.png) - - - Let's change the implementation. The second parameter `state` is no longer - - of type `Option[String]` but of type `Int`. We change the implementation to take this fact into the account: - - - ```scala - - ... - - val tokenGet = tokenGetAction { input: (String, String, String, Int) => - val (redirect_uri, scope, response_type, state) = input - // ----- Start of unmanaged code area for action TokenService.tokenGet - val statePart = s"""state=$state""" - ... - - } - - ``` - - - Refreshing Swagger UI and trying out a couple of integer values for `state` shows that the service - - now excepts value within the range `[2000..2100]`, but returns a descriptive error when outside. I.e. - - - ```json - - [ - { - "messages": [ - "error.max" - ], - "args": [ - 2100 - ] - } - ] - - ``` - - - ## Test Generators - - - Having an API definition as the single source of truth in your codebase—with formal type specification of the in- and output values, - - including their constraints—provides for a powerful feature when it comes to testing. - - The Play-Swagger plugin automates the creation of test data generators that can drive property checks directly - - from the API specification. Play-Swagger derives data generators and unit tests directly from your Swagger API specification. - - - Property-based testing using generator-driven property checks is a cool way to test the validity of your application - - according to the rules or properties that apply to your application. Properties, in this sense, are high-level - - specifications that should always hold for a range of data values. The idea is to generate a range of data - - values for your data types and let (also generated) tests assert that the properties of these data types hold. - - A Swagger API definition contains formal type definitions _and_ constraints for all data values, and the Play-Swagger - - plugin maps these types on managed Scala source code that represents the data types, so it is also possible to map - - these API definitions on test data generators that provide a range of data values for these types. - - The plugin does exactly that: It creates managed test data generators and unit tests that assert whether your - - application still complies to your specification. It does so in a single-source-of-truth manner, - - taking the Swagger API definition as the source. - - - We employ the ScalaTest [property-based testing](http://www.scalatest.org/user_guide/property_based_testing) - - functionality as the framework to generate the data values, and map the data types of our API definition on - - the test data generators that are created by the plugin. ScalaTest provides - - `org.scalacheck.Gen` and `org.scalacheck.Arbitrary` objects with utility methods that help generate a range of - - (possibly arbitrary) data values for common Scala types and primitives. The Play-Swagger plugin uses these - - methods to create test data generators specific for the data types of our API definition. When necessary, - - it composes generators from primitive types into generators for complex types, so that you end up with a - - set of generators that provide test data for your complete API. - - - As an example, let's take the API definition for the simple pet store—trimmed down to the parts defining - - parameter types, and (for brevity) omitting any non-data definitions and error definitions: - - - ```yaml - - paths: - /pets: - get: - parameters: - - name: limit - in: query - required: false - type: integer - format: int32 - responses: - default: - description: error payload - post: - parameters: - - name: pet - in: body - required: true - schema: - $ref: '#/definitions/newPet' - responses: - default: - description: error payload - /pets/{id}: - get: - parameters: - - name: id - in: path - required: true - type: integer - format: int64 - responses: - default: - description: error payload - delete: - parameters: - - name: id - in: path - required: true - type: integer - format: int64 - responses: - default: - description: error payload - definitions: - pet: - required: - - id - - name - properties: - id: - type: integer - format: int64 - name: - type: string - tag: - type: string - newPet: - required: - - name - properties: - id: - type: integer - format: int64 - name: - type: string - tag: - type: string - ``` - - - The `get` method on path `/pets` takes an optional `limit` parameter of common type `integer`. - - The `post` method takes a `newPet` body parameter comprising of the primitive attributes `id`, `name` and `tag`, - - subsequently of common types `long` and `string` (twice). Of these, only the `name` attribute is mandatory. - - The `get` method on the path `/pets/{id}` takes the path parameter `id` of common type `long` and returns - - an array of `pet`s consisting of the same attributes and primitive types as a `newPet` - but this time - - with both `name` and `id` being mandatory. This specification maps to the following managed Scala domain model code: - - - - ```scala - - package example - - - package object yaml { - - import de.zalando.play.controllers.PlayPathBindables - - type PetsIdDeleteResponsesDefault = Null - type NewPetTag = Option[String] - type PetsIdDeleteId = Long - type PetsGetLimit = Option[Int] - type NewPetId = Option[Long] - - case class Pet(id: Long, name: String, tag: NewPetTag) - case class NewPet(name: String, id: NewPetId, tag: NewPetTag) - - implicit val bindable_OptionIntQuery = PlayPathBindables.createOptionQueryBindable[Int] - } - - ``` - - - We want to have test data generators that generate an arbitrary range of values for the model - - code shown above - composed from primitive, and sometimes optional, data definitions. - - The Play-Swagger plugin does this by generating two Scala objects: one for the Swagger API definition, - - and one for the API path parts. Each object contains generator factory methods for the defined data types, - - prefixed by `create`, which returns a generator function. A generator function takes a given integer count - - and returns a generated amount of test data for the data type it was created for. - - - Data types are composed from primitive types, Scala optional types, and possibly more complex types. - - Test data values for the primitive types are generated arbitrarily, employing the ScalaCheck - - `org.scalacheck.Arbitrary.arbitrary[T]` method (the type parameter, replaced with Scala's primitive type, - - on which the Swagger common type is mapped). - - - In the code shown below, starting with primitive leaf data values, the `pet` parameter's attribute `id` - - of common type `long` is arbitrarily generated from a `scala.Long`. Note that the `id` attribute is optional, - - though, for the `newPet` definition. As with the generated model, we created a `NewPetIdGenerator` value that - - takes an arbitrarily generated `scala.Long` id value and generates an option value from it, employing the - - ScalaCheck `org.scalacheck.Gen.option[T]`. This generator will generate test data values comprising of `None` - - and `Some` arbitrarily id value. It's probably best to let the Scala generator code speak for itself. - - Note how it composes according to the same structure as the Scala model code. - - - ```scala - - package example.yaml - - - import org.scalacheck.Gen - - import org.scalacheck.Arbitrary - - import play.api.libs.json.scalacheck.JsValueGenerators - - import Arbitrary._ - - - object Generators extends JsValueGenerators { - - def createNullGenerator = _generate(NullGenerator) - def createNewPetTagGenerator = _generate(NewPetTagGenerator) - def createLongGenerator = _generate(LongGenerator) - def createPetsGetLimitGenerator = _generate(PetsGetLimitGenerator) - def createNewPetIdGenerator = _generate(NewPetIdGenerator) - - def createPetGenerator = _generate(PetGenerator) - def createNewPetGenerator = _generate(NewPetGenerator) - - def NullGenerator = arbitrary[Null] - def NewPetTagGenerator = Gen.option(arbitrary[String]) - def LongGenerator = arbitrary[Long] - def PetsGetLimitGenerator = Gen.option(arbitrary[Int]) - def NewPetIdGenerator = Gen.option(arbitrary[Long]) - - def PetGenerator = for { - id <- arbitrary[Long] - name <- arbitrary[String] - tag <- NewPetTagGenerator - } yield Pet(id, name, tag) - def NewPetGenerator = for { - name <- arbitrary[String] - id <- NewPetIdGenerator - tag <- NewPetTagGenerator - } yield NewPet(name, id, tag) - - def _generate[T](gen: Gen[T]) = (count: Int) => for (i <- 1 to count) yield gen.sample - } - - ``` - - - A `PetGenerator` and `NewPetGenerator` are created and implemented by the plugin as a for comprehension - - that generates data values for each attribute, yielding an instance of a test pet. Other generators follow - - the same pattern but, if necessary, delegate to different child generators. From this we acquire a set of - - test data generators to implement our property-based testing. - - - Running the test is as simple as running a test set from sbt. Just type `test` from your `sbt` prompt. - - - # Building a Play-Swagger Plugin - - - To build a plugin, do the following: - - - - Clone the repository to your local filesystem - - - Run ```sbt +publishLocal``` in the Play-Swagger directory. This will publish the plugin into your local ivy repository - - - To use the plugin in a plain Play project: - - - - Create a new Play-Swagger project using activator template, for example: ```activator new hello-world play-swagger-service``` - - - Take a look at the `project/plugins.sbt` of the generated project and add required plugins and resolvers to the `project/plugins.sbt` of your Play project - - - Do the same for `build.sbt` - - - Put a Swagger specification with a ```.yaml``` or ```.json``` extension into the ```conf``` directory - - - Add a specification link (`->`) to the play's routes file - - - - ## Plugin Architecture - - - Ths Play-Swagger plugin has a three-tier architecture: - - - * specification - this tier is responsible for finding and parsing a specification and converting it into the raw AST format - - * normalisation - this tier performs a couple of optimisations on the AST including type deduplication, flattening and parameter dereferencing - - * generation - a final step including transformation of the AST into the source-code related data and generation of source code from it - - - The separation of the specification and generation tiers allows for plugging in different specification standards - - and generating source code for different frameworks. - - - - ## Plugin Project Structure - - - There are a couple of sub-projects: - - - * `swagger-model` - A standalone Scala Swagger model and a Jackson parser for it. Can be used by another projects - - * `api` - This is the project that's automatically added to the runtime classpath of any projects that use this plugin. - - * `swagger-parser` - A converter of the Swagger model to the internal AST of the plugin - - * `api-first-core` - This is a core of the plugin with minimal functionality. It includes defining an AST structure and some transformations on AST. - - * `play-scala-generator` - The standalone generator for transforming an AST into the skeleton of Play-Scala application. - - * `plugin` - A coupble of sbt plugins, one for each tier: - - `ApiFirstSwaggerParser` - a plugin wrapping Swagger parsing part - - `ApiFirstCore` - a wrapper for AST-related functionality - - `ApiFirstPlayScalaCodeGenerator` - a wrapper for the Play-Scala generator - - Because of the modular plugin architecture, all modules must be enabled separatly in sbt's build.sbt. - - It is also necessary to configure which parser(s) must be used by the plugin, like that: - - - ```scala - - lazy val root = (project in file(".")).enablePlugins(PlayScala, ApiFirstCore, ApiFirstPlayScalaCodeGenerator, ApiFirstSwaggerParser) - - - apiFirstParsers := Seq(ApiFirstSwaggerParser.swaggerSpec2Ast.value).flatten - - ``` - - - Please take a look at activator template's configuration for complete example. - - - - ## Custom Templates For Code Generation - - - The PlayScala generator supports custom templates. In order to override default template for some of the components, - - please provide your custom template named in accordance to the following list: - - * `play_scala_test.mustache` - for unit tests - * `play_validation.mustache` - for validators - * `generators.mustache` - for test data generators - * `model.mustache` - for model classes and query and path bindables - * `play_scala_controller_base.mustache` - for play controller bases - * `play_scala_controller_security.mustache` - for security adapters used by controller bases - * `play_scala_form_parser.mustache` - for form parsers used by the controller bases - * `play_scala_controller.mustache` - for play controller skeletons supposed to be augmented by the programmer - * `play_scala_response_writers.mustache` - for custom serializers to be augmented by the programmer - * `play_scala_security_extractors.mustache` - for custom security extractors to be augmented by the programmer - - - Please be aware that generated artifacts need to preserve some specific shape in order to be compiled together without errors. - - - The location where custom templates reside needs to be configured by overriding the plugin setting `playScalaCustomTemplateLocation`. - - - For example following configuration will set this place to be `conf/templates` folder of the project: - - ```scala - - playScalaCustomTemplateLocation := Some(((resourceDirectory in Compile) / "templates").value) - - ``` - - - - ## Plugin Developing - - - sbt doesn't allow sub-projects to depend on each other as sbt plugins. To test an sbt plugin, you need a separate - - project. This project is `swagger-tester`. To test your changes as you're developing the plugin, cd into this - - directory, and run sbt. This project uses an sbt `ProjectRef` to the sbt plugin, which means you don't need to - - `publishLocal` the plugin after each change. Just run `reload` in the sbt console, and it will pick up your changes. - - - The play-swagger plugin provides a couple of commands useful for development: - - - * `apiFirstPrintDenotations` - outputs a common names of different parts of the AST as they are intended to be used in generated Scala code - - * `apiFirstPrintRawAstTypes` - outputs all type definitions as they read from the specification before type optimisations - - * `apiFirstPrintRawAstParameters` - outputs all parameters definitions before type optimisations - - * `apiFirstPrintFlatAstTypes` - outputs type definitions after type optimisations - - * `apiFirstPrintFlatAstParameters` - outputs parameter definitions after type optimisations - - - - ## Plugin Testing - - - We're using the sbt scripted framework for testing. You can find the tests in `plugin/src/sbt-test`, and run them - - by running `scripted` in the sbt console. - - - - ## Code quality - - - There are some quality checks embedded into the build script: - - * the source code is (re)formatted using [scalariform](https://github.com/scala-ide/scalariform) each time it is compiled (currently deactivated). - - * [`scalastyle`](http://www.scalastyle.org) sbt command shall be used to perform code style checks before putting changes into the repository. - - * [`lint:compile`](https://github.com/HairyFotr/linter) sbt command shall be used to perform static code analysis before putting changes into the repository. - - * code coverage for api and compiler modules can be executed by issuing `sbt clean coverage test` command for these - - projects. Coverage statistics can be generated using `coverageReport` sbt command. -casualjim/go-swagger: > - # Swagger 2.0 [![Build - Status](https://circleci.com/gh/go-swagger/go-swagger.svg?style=shield)](https://circleci.com/gh/go-swagger/go-swagger) - [![Build - status](https://ci.appveyor.com/api/projects/status/x377t5o9ennm847o/branch/master?svg=true)](https://ci.appveyor.com/project/casualjim/go-swagger/branch/master) - [![codecov](https://codecov.io/gh/go-swagger/go-swagger/branch/master/graph/badge.svg)](https://codecov.io/gh/go-swagger/go-swagger) - [![GitHub - version](https://badge.fury.io/gh/go-swagger%2Fgo-swagger.svg)](https://badge.fury.io/gh/go-swagger%2Fgo-swagger) - - [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) - - [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/swagger-api/swagger-spec/master/LICENSE) - - [![GoDoc](https://godoc.org/github.com/go-swagger/go-swagger?status.svg)](http://godoc.org/github.com/go-swagger/go-swagger) - - [![Docker Repository on Quay](https://quay.io/repository/goswagger/swagger/status "Docker Repository on Quay")](https://quay.io/repository/goswagger/swagger) - - [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fgo-swagger%2Fgo-swagger.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fgo-swagger%2Fgo-swagger?ref=badge_shield) - - [![GolangCI](https://golangci.com/badges/github.com/go-swagger/go-swagger.svg)](https://golangci.com) - - [![Go Report Card](https://goreportcard.com/badge/github.com/go-swagger/go-swagger)](https://goreportcard.com/report/github.com/go-swagger/go-swagger) - - - This package contains a golang implementation of Swagger 2.0 (aka [OpenAPI 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md)): - - it knows how to serialize and deserialize swagger specifications. - - - [Swagger](https://swagger.io/) is a simple yet powerful representation of your RESTful API.
- - - > ![swagger](https://raw.githubusercontent.com/go-swagger/go-swagger/master/docs/favicon-16x16.png) **Swagger in a nutshell** - - > - - > With the largest ecosystem of API tooling on the planet, thousands of developers are supporting Swagger in almost every modern programming language and deployment environment. - - > - - > With a Swagger-enabled API, you get interactive documentation, client SDK generation and discoverability. We created Swagger to help fulfill the promise of APIs. - - > - - > Swagger helps companies like Apigee, Getty Images, Intuit, LivingSocial, McKesson, Microsoft, Morningstar, and PayPal build the best possible services with RESTful APIs. Now in version 2.0, Swagger is more enabling than ever. And it's 100% open source software. - - - ## Features - - `go-swagger` brings to the go community a complete suite of fully-featured, high-performance, API components to work with a Swagger API: server, client and data model. - - - * Generates a server from a swagger specification - - * Generates a client from a swagger specification - - * Supports most features offered by jsonschema and swagger, including polymorphism - - * Generates a swagger specification from annotated go code - - * Additional tools to work with a swagger spec - - * Great customization features, with vendor extensions and customizable templates - - - Our focus with code generation is to produce idiomatic, fast go code, which plays nice with golint, go vet etc. - - - ## Project status - - `go-swagger` is now feature complete and has stabilized its API. - - - Most features and building blocks are now in a stable state, with a rich set of CI tests. - - - The go-openapi community actively continues bringing fixes and enhancements to this code base. - - - There is still much room for improvement: contributors and PR's are welcome. You may also get in touch with maintainers on [our slack channel](https://slackin.goswagger.io). - - - ## Documentation - - - - - ## FAQ - - Q&A contributed by the community: - - - - - - ## How is this different from go generator in swagger-codegen? - - **tl;dr** The main difference at this moment is that this one actually works... - - - The swagger-codegen project only generates a _workable_ go client and even there it will only support flat models. - - Further, the go server generated by swagger-codegen is mostly a stub. - - - > **Motivation** - - > Why is this not done as a part of the swagger-codegen project? Because: - - > - - > * I don't really know java very well and so I'd be learning both java and the object model of the codegen which was in heavy flux as opposed to doing go and I really wanted to go experience of designing a large codebase with it. - - > * Go's super limited type system makes it so that it doesn't fit well in the model of swagger-codegen - - > * Go's idea of polymorphism doesn't reconcile very well with a solution designed for languages that actually have inheritance and so forth. - - > * For supporting types like `[][][]map[string][][]int64` I don't think it's possible with mustache - - > - - > I gravely underestimated the amount of work that would be involved in making something useful out of it. - - > My personal mission: I want the jvm to go away, it was great way back when now it's just silly (vm in container on vm in vm in container) - - - ## What's inside? - - - Here is an outline of available features (see the full list [here](https://goswagger.io/features.html)): - - - - An object model that serializes swagger-compliant yaml or json - - - A tool to work with swagger - - Serve swagger UI for any swagger spec file - - Flexible code generation, with customizable templates - - Generate go API server based on swagger spec - - Generate go API client from a swagger spec - - Validate a swagger spec document, with extra rules outlined [here](https://github.com/apigee-127/sway/blob/master/docs/README.md#semantic-validation) - - Generate a spec document based on annotated code - - A runtime to work with Rest API and middlewares - - Serve spec - - Routing - - Validation - - Authorization - - Swagger docs UI - - A Diff tool which will cause a build to fail if a change in the spec breaks backwards compatibility - - There is more to that... - - - - A [typed JSON Schema implementation](https://goswagger.io/use/model.html), supporting most Draft 4 features - - - Extended string and numeric formats: [strfmt](https://github.com/go-openapi/strfmt) - - - Utilities to work with JSON, convert data types and pointers: [swag](https://github.com/go-openapi/swag) - - - A jsonschema (Draft 4) validator, with full $ref support: [validate](https://github.com/go-openapi/validate) - - - Custom validation interface - - - ## Installing - - `go-swagger` is available as binary or docker releases as well as from source: [more details](https://goswagger.io/install.html). - - - ## Use-cases - - The main package of the toolkit, go-swagger/go-swagger, provides command line tools to help working with swagger. - - - The toolkit is highly customizable and allows endless possibilities to work with OpenAPI2.0 specifications. - - - Beside the go-swagger CLI tool and generator, the [go-openapi packages](https://github.com/go-openapi) provide modular functionality to build custom solutions on top of OpenAPI. - - - The CLI supports shell autocompletion utilities: see [here](https://goswagger.io/cli_helpers.html). - - - ### Serve specification UI - - Most basic use-case: serve a UI for your spec: - - - ``` - - swagger serve https://raw.githubusercontent.com/swagger-api/swagger-spec/master/examples/v2.0/json/petstore-expanded.json - - ``` - - - ### Validate a specification - - To [validate](https://goswagger.io/usage/validate.html) a Swagger specification: - - - ``` - - swagger validate https://raw.githubusercontent.com/swagger-api/swagger-spec/master/examples/v2.0/json/petstore-expanded.json - - ``` - - - ### Generate an API server - - To generate a [server for a swagger spec](https://goswagger.io/generate/server.html) document: - - - ``` - - swagger generate server [-f ./swagger.json] -A [application-name [--principal [principal-name]] - - ``` - - - ### Generate an API client - - To generate a [client for a swagger spec](https://goswagger.io/generate/client.html) document: - - - ``` - - swagger generate client [-f ./swagger.json] -A [application-name [--principal [principal-name]] - - ``` - - - ### Generate a spec from source - - To generate a [swagger spec document for a go application](https://goswagger.io/generate/spec.html): - - - ``` - - swagger generate spec -o ./swagger.json - - ``` - - - ### Generate a data model - - To generate model structures and validators exposed by the API: - - - ``` - - swagger generate model --spec={spec} - - ``` - - - ### Transform specs - - - There are [several commands](https://goswagger.io/use/transform.html) allowing you to transform your spec. - - - Resolve and expand $ref's in your spec as inline definitions: - - ``` - - swagger expand {spec} - - ``` - - - Flatten your spec: all external $ref's are imported into the main document and inline schemas reorganized as definitions. - - ``` - - swagger flatten {spec} - - ``` - - - Merge specifications (composition): - - ``` - - swagger mixin {spec1} {spec2} - - ``` - - - ### Compare specs - - - The diff command allows you to check backwards compatibility. - - Type ```swagger diff --help``` for info. - - - ``` - - swagger diff {spec1} {spec2} - - ``` - - - ## Try it - - - Try `go-swagger` in a free online workspace using Gitpod: - - - [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io#https://github.com/go-swagger/go-swagger) - - - ## Licensing - - - The toolkit itself is licensed as Apache Software License 2.0. Just like swagger, this does not cover code generated by the toolkit. That code is entirely yours to license however you see fit. - - - - [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fgo-swagger%2Fgo-swagger.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fgo-swagger%2Fgo-swagger?ref=badge_large) - - - ## Who is using this project? - - - To name but a few... (feel free to sign in there if you are using this project): - - - > In the list below, we tried to figure out the public repos where you'll find examples on how to use `go-swagger` and `go-openapi`: - - - [3DSIM](https://github.com/3DSIM) - - [Alibaba PouchAPI](https://github.com/alibaba/pouch) - - [CheckR](https://github.com/checkr/flagr) - - [Cilium](https://github.com/cilium/cilium) - - [CoreOS](https://github.com/coreos/go-quay) - - [NetBox Community](https://github.com/netbox-community/go-netbox) - - [EVE Central](https://github.com/evecentral) - - Iron.io - - [JaegerTracing](https://github.com/jaegertracing/jaeger) - - [Kubernetes-Helm](https://github.com/kubernetes-helm/monocular) - - [Kubernetes](https://godoc.org/k8s.io/apiextensions-apiserver/pkg/apiserver) - - [ManifoldCo](https://github.com/manifoldco) - - [Metaparticle.io](https://github.com/metaparticle-io/metaparticle-ast) - - [Netlify](https://github.com/netlify/open-api) - - [Nutanix](https://github.com/nutanix) - - [OAS2](https://github.com/hypnoglow/oas2) - - [OVH API](https://github.com/appscode/go-ovh) - - [RackHD](https://github.com/RackHD/RackHD) - - [ScaleFT](https://github.com/authclub/billforward) - - [StratoScale](https://github.com/Stratoscale/swagger) - - [Terraform Provider OpenAPI](https://github.com/dikhan/terraform-provider-openapi) - - [VMWare](https://github.com/vmware/dispatch) - - ... - - - ## Note to users migrating from older releases - - - ### Using 0.5.0 - - - Because 0.5.0 and master have diverged significantly, you should checkout the tag 0.5.0 for go-swagger when you use the currently released version. - - - ### Migrating from 0.5.0 to 0.6.0 - - - You will have to rename some imports: - - - ``` - - github.com/go-swagger/go-swagger/httpkit/validate to github.com/go-openapi/validate - - github.com/go-swagger/go-swagger/httpkit to github.com/go-openapi/runtime - - github.com/naoina/denco to github.com/go-openapi/runtime/middleware/denco - - github.com/go-swagger/go-swagger to github.com/go-openapi - - ``` - - - ### Migrating from 0.12 to 0.13 - - - Spec flattening and $ref resolution brought breaking changes in model generation, since all complex things generate their own definitions. - - - ### Migrating from 0.14 to 0.15 - - - Generated servers no more import the following package (replaced by go1.8 native functionality): - - ``` - - github.com/tylerb/graceful - - ``` - - - Spec flattening now defaults to minimal changes to models and should be workable for 0.12 users. - - - Users who prefer to stick to 0.13 and 0.14 default flattening mode may now use the `--with-flatten=full` option. - - - Note that the `--skip-flatten` option has been phased out and replaced by the more explicit `--with-expand` option. -krakenjs/swaggerize-hapi: > - # hapi-openapi - - - [![Build Status](https://travis-ci.org/krakenjs/hapi-openapi.svg?branch=master)](https://travis-ci.org/krakenjs/hapi-openapi) - - [![NPM version](https://badge.fury.io/js/hapi-openapi.png)](http://badge.fury.io/js/hapi-openapi) - - - ### Note: this project was renamed from 'swaggerize-hapi' to 'hapi-openapi'. - - - `hapi-openapi` is a design-driven approach to building RESTful services with [OpenAPI (Swagger)](http://openapis.org) and [Hapi](http://hapijs.com) (OpenAPI 3.0 support coming soon). - - - `hapi-openapi` provides the following features: - - - - API schema validation. - - - Routes based on the OpenAPI document. - - - API documentation route. - - - Input validation. - - - ### Why "Design Driven" - - - There are already a number of modules that help build RESTful APIs for node with OpenAPI. However, - - these modules tend to focus on building the documentation or specification as a side effect of writing - - the application business logic. - - - `hapi-openapi` begins with the OpenAPI document first. This facilitates writing APIs that are easier to design, review, and test. - - - At runtime, `hapi-openapi` uses the API specification to build routes from previously defined paths. This ensures that everything specified is what is implemented. - - - ### Quick Start with a Generator - - - This guide will let you go from an `api.json` to a service project in no time flat. - - - First install `generator-swaggerize` (and `yo` if you haven't already): - - - ```bash - - $ npm install -g yo - - $ npm install -g generator-swaggerize - - ``` - - - Now run the generator. - - - ```bash - - $ mkdir petstore && cd $_ - - $ yo swaggerize - - ``` - - - Follow the prompts (note: make sure to choose `hapi` as your framework choice). - - - You now have a working api and can use something like [SwaggerHub](https://swaggerhub.com/?_ga=2.118604234.2143392684.1515431456-1673703125.1481054263) to explore it. - - - ### Manual Usage - - - ```javascript - - const Hapi = require('@hapi/hapi'); - - - const server = new Hapi.Server(); - - - await server.register({ - plugin: require('hapi-openapi'), - options: { - api: Path.join(__dirname, './config/pets.json'), - handlers: Path.join(__dirname, './handlers') - } - }); - - ``` - - - ### Hapi Plugin - - - The plugin will be registered as `openapi` on `server.plugins` with the following exposed: - - - - `getApi()` - the resolved Swagger document. - - - `setHost(host)` - a helper function for setting the `host` property on the `api`. - - - ### Configuration Options - - - - `api` - a path to a valid OpenAPI 2.0 document, or a valid document in the form of an object. - - - *deprecated* `docspath` - the path to expose api docs for swagger-ui, etc. Defaults to `/api-docs`. - - - `docs` - an object used to configure the api docs route. - - `path` - the path to expose api docs for swagger-ui, etc. Defaults to `/api-docs`. - - `auth` - options auth config for this route. - - `stripExtensions` - strip vendor extensions from docs. Defaults to true. - - `prefixBasePath` - prefix path of docs with he OpenAPI document's `basePath` value. Defaults to true. - - `handlers` - either a string directory structure for route handlers, object, or not set if using `x-hapi-handler`. - - - `extensions` - an array of file extension types to use when scanning for handlers. Defaults to `['js']`. - - - `vhost` - *optional* domain string (see [hapi route options](http://hapijs.com/api#route-options)). - - - `cors` - *optional* cors setting (see [hapi route options](http://hapijs.com/api#route-options)). - - - `outputvalidation` - *optional* validate response data. - - - ### Mount Path - - - Api `path` values will be prefixed with the OpenAPI document's `basePath` value. This behavior can be negated if you set the option `docs.prefixBasePath` to `false`. - - - ### Handlers Directory - - - The `options.handlers` option specifies a directory to scan for handlers. These handlers are bound to the api `paths` defined in the OpenAPI document. - - - ``` - - handlers - |--foo - | |--bar.js - |--foo.js - |--baz.js - ``` - - - Will route as: - - - ``` - - foo.js => /foo - - foo/bar.js => /foo/bar - - baz.js => /baz - - ``` - - - ### Path Parameters - - - The file and directory names in the handlers directory can also represent path parameters. - - - For example, to represent the path `/users/{id}`: - - - ```shell - - handlers - |--users - | |--{id}.js - ``` - - - This works with directory names as well: - - - ```shell - - handlers - |--users - | |--{id}.js - | |--{id} - | |--foo.js - ``` - - - To represent `/users/{id}/foo`. - - - ### Handlers File - - - Each provided javascript file should export an object containing functions with HTTP verbs as keys. - - - Example: - - - ```javascript - - module.exports = { - get: function (req, h) { ... }, - put: function (req, h) { ... }, - ... - } - - ``` - - - Optionally, `pre` handlers can be used by providing an array of handlers for a method: - - - ```javascript - - module.exports = { - get: [ - function p1(req, h) { ... }, - function handler(req, h) { ... } - ], - } - - ``` - - - ### Handlers Object - - - The directory generation will yield this object, but it can be provided directly as `options.handlers`. - - - Example: - - - ```javascript - - { - 'foo': { - 'get': function (req, h) { ... }, - 'bar': { - 'get': function (req, h) { ... }, - 'post': function (req, h) { ... } - } - } - ... - } - - ``` - - - ### X-Hapi-Handler - - - Alternatively the API document can set `x-hapi-handler` attribute on each defined `paths` element if `handlers` is not defined. - - - Example: - - - ``` - - "/pets/{id}": { - "x-hapi-handler": "./routes/pets-by-id.js", - . - . - . - ``` - - - This will construct a `handlers` object from the given `x-hapi-handler` files. - - - ### X-Hapi-Options - - - There is now support at the operations level for `x-hapi-options` which represent individual [Hapi Route Optijons](https://github.com/hapijs/hapi/blob/master/API.md#route-options). - - - This support is limited to configuration supported by the JSON file type. - - - Example: - - - ``` - - "/internal": { - "post": { - "x-hapi-options": { - "isInternal": true - } - . - . - . - ``` - - - ### Authentication - - - Support for OpenAPI [security schemes](http://swagger.io/specification/#securitySchemeObject) requires that relevant authentication scheme and strategy are registered before the hapi-openapi plugin. See the [hapi docs](http://hapijs.com/tutorials/auth) for information about authentication schemes and strategies. - - - The name of the hapi authentication strategy is expected to match the name field of the OpenAPI [security requirement object](http://swagger.io/specification/#securityRequirementObject). - - - Example: - - - ```yaml - - securityDefinitions: - api_key: - type: apiKey - name: Authorization - in: header - paths: - '/users/': - get: - security: - - api_key: [] - ``` - - - ```javascript - - const server = new Hapi.Server(); - - - await server.register({ plugin: AuthTokenScheme }); - - - server.auth.strategy('api_key', 'auth-token-scheme', { - validateFunc: async function (token) { - // Implement validation here, return { credentials, artifacts }. - } - }); - - - await server.register({ - plugin: require('hapi-openapi'), - options: { - api: require('./config/pets.json'), - handlers: Path.join(__dirname, './handlers') - } - }); - - ``` - - - ### X-Hapi-Auth - - - Alternatively it may be easier to automatically register a plugin to handle registering the necessary schemes and strategies. - - - **x-hapi-auth-schemes** - - - The root document can contain an `x-hapi-auth-schemes` object specifying different plugins responsible for registering auth schemes. - - - Example: - - - ``` - - "x-hapi-auth-schemes": { - "apiKey": "../lib/xauth-scheme.js" - } - - ``` - - - This plugin will be passed the following options: - - - - `name` - the auth scheme name, in this example `apiKey`. - - - **x-hapi-auth-strategy** - - - The `securityDefinitions` entries can contain an `x-hapi-auth-strategy` attribute pointing to a plugin responsible for registering auth strategies. - - - Example: - - - ``` - - "securityDefinitions": { - "api_key": { - "x-hapi-auth-strategy": "../lib/xauth-strategy.js", - "type": "apiKey", - "name": "authorization", - "in": "header" - } - } - - ``` - - - The plugin will be passed the following options: - - - - `name` - the `securityDefinitions` entry's key. In this example, `api_key`. This is typically used as the strategy name. - - - `scheme` - the `securityDefinitions` `type`. In this example, `apiKey`. This should match a `x-hapi-auth-scheme` name. - - - `where` - `securityDefinitions` entry `in` attribute. This is search for the `lookup` value; in this example `header`. - - - `lookup` - `securityDefinitions` entry `name` attribute. Used as the name to look up against `where`. - - - The way you can make these play together is that for every `type`, a scheme exists that delegates some lookup or evaluation to the appropriate strategy. - - - Example: - - - ```javascript - - //xauth-scheme.js - - - const register = function (server, { name }) { - server.auth.scheme(name /*apiKey*/, (server, /* options received from the strategy */ { validate }) => { - return { - authenticate: async function (request, h) { - return h.authenticated(await validate(request)); - } - }; - }); - }; - - - module.exports = { register, name: 'x-hapi-auth-scheme' }; - - ``` - - - and - - - ```javascript - - //xauth-strategy.js - - - const Boom = require('@hapi/boom'); - - - const register = function (server, { name, scheme, where, lookup }) { - server.auth.strategy(name, /* the scheme to use this strategy with */ scheme, { - //Define a validate function for the scheme above to receive - validate: async function (request) { - const token = request.headers[lookup]; - - //Some arbitrary example - if (token === '12345') { - return { credentials: { scope: ['read'] }, artifacts: { token } }; - } - - throw Boom.unauthorized(); - } - }); - }; - - - module.exports = { register, name: 'x-hapi-auth-strategy' }; - - ``` -AntXlab/pyswagger: >+ - pyswagger - - ========= - - - [![Build Status](https://travis-ci.org/mission-liao/pyswagger.svg?branch=master)](https://travis-ci.org/mission-liao/pyswagger) - - [![Coverage Status](https://coveralls.io/repos/mission-liao/pyswagger/badge.svg?branch=master&style=flat)](https://coveralls.io/r/mission-liao/pyswagger?branch=master) - - - A python client for [Swagger](https://helloreverb.com/developers/swagger) enabled REST API. It wouldn't be easier to - - try Swagger REST API by [Swagger-UI](https://github.com/wordnik/swagger-ui). However, when it's time to **unittest** - - your API, the first option you find would be [Swagger-codegen](https://github.com/wordnik/swagger-codegen), but the better option is us. - - - This project is developed after [swagger-py](https://github.com/digium/swagger-py), which is a nicely implemented one, and inspired many aspects of this project. Another project is [flex](https://github.com/pipermerriam/flex), which focuses on parameter validation, try it if you can handle other parts by yourselves. For other projects related to Swagger tools in python, check [here](https://github.com/swagger-api/swagger-spec#python). - - - **pyswagger** is much easier to use (compared to swagger-codegen, you don't need to prepare a scala environment) and tries hard to **fully supports** [Swagger Spec](https://helloreverb.com/developers/swagger) in all aspects. - - - - [NEWs: upcoming support for OpenAPI 3.0](docs/md/news.md) - - - [Features](README.md#features) - - - [Tutorial](README.md#tutorial) - - - [Quick Start](README.md#quick-start) - - - [Installation](README.md#installation) - - - [Reference](README.md#reference) - - - [Contributors](README.md#contributors) - - - [Contribution Guideline](README.md#contribution-guildeline) - - - [FAQ](docs/md/faq.md) - - - [Changes](CHANGES.md) - - - --------- - - - ## Features - - - convert Swagger Document from older version to newer one. (ex. convert from 1.2 to 2.0) - - - support Swagger **1.2**, **2.0** on python ~~2.6~~, **2.7**, **3.3**, **3.5**, **3.6** - - - support YAML via [Pretty-YAML](https://github.com/mk-fg/pretty-yaml) - - - support $ref to **External Document**, multiple swagger.json will be organized into a group of App. And external document with self-describing resource is also supported (refer to [issue](https://github.com/swagger-api/swagger-spec/issues/219)). - - - type safe, input/output are converted to python types according to [Data Type](https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#43-data-types) described in Swagger. You don't need to touch any json schema when using pyswagger. Limitations like **minimum/maximum** or **enum** are also checked. **Model inheritance** also supported. - - - provide function **App.validate** to check validity of the loaded API definition according to spec. - - - builtin client implementation based on various http clients in python. For usage of these clients, please refer to `pyswagger.tests.contrib.client` for details - - [requests](https://github.com/kennethreitz/requests) - - [tornado.httpclient.AsyncHTTPClient](http://tornado.readthedocs.org/en/latest/httpclient.html) - - [flask.testing.FlaskClient](http://flask.pocoo.org/docs/0.10/api/#flask.testing.FlaskClient) - - [webapp2](http://webapp2.readthedocs.io/en/latest/guide/testing.html) - - not implemented parts, fire me a bug if you need it - - [ ] Swagger 2.0 - - [ ] Schema.pattern - - [ ] Scheme.patternProperties - - [ ] Schema.readonly - - [ ] Schema.allowEmptyValue - - [ ] A scanner to validate schema - - [ ] A WebSocket client - - [ ] dump extension field - - --------- - - - ## Tutorial - - - - [Initialization](docs/md/tutorial/init.md) - - - [Making a Request](docs/md/tutorial/request.md) - - - [Access the Response](docs/md/tutorial/response.md) - - - [Testing a Local Server](docs/md/tutorial/local.md) - - - [Converting Document into another version](docs/md/tutorial/converter.md) - - - [Exntending Primitive Factory for user-defined primitives](docs/md/tutorial/extend_prim.md) - - - [Rendering Random Requests for BlackBox Testing](docs/md/tutorial/render.md) - - - [Operation MIME Support](docs/md/tutorial/mime.md) - - - [Test with Invalid Input](docs/md/tutorial/invalid.md) - - - [Load Spec from a Restricted Service](docs/md/tutorial/restricted_service.md) - - - [Customized Headers](docs/md/tutorial/customized_headers.md) - - - --------- - - - ## Quick Start - - - Before running this script, please make sure [requests](https://github.com/kennethreitz/requests) is installed on your environment. - - - ```python - - from pyswagger import App, Security - - from pyswagger.contrib.client.requests import Client - - from pyswagger.utils import jp_compose - - - # load Swagger resource file into App object - - app = App._create_('http://petstore.swagger.io/v2/swagger.json') - - - auth = Security(app) - - auth.update_with('api_key', '12312312312312312313q') # api key - - auth.update_with('petstore_auth', '12334546556521123fsfss') # oauth2 - - - # init swagger client - - client = Client(auth) - - - # a dict is enough for representing a Model in Swagger - - pet_Tom=dict(id=1, name='Tom', photoUrls=['http://test']) - - # a request to create a new pet - - client.request(app.op['addPet'](body=pet_Tom)) - - - # - access an Operation object via App.op when operationId is defined - - # - a request to get the pet back - - req, resp = app.op['getPetById'](petId=1) - - # prefer json as response - - req.produce('application/json') - - pet = client.request((req, resp)).data - - assert pet.id == 1 - - assert pet.name == 'Tom' - - - # new ways to get Operation object corresponding to 'getPetById'. - - # 'jp_compose' stands for JSON-Pointer composition - - req, resp = app.resolve(jp_compose('/pet/{petId}', base='#/paths')).get(petId=1) - - req.produce('application/json') - - pet = client.request((req, resp)).data - - assert pet.id == 1 - - ``` - - - --------- - - - ## Installation - - We support pip installtion. - - ```bash - - pip install pyswagger - - ``` - - - Additional dependencies must be prepared before firing a request. If you are going to access a remote/local web server, you must install [requests](https://github.com/kennethreitz/requests) first. - - ```bash - - pip install requests - - ``` - - - If you want to test a local tornado server, please make sure tornado is ready on your environment - - ``` bash - - pip install tornado - - ``` - - - We also provide native client for flask app, but to use it, flask is also required - - ``` bash - - pip install flask - - ``` - - - - --------- - - - ## Reference - - All exported API are described in following sections. ![A diagram about relations between components](https://docs.google.com/drawings/d/1DZiJgl4i9L038UJJp3kpwkWRvcNQktf5h-e4m96_C-k/pub?w=849&h=530) - - - - [App](docs/md/ref/app.md) - - - [SwaggerClient](docs/md/ref/client.md) - - - [Security](docs/md/ref/security.md) - - - --------- - - - ## Contributors - - - [Marcin Goliński](https://github.com/mjgolinski) - - - [Andrey Mikhailov](https://github.com/zlovred) - - - [Telepenin Nikolay](https://github.com/prefer) - - - [WangJiannan](https://github.com/WangJiannan) - - - --------- - - - ## Contribution Guildeline - - - #### report an issue: - - - issues can be reported [here](https://github.com/mission-liao/pyswagger/issues) - - - include swagger.json if possible - - - turn on logging and report with messages on console - - ```python - - import logging - - logger = logging.getLogger('pyswagger') - - - formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') - - - console = logging.StreamHandler() - - console.setLevel(logging.DEBUG) - - console.setFormatter(formatter) - - - logger.addHandler(console) - - logger.setLevel(logging.DEBUG) - - - ... your stuff - - - ``` - - - - describe expected behavior, or more specific, the input/output - - - #### submit a PR - - - test included - - - only PR to `develop` would be accepted - - - env preparation - - ```bash - - pip install -r requirement-dev.txt - - ``` - - - unit testing - - ```bash - - python -m pytest -s -v --cov=pyswagger --cov-config=.coveragerc pyswagger/tests - - ``` - -RobWin/swagger2markup: > - = Swagger2Markup - - :author: Robert Winkler - - :hardbreaks: - - - image:https://travis-ci.org/Swagger2Markup/swagger2markup.svg?branch=master["Build Status", link="https://travis-ci.org/Swagger2Markup/swagger2markup"] image:https://coveralls.io/repos/Swagger2Markup/swagger2markup/badge.svg["Coverage Status", link="https://coveralls.io/r/Swagger2Markup/swagger2markup"] image:https://api.codacy.com/project/badge/grade/498a6a39d7d84ff687546359f58ee18d["Codacy code quality", link="https://www.codacy.com/app/robwin/swagger2markup"] image:https://api.bintray.com/packages/swagger2markup/Maven/swagger2markup/images/download.svg[link="https://bintray.com/swagger2markup/Maven/swagger2markup/_latestVersion"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"] image:https://img.shields.io/badge/Twitter-rbrtwnklr-blue.svg["Twitter", link="https://twitter.com/rbrtwnklr"] image:https://badges.gitter.im/Join%20Chat.svg[link="https://gitter.im/RobWin/swagger2markup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"] - - - - == Overview - - - - NOTE: Dear community, - - unfortunately I can't maintain Swagger2Markup alone anymore. There are many interesting new topics: - - 1) Swagger v3 support - - 2) Fixing bugs - - 2) Merge Swagger2Markup repositories and create a new multi-module repository. - - Any help is welcome. - - Kind regards, - - Robert - - - - The primary goal of this project is to *simplify the generation of an up-to-date RESTful API documentation by combining documentation that's been hand-written with auto-generated API documentation* produced by https://github.com/swagger-api[Swagger]. The result is intended to be an *up-to-date, easy-to-read, on- and offline user guide*, comparable to https://developer.github.com/v3/[GitHub's API documentation]. The output of Swagger2Markup can be used as an alternative to https://github.com/swagger-api/swagger-ui[swagger-ui] and can be served as static content. - - NOTE: The Swagger Specification has been donated to to the https://openapis.org/[Open API Initiative (OAI)] and has been renamed to the https://github.com/OAI/OpenAPI-Specification[OpenAPI Specification]. - - - Swagger2Markup converts a Swagger JSON or YAML file into several *AsciiDoc* or *GitHub Flavored Markdown* documents which can be combined with hand-written documentation. The Swagger source file can be located locally or remotely via HTTP. Swagger2Markup supports the Swagger 1.2 and 2.0 specification. Internally it uses the _official_ https://github.com/swagger-api/swagger-parser[swagger-parser] and my https://github.com/RobWin/markup-document-builder[markup-document-builder]. - - - You can use Swagger2Markup to convert your contract-first Swagger YAML file into a human-readable format and combine it with hand-written documentation. As an alternative, you can choose the code-first approach and use Swagger2Markup together with https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-JAX-RS-Project-Setup-1.5.X[Swagger JAX-RS], https://github.com/springfox/springfox[springfox] or https://github.com/spring-projects/spring-restdocs[spring-restdocs]. If you are Gradle or Maven user, you can also use the https://github.com/RobWin/swagger2markup-gradle-plugin[Swagger2Markup Gradle Plugin] or https://github.com/redowl/swagger2markup-maven-plugin[Swagger2markup Maven Plugin]. - - - http://asciidoctor.org/docs/asciidoc-writers-guide/[AsciiDoc] is preferable to Markdown as it has more features. AsciiDoc is a text document format for writing documentation, articles, books, ebooks, slideshows, web pages and blogs. AsciiDoc files can be converted to *HTML*, *PDF* and *EPUB*. AsciiDoc is much better suited for describing public APIs than *JavaDoc* or *Annotations*. - - - You can generate your HTML5, PDF and EPUB documentation via https://github.com/asciidoctor/asciidoctorj[asciidoctorj] or even better via the https://github.com/asciidoctor/asciidoctor-gradle-plugin[asciidoctor-gradle-plugin] or https://github.com/asciidoctor/asciidoctor-maven-plugin[asciidoctor-maven-plugin]. - - - The project requires at least JDK 8. - - - == Example - - - image::swagger2markup-documentation/src/docs/asciidoc/images/Swagger2Markup.PNG[] - - - image::swagger2markup-documentation/src/docs/asciidoc/images/Swagger2Markup_definitions.PNG[] - - - == Reference documentation - - - http://swagger2markup.github.io/swagger2markup/1.3.3/[Reference Documentation] - - - https://github.com/Swagger2Markup/swagger2markup/blob/master/RELEASENOTES.adoc[Release notes] - - - https://github.com/Swagger2Markup/spring-swagger2markup-demo[Demo using Swagger2Markup, Spring Boot, Springfox and spring-restdocs] - - - == Contributing - - - === Community contributions - - - Pull requests are welcome. - - - === Questions - - You can ask questions about Swagger2Markup in https://gitter.im/Swagger2Markup/swagger2markup[Gitter]. - - - === Bugs - - If you believe you have found a bug, please take a moment to search the existing issues. If no one else has reported the problem, please open a new issue that describes the problem in detail and, ideally, includes a test that reproduces it. - - - === Enhancements - - If you’d like an enhancement to be made to Swagger2Markup, pull requests are most welcome. The source code is on GitHub. You may want to search the existing issues and pull requests to see if the enhancement is already being worked on. You may also want to open a new issue to discuss a possible enhancement before work on it begins. - - - == Companies who use Swagger2Markup - - - * Deutsche Telekom AG - - * https://restlet.com/[Restlet] -- Restlet offers an API platform, covering the https://restlet.com/products/restlet-studio/[design], https://restlet.com/products/dhc/[test] and https://restlet.com/products/apispark/[operation] of Web APIs, and uses Swagger2Markup to generate appealing HTML documentation from API definitions. - - * http://www.qaware.de/[QAware GmbH] - - * http://www.appdirect.com/[AppDirect] -- The leading commerce platform for selling cloud services. - - * http://www.wescale.com[wescale] - - * http://taskassure.com[TaskAssure] - - * https://www.isaac.nl[ISAAC] - - * https://www.spreadshirt.de[Spreadshirt] - - - == License - - - Copyright 2015 Robert Winkler - - - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -OpenAPITools/openapi-generator: >+ -

OpenAPI Generator

- - - -
- - - [![Stable releases in Maven Central](https://img.shields.io/maven-metadata/v/https/repo1.maven.org/maven2/org/openapitools/openapi-generator/maven-metadata.xml.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.openapitools%22%20AND%20a%3A%22openapi-generator%22) - - [![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-orange)](./LICENSE) - - [![Open Collective backers](https://img.shields.io/opencollective/backers/openapi_generator?color=orange&label=OpenCollective%20Backers)](https://opencollective.com/openapi_generator) - - [![Join the Slack chat room](https://img.shields.io/badge/Slack-Join%20the%20chat%20room-orange)](https://join.slack.com/t/openapi-generator/shared_invite/zt-12jxxd7p2-XUeQM~4pzsU9x~eGLQqX2g) - - [![Follow OpenAPI Generator Twitter account to get the latest update](https://img.shields.io/twitter/follow/oas_generator.svg?style=social&label=Follow)](https://twitter.com/oas_generator) - - [![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/OpenAPITools/openapi-generator) - - [![Conan Center](https://shields.io/conan/v/openapi-generator)](https://conan.io/center/openapi-generator) - - -
- - -
- - - [Master](https://github.com/OpenAPITools/openapi-generator/tree/master) (`6.6.0`): - - [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/master.svg?label=Integration%20Test)](https://app.travis-ci.com/github/OpenAPITools/openapi-generator/builds) - - [![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator) - - [![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=master&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator) - - [![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/master?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67) - - - [7.0.x](https://github.com/OpenAPITools/openapi-generator/tree/7.0.x) (`7.0.x`): - - [![Build Status](https://img.shields.io/travis/OpenAPITools/openapi-generator/7.0.x.svg?label=Integration%20Test)](https://app.travis-ci.com/github/OpenAPITools/openapi-generator/builds) - - [![Integration Test2](https://circleci.com/gh/OpenAPITools/openapi-generator/tree/7.0.x.svg?style=shield)](https://circleci.com/gh/OpenAPITools/openapi-generator) - - [![Windows Test](https://ci.appveyor.com/api/projects/status/github/openapitools/openapi-generator?branch=7.0.x&svg=true&passingText=Windows%20Test%20-%20OK&failingText=Windows%20Test%20-%20Fails)](https://ci.appveyor.com/project/WilliamCheng/openapi-generator) - - [![Bitrise](https://img.shields.io/bitrise/4a2b10a819d12b67/7.0.x?label=bitrise%3A%20Swift+4,5&token=859FMDR8QHwabCzwvZK6vQ)](https://app.bitrise.io/app/4a2b10a819d12b67) - - -
- - -
- - - :star::star::star: If you would like to contribute, please refer to [guidelines](CONTRIBUTING.md) and a list of [open tasks](https://github.com/openapitools/openapi-generator/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22).:star::star::star: - - - :bangbang: To migrate from Swagger Codegen to OpenAPI Generator, please refer to the [migration guide](docs/migration-from-swagger-codegen.md) :bangbang: - - - :notebook_with_decorative_cover: For more information, please refer to the [Wiki page](https://github.com/openapitools/openapi-generator/wiki) and [FAQ](https://github.com/openapitools/openapi-generator/wiki/FAQ) :notebook_with_decorative_cover: - - - :notebook_with_decorative_cover: The eBook [A Beginner's Guide to Code Generation for REST APIs](https://gum.co/openapi_generator_ebook) is a good starting point for beginners :notebook_with_decorative_cover: - - - :warning: If the OpenAPI spec, templates or any input (e.g. options, environment variables) is obtained from an untrusted source or environment, please make sure you've reviewed these inputs before using OpenAPI Generator to generate the API client, server stub or documentation to avoid potential security issues (e.g. [code injection](https://en.wikipedia.org/wiki/Code_injection)). For security vulnerabilities, please contact [team@openapitools.org](mailto:team@openapitools.org). :warning: - - - :bangbang: Both "OpenAPI Tools" (https://OpenAPITools.org - the parent organization of OpenAPI Generator) and "OpenAPI Generator" are not affiliated with OpenAPI Initiative (OAI) :bangbang: - - -
- - - ## Sponsors - - - If you find OpenAPI Generator useful for work, please consider asking your company to support this Open Source project by [becoming a sponsor](https://opencollective.com/openapi_generator). You can also individually sponsor the project by [becoming a backer](https://opencollective.com/openapi_generator). - - - #### Thank you to our bronze sponsors! - - - [![NamSor](https://openapi-generator.tech/img/companies/namsor.png)](https://www.namsor.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [![LightBow](https://openapi-generator.tech/img/companies/lightbow.png)](https://www.lightbow.net/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://docspring.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://datadoghq.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://cpl.thalesgroup.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://www.apideck.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://www.pexa.com.au/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://www.numary.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://www.onesignal.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://www.virtualansoftware.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://www.merge.dev/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://www.burkert.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://www.finbourne.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://bump.sh/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - - #### Thank you GoDaddy for sponsoring the domain names, Linode for sponsoring the VPS and Checkly for sponsoring the API monitoring - - - [](https://www.godaddy.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [![Linode](https://www.linode.com/media/images/logos/standard/light/linode-logo_standard_light_small.png)](https://www.linode.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - [](https://checklyhq.com/?utm_source=openapi_generator&utm_medium=github_webpage&utm_campaign=sponsor) - - - - ## Overview - - OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an [OpenAPI Spec](https://github.com/OAI/OpenAPI-Specification) (both 2.0 and 3.0 are supported). Currently, the following languages/frameworks are supported: - - - | | Languages/Frameworks | - - | -------------------------------- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| - - | **API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later, .NET Standard 1.3 - 2.1, .NET Core 3.1, .NET 5.0. Libraries: RestSharp, GenericHost, HttpClient), **C++** (Arduino, cpp-restsdk, Qt5, Tizen, Unreal Engine 4), **Clojure**, **Crystal**, **Dart**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Apache HttpClient 4.x, Apache HttpClient 5.x, Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client, MicroProfile Rest Client, Helidon), **Jetbrains HTTP Client**, **Julia**, **k6**, **Kotlin**, **Lua**, **Nim**, **Node.js/JavaScript** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types, Apollo GraphQL DataStore), **Objective-C**, **OCaml**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (hyper, reqwest, rust-server), **Scala** (akka, http4s, scalaz, sttp, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x, 5.x), **Typescript** (AngularJS, Angular (2.x - 15.x), Aurelia, Axios, Fetch, Inversify, jQuery, Nestjs, Node, redux-query, Rxjs) | - - | **Server stubs** | **Ada**, **C#** (ASP.NET Core, Azure Functions), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin, Echo), **Haskell** (Servant, Yesod), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples), [Vert.x](https://vertx.io/), [Apache Camel](https://camel.apache.org/), [Helidon](https://helidon.io/)), **Julia**, **Kotlin** (Spring Boot, Ktor, Vertx), **PHP** (Laravel, Lumen, [Mezzio (fka Zend Expressive)](https://github.com/mezzio/mezzio), Slim, Silex, [Symfony](https://symfony.com/)), **Python** (FastAPI, Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** ([rust-server](https://openapi-generator.tech/docs/generators/rust-server/)), **Scala** (Akka, [Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), Scalatra) | - - | **API documentation generators** | **HTML**, **Confluence Wiki**, **Asciidoc**, **Markdown**, **PlantUML** | - - | **Configuration files** | [**Apache2**](https://httpd.apache.org/) | - - | **Others** | **GraphQL**, **JMeter**, **Ktorm**, **MySQL Schema**, **Protocol Buffer**, **WSDL** | - - - ## Table of contents - - - [OpenAPI Generator](#openapi-generator) - - [Overview](#overview) - - [Table of Contents](#table-of-contents) - - [1 - Installation](#1---installation) - - [1.1 - Compatibility](#11---compatibility) - - [1.2 - Artifacts on Maven Central](#12---artifacts-on-maven-central) - - [1.3 - Download JAR](#13---download-jar) - - [1.4 - Build Projects](#14---build-projects) - - [1.5 - Homebrew](#15---homebrew) - - [1.6 - Docker](#16---docker) - - [1.7 - NPM](#17---npm) - - [2 - Getting Started](#2---getting-started) - - [3 - Usage](#3---usage) - - [3.1 - Customization](#31---customization) - - [3.2 - Workflow Integration](#32---workflow-integration-maven-gradle-github-cicd) - - [3.3 - Online Generators](#33---online-openapi-generator) - - [3.4 - License Information on Generated Code](#34---license-information-on-generated-code) - - [3.5 - IDE Integration](#35---ide-integration) - - [4 - Companies/Projects using OpenAPI Generator](#4---companiesprojects-using-openapi-generator) - - [5 - Presentations/Videos/Tutorials/Books](#5---presentationsvideostutorialsbooks) - - [6 - About Us](#6---about-us) - - [6.1 - OpenAPI Generator Core Team](#61---openapi-generator-core-team) - - [6.2 - OpenAPI Generator Technical Committee](#62---openapi-generator-technical-committee) - - [6.3 - History of OpenAPI Generator](#63---history-of-openapi-generator) - - [7 - License](#7---license) - - ## [1 - Installation](#table-of-contents) - - - ### [1.1 - Compatibility](#table-of-contents) - - - The OpenAPI Specification has undergone 3 revisions since initial creation in 2010. The openapi-generator project has the following compatibilities with the OpenAPI Specification: - - - | OpenAPI Generator Version | Release Date | Notes | - - | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------------------------------------- | - - | 7.0.0 (upcoming major release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/7.0.0-SNAPSHOT/) | May/Jun 2023 | Major release with breaking changes (no fallback) | - - | 6.6.0 (upcoming minor release) [SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.5.0-SNAPSHOT/) | 28.04.2023 | Minor release with breaking changes (with fallback) | - - | [6.5.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v6.5.0) (latest stable release) | 01.04.2023 | Minor release with breaking changes (with fallback) | - - | [5.4.0](https://github.com/OpenAPITools/openapi-generator/releases/tag/v5.4.0) | 31.01.2022 | Minor release with breaking changes (with fallback) | - - | [4.3.1](https://github.com/OpenAPITools/openapi-generator/releases/tag/v4.3.1) | 06.05.2020 | Patch release (enhancements, bug fixes, etc) | - - - OpenAPI Spec compatibility: 1.0, 1.1, 1.2, 2.0, 3.0 - - - For old releases, please refer to the [**Release**](https://github.com/OpenAPITools/openapi-generator/releases) page. - - - For decomissioned generators/libraries/frameworks, please refer to [the "Decommission" label](https://github.com/OpenAPITools/openapi-generator/issues?q=label%3ADecommission+is%3Amerged+) in the pull request page. - - - ## [1.2 - Artifacts on Maven Central](#table-of-contents) - - - You can find our released artifacts on maven central: - - - **Core:** - - ```xml - - - org.openapitools - openapi-generator - ${openapi-generator-version} - - - ``` - - See the different versions of the [openapi-generator](https://search.maven.org/artifact/org.openapitools/openapi-generator) artifact available on maven central. - - - **Cli:** - - ```xml - - - org.openapitools - openapi-generator-cli - ${openapi-generator-version} - - - ``` - - See the different versions of the [openapi-generator-cli](https://search.maven.org/artifact/org.openapitools/openapi-generator-cli) artifact available on maven central. - - - **Maven plugin:** - - ```xml - - - org.openapitools - openapi-generator-maven-plugin - ${openapi-generator-version} - - - ``` - - * See the different versions of the [openapi-generator-maven-plugin](https://search.maven.org/artifact/org.openapitools/openapi-generator-maven-plugin) artifact available on maven central. - - * [Readme](https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator-maven-plugin/README.md) - - - **Gradle plugin:** - - ```xml - - - org.openapitools - openapi-generator-gradle-plugin - ${openapi-generator-version} - - - ``` - - * See the different versions of the [openapi-generator-gradle-plugin](https://search.maven.org/artifact/org.openapitools/openapi-generator-gradle-plugin) artifact available on maven central. - - * [Readme](https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator-gradle-plugin/README.adoc) - - - ### [1.3 - Download JAR](#table-of-contents) - - - - If you're looking for the latest stable version, you can grab it directly from Maven.org (Java 8 runtime at a minimum): - - - JAR location: `https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.5.0/openapi-generator-cli-6.5.0.jar` - - - For **Mac/Linux** users: - - ```sh - - wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.5.0/openapi-generator-cli-6.5.0.jar -O openapi-generator-cli.jar - - ``` - - - For **Windows** users, you will need to install [wget](http://gnuwin32.sourceforge.net/packages/wget.htm) or you can use Invoke-WebRequest in PowerShell (3.0+), e.g. - - ``` - - Invoke-WebRequest -OutFile openapi-generator-cli.jar https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.5.0/openapi-generator-cli-6.5.0.jar - - ``` - - - After downloading the JAR, run `java -jar openapi-generator-cli.jar help` to show the usage. - - - For Mac users, please make sure Java 8 is installed (Tips: run `java -version` to check the version), and export `JAVA_HOME` in order to use the supported Java version: - - ```sh - - export JAVA_HOME=`/usr/libexec/java_home -v 1.8` - - export PATH=${JAVA_HOME}/bin:$PATH - - ``` - - - - ### Launcher Script - - - One downside to manual jar downloads is that you don't keep up-to-date with the latest released version. We have a Bash launcher script at [bin/utils/openapi-generator.cli.sh](./bin/utils/openapi-generator-cli.sh) which resolves this issue. - - - To install the launcher script, copy the contents of the script to a location on your path and make the script executable. - - - An example of setting this up (NOTE: Always evaluate scripts curled from external systems before executing them). - - - ``` - - mkdir -p ~/bin/openapitools - - curl https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/bin/utils/openapi-generator-cli.sh > ~/bin/openapitools/openapi-generator-cli - - chmod u+x ~/bin/openapitools/openapi-generator-cli - - export PATH=$PATH:~/bin/openapitools/ - - ``` - - - Now, `openapi-generator-cli` is "installed". On invocation, it will query the GitHub repository for the most recently released version. If this matches the last downloaded jar, - - it will execute as normal. If a newer version is found, the script will download the latest release and execute it. - - - If you need to invoke an older version of the generator, you can define the variable `OPENAPI_GENERATOR_VERSION` either ad hoc or globally. You can export this variable if you'd like to persist a specific release version. - - - Examples: - - - ``` - - # Execute latest released openapi-generator-cli - - openapi-generator-cli version - - - # Execute version 4.1.0 for the current invocation, regardless of the latest released version - - OPENAPI_GENERATOR_VERSION=4.1.0 openapi-generator-cli version - - - # Execute version 4.1.0-SNAPSHOT for the current invocation - - OPENAPI_GENERATOR_VERSION=4.1.0-SNAPSHOT openapi-generator-cli version - - - # Execute version 4.0.2 for every invocation in the current shell session - - export OPENAPI_GENERATOR_VERSION=4.0.2 - - openapi-generator-cli version # is 4.0.2 - - openapi-generator-cli version # is also 4.0.2 - - - # To "install" a specific version, set the variable in .bashrc/.bash_profile - - echo "export OPENAPI_GENERATOR_VERSION=4.0.2" >> ~/.bashrc - - source ~/.bashrc - - openapi-generator-cli version # is always 4.0.2, unless any of the above overrides are done ad hoc - - ``` - - - ### [1.4 - Build Projects](#table-of-contents) - - - To build from source, you need the following installed and available in your `$PATH:` - - - * [Java 8](https://www.oracle.com/technetwork/java/index.html) - - - * [Apache Maven 3.3.4 or greater](https://maven.apache.org/) - - - After cloning the project, you can build it from source with this command: - - ```sh - - mvn clean install - - ``` - - - If you don't have maven installed, you may directly use the included [maven wrapper](https://github.com/takari/maven-wrapper), and build with the command: - - ```sh - - ./mvnw clean install - - ``` - - - #### Nix users - - - If you're a nix user, you can enter OpenAPI Generator shell, by typing: - - ```sh - - nix develop - - ``` - - It will enter a shell with Java 8 and Maven installed. - - - Direnv supports automatically loading of the nix developer shell, so if you're using direnv too, type: - - ```sh - - direnv allow - - ``` - - and have `java` and `mvn` set up with correct versions each time you enter project directory. - - - The default build contains minimal static analysis (via CheckStyle). To run your build with PMD and Spotbugs, use the `static-analysis` profile: - - - ```sh - - mvn -Pstatic-analysis clean install - - ``` - - - ### [1.5 - Homebrew](#table-of-contents) - - - To install, run `brew install openapi-generator` - - - Here is an example usage to generate a Ruby client: - - ```sh - - openapi-generator generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g ruby -o /tmp/test/ - - ``` - - - To reinstall with the latest master, run `brew uninstall openapi-generator && brew install --HEAD openapi-generator` - - - To install OpenJDK (pre-requisites), please run - - ```sh - - brew tap AdoptOpenJDK/openjdk - - brew install --cask adoptopenjdk12 - - export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-12.0.2.jdk/Contents/Home/ - - ``` - - - To install Maven, please run - - ```sh - - brew install maven - - ``` - - - ### [1.6 - Docker](#table-of-contents) - - - #### Public Pre-built Docker images - - - [https://hub.docker.com/r/openapitools/openapi-generator-cli/](https://hub.docker.com/r/openapitools/openapi-generator-cli/) (official CLI) - - [https://hub.docker.com/r/openapitools/openapi-generator-online/](https://hub.docker.com/r/openapitools/openapi-generator-online/) (official web service) - - - #### OpenAPI Generator CLI Docker Image - - - The OpenAPI Generator image acts as a standalone executable. It can be used as an alternative to installing via homebrew, or for developers who are unable to install Java or upgrade the installed version. - - - To generate code with this image, you'll need to mount a local location as a volume. - - - Example: - - - ```sh - - docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \ - -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml \ - -g go \ - -o /local/out/go - ``` - - - The generated code will be located under `./out/go` in the current directory. - - - #### OpenAPI Generator Online Docker Image - - - The openapi-generator-online image can act as a self-hosted web application and API for generating code. This container can be incorporated into a CI pipeline, and requires at least two HTTP requests and some docker orchestration to access generated code. - - - Example usage: - - - ```sh - - # Start container at port 8888 and save the container id - - > CID=$(docker run -d -p 8888:8080 openapitools/openapi-generator-online) - - - # allow for startup - - > sleep 10 - - - # Get the IP of the running container (optional) - - GEN_IP=$(docker inspect --format '{{.NetworkSettings.IPAddress}}' $CID) - - - # Execute an HTTP request to generate a Ruby client - - > curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' \ - - -d '{"openAPIUrl": "https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml"}' \ - - 'http://localhost:8888/api/gen/clients/ruby' - - - {"code":"c2d483.3.4672-40e9-91df-b9ffd18d22b8","link":"http://localhost:8888/api/gen/download/c2d483.3.4672-40e9-91df-b9ffd18d22b8"} - - - # Download the generated zip file - - > wget http://localhost:8888/api/gen/download/c2d483.3.4672-40e9-91df-b9ffd18d22b8 - - - # Unzip the file - - > unzip c2d483.3.4672-40e9-91df-b9ffd18d22b8 - - - # Shutdown the openapi generator image - - > docker stop $CID && docker rm $CID - - ``` - - - #### Development in docker - - - You can use `run-in-docker.sh` to do all development. This script maps your local repository to `/gen` - - in the docker container. It also maps `~/.m2/repository` to the appropriate container location. - - - To execute `mvn package`: - - - ```sh - - git clone https://github.com/openapitools/openapi-generator - - cd openapi-generator - - ./run-in-docker.sh mvn package - - ``` - - - Build artifacts are now accessible in your working directory. - - - Once built, `run-in-docker.sh` will act as an executable for openapi-generator-cli. To generate code, you'll need to output to a directory under `/gen` (e.g. `/gen/out`). For example: - - - ```sh - - ./run-in-docker.sh help # Executes 'help' command for openapi-generator-cli - - ./run-in-docker.sh list # Executes 'list' command for openapi-generator-cli - - ./run-in-docker.sh /gen/bin/go-petstore.sh # Builds the Go client - - ./run-in-docker.sh generate -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml \ - -g go -o /gen/out/go-petstore -p packageName=petstore # generates go client, outputs locally to ./out/go-petstore - ``` - - - ##### Troubleshooting - - - If an error like this occurs, just execute the **mvn clean install -U** command: - - - > org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test (default-test) on project openapi-generator: A type incompatibility occurred while executing org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test: java.lang.ExceptionInInitializerError cannot be cast to java.io.IOException - - - ```sh - - ./run-in-docker.sh mvn clean install -U - - ``` - - - > Failed to execute goal org.fortasoft:gradle-maven-plugin:1.0.8:invoke (default) on project openapi-generator-gradle-plugin-mvn-wrapper: org.gradle.tooling.BuildException: Could not execute build using Gradle distribution 'https://services.gradle.org/distributions/gradle-4.7-bin.zip' - - - Right now: no solution for this one :| - - - #### Run Docker in Vagrant - - Prerequisite: install [Vagrant](https://www.vagrantup.com/downloads.html) and [VirtualBox](https://www.virtualbox.org/wiki/Downloads). - ```sh - git clone https://github.com/openapitools/openapi-generator.git - - cd openapi-generator - - vagrant up - - vagrant ssh - - cd /vagrant - - ./run-in-docker.sh mvn package - - ``` - - - ### [1.7 - NPM](#table-of-contents) - - - There is also an [NPM package wrapper](https://www.npmjs.com/package/@openapitools/openapi-generator-cli) available for different platforms (e.g. Linux, Mac, Windows). (JVM is still required) - - Please see the [project's README](https://github.com/openapitools/openapi-generator-cli) there for more information. - - - Install it globally to get the CLI available on the command line: - - - ```sh - - npm install @openapitools/openapi-generator-cli -g - - openapi-generator-cli version - - ``` - - - - - To use a specific version of "openapi-generator-cli" - - - ```sh - - openapi-generator-cli version-manager set 6.5.0 - - ``` - - - Or install it as dev-dependency: - - - ```sh - - npm install @openapitools/openapi-generator-cli -D - - ``` - - - - ## [2 - Getting Started](#table-of-contents) - - - To generate a PHP client for [petstore.yaml](https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml), please run the following - - ```sh - - git clone https://github.com/openapitools/openapi-generator - - cd openapi-generator - - mvn clean package - - java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \ - -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml \ - -g php \ - -o /var/tmp/php_api_client - ``` - - (if you're on Windows, replace the last command with `java -jar modules\openapi-generator-cli\target\openapi-generator-cli.jar generate -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml -g php -o c:\temp\php_api_client`) - - - - - You can also download the JAR (latest release) directly from [maven.org](https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.5.0/openapi-generator-cli-6.5.0.jar) - - - - - To get a list of **general** options available, please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar help generate` - - - To get a list of PHP specified options (which can be passed to the generator with a config file via the `-c` option), please run `java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar config-help -g php` - - - ## [3 - Usage](#table-of-contents) - - - ### To generate a sample client library - - You can build a client against the [Petstore API](https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml) as follows: - - - ```sh - - ./bin/generate-samples.sh ./bin/configs/java-okhttp-gson.yaml - - ``` - - - (On Windows, please install [GIT Bash for Windows](https://gitforwindows.org/) to run the command above) - - - This script uses the default library, which is `okhttp-gson`. It will run the generator with this command: - - - ```sh - - java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \ - -i https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/petstore.yaml \ - -g java \ - -t modules/openapi-generator/src/main/resources/Java \ - --additional-properties artifactId=petstore-okhttp-gson,hideGenerationTimestamp:true \ - -o samples/client/petstore/java/okhttp-gson - ``` - - - with a number of options. [The java options are documented here.](docs/generators/java.md) - - - You can also get the options with the `help generate` command (below only shows partial results): - - - ``` - - NAME - openapi-generator-cli generate - Generate code with the specified - generator. - - SYNOPSIS - openapi-generator-cli generate - [(-a | --auth )] - [--api-name-suffix ] [--api-package ] - [--artifact-id ] [--artifact-version ] - [(-c | --config )] [--dry-run] - [(-e | --engine )] - [--enable-post-process-file] - [(-g | --generator-name )] - [--generate-alias-as-model] [--git-host ] - [--git-repo-id ] [--git-user-id ] - [--global-property ...] [--group-id ] - [--http-user-agent ] - [(-i | --input-spec )] - [--ignore-file-override ] - [--import-mappings ...] - [--instantiation-types ...] - [--invoker-package ] - [--language-specific-primitives ...] - [--legacy-discriminator-behavior] [--library ] - [--log-to-stderr] [--minimal-update] - [--model-name-prefix ] - [--model-name-suffix ] - [--model-package ] - [(-o | --output )] [(-p | --additional-properties )...] - [--package-name ] [--release-note ] - [--remove-operation-id-prefix] - [--reserved-words-mappings ...] - [(-s | --skip-overwrite)] [--server-variables ...] - [--skip-validate-spec] [--strict-spec ] - [(-t