When we create service with REST interface we need to publish protocol description. Which method will be used, which parameters will be used. If we do not want to share this responsibility from programmers to technical writers, we need to use simple tool for this problem.
One of the best thing that you can do is describe your API in fixed typed format of API documentation. Most common format of documentation is Swagger. Write your documentation in yaml/json format and export to nice looking ui. Example project Petstore demonstrate this concept: [ui] [json].
In swagger we can define different levels of api:
Lets look at endpoint declaration. Take attention to tags: each group of endpoint is marked with same tag. Another interesting thing is schema $ref: we can link to object definition.
/pet:
post:
tags:
- pet
summary: Add a new pet to the store
operationId: addPet
consumes:
- application/json
produces:
- application/json
parameters:
- in: body
name: body
description: Pet object that needs to be added to the store
required: true
schema:
$ref: '#/definitions/Pet'
responses:
405:
description: Invalid input
security:
- petstore_auth:
- write:pets
- read:pets
Pet object definition describe pet object fields including fields and fields types. As in paths we can link to another schemas using $ref:
Pet:
type: object
required:
- name
- photoUrls
properties:
id:
type: integer
format: int64
category:
$ref: '#/definitions/Category'
name:
type: string
example: doggie
photoUrls:
type: array
xml:
name: photoUrl
wrapped: true
items:
type: string
tags:
type: array
xml:
name: tag
wrapped: true
items:
$ref: '#/definitions/Tag'
status:
type: string
description: pet status in the store
enum:
- available
- pending
- sold
If we do not want to write swagger definition and source code separately we need to use support tool. TornadoSwagger allow you to write swagger in docstring and serve swagger-ui in special endpoint.
class PostsDetailsHandler(tornado.web.RequestHandler):
def get(self, posts_id):
"""
---
tags:
- Posts
summary: Get posts details
description: posts full version
produces:
- application/json
parameters:
- name: posts_id
in: path
description: ID of post to return
required: true
type: string
responses:
200:
description: list of posts
schema:
$ref: '#/definitions/PostModel'
"""
@register_swagger_model
class PostModel:
"""
---
type: object
description: Post model representation
properties:
id:
type: integer
format: int64
title:
type: string
text:
type: string
is_visible:
type: boolean
default: true
"""
Tornado-swagger can be simple installed. Just add setup_swagger into your Application __init__:
class Application(tornado.web.Application):
_routes = [
tornado.web.url(r'/api/posts', PostsHandler),
tornado.web.url(r'/api/posts/(\w+)', PostsDetailsHandler),
]
def __init__(self):
settings = {
'debug': True
}
setup_swagger(self._routes,
swagger_url='/doc',
api_base_url='/',
description='',
api_version='1.0.0',
title='Journal API',
contact='name@domain',
schemes=['https'],
security_definitions={
'ApiKeyAuth': {
'type': 'apiKey',
'in': 'header',
'name': 'X-API-Key'
}
})
super(Application, self).__init__(self._routes, **settings)
pip install tornado-swagger
API must be described and published in common format. It can improve cross team developing speed and simplify service integration into your large system. Most common tool is Swagger. Tornado-Swagger allow you to integrate swagger-ui and swagger-format into your project.
Author @mrkandreev
Machine Learning Engineer