# Install it with the swagger module
# that renders the spec in a web-ui
!pip install connexion[swagger-ui] connexion
# And load some gobal settings for the exercises.
import socket
host = socket.gethostbyname(socket.gethostname())
port = 5000
connexion uses your OAS3 specification to:
- dispatch requests
- serve mock responses on unimplemented methods
- validate input and output of the called methods
- apply authentication policies
- provide an API Documentation UI (Swagger UI) where we can browse our API.
print(f"$ connexion run notebooks/oas3/ex-01-info-ok.yaml --host {host} --port {port}")
print()
print(f"Then open the documentation URL: http://{host}:{port}/ui")
Remember:
- default port is
:5000 - the Swagger UI is at the
/uipath.
# A request on a generic PATH on the server returns a
# nicely formatted and explicative error.
# Remember that we haven't already defined an operation.
!curl http://0.0.0.0:5000 -kv
Open the documentation URL}) and check the outcome!
Exercises {#connexion-run-ex}¶
- issue a
POST /uirequest and check that the status code is405 Method Not Allowed. - issue a
GET /MISSINGrequest and check that the status code is404 Not Found. - the
Content-Typeheader field conveys the media type of the returned content; what's the content type of the error responses?
Defining endpoints in OAS3¶
Now that we have added our metadata, we can provide informations about server endpoints. OAS3 allows multiple server endpoints because stakeholders interactions go through various lifecycle stages.
Every endpoint can start with a base path (eg. /datetime/v1).
# One or more server
# You can add production, staging and test environments.
# A tip is to mark non-production instances as sandboxes.
servers:
- description: |
An interoperable API has many endpoints.
One for development...
url: https://localhost:8443/datetime/v1
x-sandbox: true
- description: |
One for testing in a sandboxed environment. This
is especially important to avoid clients to
test in production.
We are using the custom `x-sandbox` to identify
url: https://api.example.com/datetime/v1
x-sandbox: true
- description: |
Then we have our production endpoint.
The custom `x-healthCheck` parameter
can be used to declare how to check the API.
url: https://api.example.com/datetime/v1/status
x-healthCheck:
url: https://api.example.com/datetime/v1/status
interval: 300
timeout: 15
Exercise: the servers parameter¶
Edit the servers attribute and make it point to:
- the
/datetime/v1base path; - your actual endpoint URL (eg. your IP/port).
Now check the outcome in the terminal.
# Use ex-02-servers-ok.yaml as a reference if you get stuck.
print(f"$ connexion run notebooks/oas3/ex-02-servers.yaml --host {host} --port {port}")
Defining paths¶
The paths section declares the API endpoints and their operations.
Our first path that is the /status one,
that is used for health-checking the API.
This allows implementers to plan a suitable method for testing it (eg. it could be a simple OK/KO method or can execute basic checks like: databases are reachable, smoke testing other components, ..)
Caveats on /status¶
NB: the /status path is not a replacement for proper monitoring your APIs, but a way to communicate to your peers that you're online.
Without it, clients may implement custom ways to check your API,
such as issuing real requests (e.g. GET /datetime/v1/now)
that may result in unintended side effects (e.g., hitting always the same
database entries, hitting caches, ..).
Paths anatomy¶
paths references:
- the associated METHODs (eg. get|post|..)
- a
summaryand adescriptionof the operation
/status:
get:
summary: Returns the application status.
description: |
This path can randomly return an error
for testing purposes. The returned object
is always a problem+json.
- an identifier, that
connexionuses to map to the python callable
operationId: get_status
- the HTTP statuses of the possible responses, each with its description, media type and examples
responses:
'200':
description: |
The application is working properly.
content:
application/problem+json:
example:
status: 200
title: OK
detail: API is working properly.
default:
description: |
If none of the above statuses is returned, then this applies
content:
application/problem+json:
example:
status: 500
title: Internal Server Error
detail: API is not responding correctly
Exercise {#ex-status-stub}¶
- open ex-03-02-path.yaml eventually copy/paste the code from/to the swagger editor.
- complete the
get /statuspath - use the OAS Checker :warning: with the "Italian Guidelines Full + Extra Security Checks" profile to identify and fix syntax errors.
- what's the name of the function referenced by
#/paths/status/get/operationId?
We haven't implemented the function referenced by operationId,
so to run the spec in a terminal
we tell connexion to ignore unimplemented methods with --mock notimplemented:
(
"bash$"
"connexion run notebooks/oas3/ex-03-02-path.yaml"
f" --host {host} --port {port}"
" --mock notimplemented"
)
Exercise {#ex-status-mock}¶
- What happens if I get the
/statusresource of my API now? - And if I invoke another path which is not mentioned in the spec?
- Edit api.py and rename
_get_statusfunction toget_status. What happens if you call the/statusresource now? - Restart the server using
--mock alland call/statusagain. What happens now?
# Exercise: what's the expected output of the following command?
!curl http://0.0.0.0:5000/datetime/v1/status
# Exercise: what happens if you GET an unexisting path?
!curl http://0.0.0.0:5000/datetime/v1/MISSING