introduction to swagger
TRANSCRIPT
Swagger
Sangeeta GuliaSoftware Consultant Knoldus Software LLP
AGENDA
Whats Swagger?
Why Swagger?
Swagger Components
Data Types
Generating Swagger Spec
Getting started with Play-Swagger
Important Attributes
Swagger Codegen
Generating SDKs
Whats Swagger?
The goal of Swagger 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.
When properly defined via Swagger, a consumer can understand and interact with the remote service with a minimal amount of implementation logic.
It can be visualised similar to what interfaces have done for lower-level programming
Swagger removes the guesswork in calling the service.
Why Swagger?
Swagger is one of the most popular specifications for REST APIs for a number of reasons:
Swagger generates an interactive API console for people to quickly learn about and try the API.
Swagger generates the client SDK code needed for implementations on various platforms.
The Swagger file can be auto-generated from code annotations or using case class definitions on a lot of different platforms.
Swagger has a strong community with helpful contributors.
Swagger Components
Swagger spec: The Swagger spec is the official schema about name and element nesting, order, and so on. If you plan on hand-coding the Swagger files, youll need to be extremely familiar with the Swagger spec.
Swagger editor: The Swagger Editor is an online editor that validates your YML-formatted content against the rules of the Swagger spec. YML is a syntax that depends on spaces and nesting. Youll need to be familiar with YML syntax and the rules of the Swagger spec to be successful here. The Swagger editor will flag errors and give you formatting tips. (Note that the Swagger spec file can be in either JSON or YAML format.)
Example: http://editor.swagger.io/#/
Swagger Components(cont...)
Swagger-UI: The Swagger UI is an HTML/CSS/JS framework that parses a JSON or YML file that follows the Swagger spec and generates a navigable UI of the documentation.
Swagger-codegen: This utility generates client SDK code for a lot of different platforms (such as Java, JavaScript, Scala, Python, PHP, Ruby, Scala, and more). This client code helps developers integrate your API on a specific platform and provides for more robust implementations that might include more scaling, threading, and other necessary code. An SDK is supportive tooling that helps developers use the REST API.
Data Types
Note: Primitives have an optional modifier property format.
Generating Swagger Spec
Two Techniques:
1) Using Annotations
2) Using ihearts play-swagger
(A library that generates swagger specs from route files and case class reflection, no code annotation needed.)
Getting started with play-swagger
Step 1 : Add dependency to build.sbt.
libraryDependencies += "com.iheart" %% "play-swagger" % "0.4.0"
Step 2 : Add a base swagger.yml (or swagger.json) to the resources (for example, conf folder in the play application).
This one needs to provide all the required fields according to swagger spec.
Getting started with play-swagger (cont...)
Basic swagger.json
{ "swagger": "2.0", "host": "localhost:9000", "consumes": [ "application/json", "application/text" ], "produces": [ "application/json" ]}
Getting started with play-swagger (cont..)
Step 3 : You can use swagger-ui webjar and have your play app serving the swagger ui:
Add the following dependency:libraryDependencies += "org.webjars" % "swagger-ui" % "2.1.4"
Step 4 : Add the following to your routes file:
### NoDocs ###GET /swagger.json controllers.ApiSpecs.specs
### NoDocs ###GET /docs/*file controllers.Assets.versioned(path:String= "/public/lib/swagger-ui", file:String)
Getting started with play-swagger (cont..)
Step 5 : Now we need to create the controller(ApiSpecs as mentioned in routes) who will be responsible for generating spec file, reading required things from routes file and models(i.e case classes).-------------------------------------------------------------------------------------------------------- ApiSpecs.scala
--------------------------------------------------------------------------------------------------------import play.api.libs.concurrent.Execution.Implicits._import com.iheart.playSwagger.SwaggerSpecGeneratorimport play.api.mvc.{Action, Controller}import scala.concurrent.Future
class ApiSpecs extends Controller { implicit val cl = getClass.getClassLoader
val domainPackage = "models" private lazy val generator = SwaggerSpecGenerator(domainPackage)
def specs = Action.async { _ => Future.fromTry(generator.generate()).map(Ok(_)) }}
Getting started with play-swagger (cont..)
SwaggerSpecGenerator is a case class which takes DomainModelQualifier, which in turn accepts namespace*.
Generate is the method which takes location of route file as argument.(Note: if not specified, by default it uses conf/routes)
Now you can see the generated swagger UI at :
http://localhost:9000/docs/index.html?url=/swagger.json#/
Important Attributes
S. No.Attribute NameDescription
1tagsUsed to group multiple routes.
2summaryDescribe short summary about route.
3consumesDetermine the type of data being accepted by any route.
4producesDetermine the type of data being returned as response.
5parametersDefine the parameters(including attributes type, format, required, description, in). It hold array of parameters.
6responsesDefine the schema of responses as per different response codes
7schemaDefine schema of response
8descriptionUsed to provide description for a route, any parameter or any response.
9requiredUsed to denote if a parameter is required or not. (default: false)
How to hide an endpoint?
If you don't want an end point to be included, add ### NoDocs ### in front of it e.g.
### NoDocs ###GET /docs/swagger-ui/*file controllers.Assets.at(path:String="/public/lib/swagger-ui", file:String)
Specify parameters in query
#### {# "tags" : ["QueryStringContainData"],# "summary" : "get student record(query example)",# "parameters" : [ {# "in" : "query",# "name":"id",# "description": "Student Id",# "required":true,# "type":"string"# } ],# "responses": {# "200": {# "description": "success",# "schema": { "$ref": "#/definitions/models.StudentRecordResponse" }# }# }# }###GET /get/student/record/ controllers.SwaggerUiController.getStudentRecordById
Specify parameters in path
#### {# "tags" : ["PathContainData"],# "summary" : "get student record(path example)",# "parameters" : [ {# "in" : "path",# "name":"id",# "description": "Student Id",# "required":true,# "type":"string"# } ],# "responses": {# "200": {# "description": "success",# "schema": { "$ref": "#/definitions/models.StudentRecordResponse" }# }# }# }###GET /student/record/:id controllers.SwaggerUiController.getRecordById(id: Int)
Specify parameters as formUrlEncodedBody
#### {
# "tags" : ["BodyData"],
# "summary" : "mirror response",
# "consumes" : [ "application/x-www-form-urlencoded" ],
# "parameters" : [ {
# "in" : "formData",
# "name":"id",
# "description": "Employee Id",
# "required":true,
# "type":"integer",
# "format":"int64"
# } ],
# "responses": {
# "200": {
# "description": "success",
# "schema": { "$ref": "#/definitions/models.RequestWithBody" }
# }
# }
# }
###
Sending Multipart form data
#### {# "tags" : ["Multipart Data"],# "summary" : "multipart data",# "consumes" : [ "multipart/form-data" ],# "parameters" : [# {# "in" : "formData",# "name":"key",# "required":true,# "type":"string"# },# ],# "responses": {# "200": {# "description": "success",# "schema": {# "$ref": "#/definitions/models.swagger.Response"# }# }# }# }###
Specify response definition in Swagger.json
definitions: {"InternRecordResponse" : { "type":"object", "required":[ "data" ], "properties": { "data" : { "$ref": "#/definitions/InternRecord" } } }, "InternRecord": { "type":"object", "properties": { "intern_id" : { "type": "string" }, "intern_email" : { "type": "string" } } }}
USAGE:"$ref": "#/definitions/InternRecordResponse"
Specify response details
# "responses": {# "200": {# "description": "success",# "schema": {# "$ref": "#/definitions/models.RequestWithBody"# }# },#"400": {#"description": "Problem in parsing input json data",#"schema": {#"$ref": "#/definitions/models.ErrorResponse"#}#},# "default": {# "description": "error",# "schema": {# "$ref": "#/definitions/models.ErrorResponse"# }# }# }
Handling Option field on UI
We can have optional field, but on UI it can be identified under Model tab and not in model schema.
This feature is yet to be included.
Swagger Codegen
swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
Generating SDKs
git clone https://github.com/swagger-api/swagger-codegencd swagger-codegenmvn clean package
Command to create SDK:
java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \ -i http://petstore.swagger.io/v2/swagger.json \ -l php \ -o /var/tmp/php_api_client
Demo
Demo project can be found at :
https://github.com/knoldus/swagger-demo
Thank You...
https://github.com/iheartradio/play-swagger
https://github.com/swagger-api/swagger-codegen
References