Once we have a mock server, we could already provide an interface to external services mocking our replies.
This is very helpful to enable clients to test our API and enable quick feedbacks on data types and possible responses.
Now that we have the contract, we should start with the implementation!
OperationId is the OAS3 fields with maps the resource-target with the python function to call.
paths:
/status
get:
...
operationId: api.get_status
...
The method signature should reflect the function's one.
OAS allows to pass parameters to the resource target via:
At first we'll just implement the get_status in api.py function that:
In [1]:
# connexion provides a predefined problem object
from connexion import problem
# Exercise: write a get_status() returning a successful response to problem.
help(problem)
In [2]:
def get_status():
return problem(
status=200,
title="OK",
detail="The application is working properly"
)
Now run the spec in a terminal using
cd /code/notebooks/oas3/
connexion run /code/notebooks/oas3/ex-03-02-path.yaml
play a bit with the Swagger UI
and try making a request!
In [3]:
!curl http://localhost:5000/datetime/v1/status -kv
Our api.get_status implementation always returns 200 OK, but in the real world APIs could
return different kind of errors.
An interoperable API should:
In our Service Management framework we expect that:
503 Service Unavailable http statusRetry-After header specifying the number of seconds
when to retry.TODO: ADD CIRCUIT_BREAKER IMAGE
To implement this we must:
Modify the OAS3 spec in ex-04-01-headers.yaml and:
503 response to the /status path;503 is returned, the retry-after header is returned.Hint: you can define a header in components/headers like that:
components:
headers:
Retry-After:
description: |-
Retry contacting the endpoint *at least* after seconds.
See https://tools.ietf.org/html/rfc7231#section-7.1.3
schema:
format: int32
type: integer
Or just $ref the Retry-After defined in https://teamdigitale.github.io/openapi/0.0.5/definitions.yaml#/headers/Retry-After
Modify api.py:get_status such that:
503 on 20% of the requests;503 is returned, the retry-after header is returned;Cache-Control: no-store header to avoid
caching on service status.Bonus track: Google post on HTTP caching
In [6]:
from random import randint
from connexion import problem
def get_status():
headers = {"Cache-Control": "no-store"}
p = randint(1, 5)
if p == 5:
return problem(
status=503,
title="Service Temporarily Unavailable",
detail="Retry after the number of seconds specified in the the Retry-After header.",
headers=dict(**headers, **{'Retry-After': str(p)})
)
return problem(
status=200,
title="OK",
detail="So far so good.",
headers=headers
)
As 503 is a quite recurring response, it's worth to define it in a reusable yaml file,
so that every path can reuse it.
In the following exercise you should edit ex-04-01-headers.yaml and:
503 response from the /status path definition to the components/responses one, eg.components:
responses:
503ServiceUnavailable:
...
#/components/responses/503ServiceUnavailable in the /status pathYour new file is semantically equivalent to the previous one: check that you can
nicely connexion run your file in terminal!
connexion run /code/notebooks/oas3/ex-04-01-headers.yaml
In [ ]: