Timeserver is a simple server application that showcases OpenAPI and Swagger UI.
The main focus of this project is building and serving the API and GUI. The home page is simply the current time in some time zone.
$ curl localhost:8081
"2020-10-25T12:35:50.39742994Z"
The API allows us to modify the behavior of the server. We can change the time zone of the time that it serves, and adapt the logging level.
By default, the time zone is UTC. With a simple call to the API, the time zone can be changed to any value in IANA Time Zone Database
$ curl -X PUT "http://localhost:8081/api/timezone" -H "X-API-KEY: 777269746572" -H "Content-Type: application/json" -d "{\"timezone\":\"Europe/Zurich\"}"
{
"timezone": "Europe/Zurich"
}
Another query of the home page reveals that the time zone was changed:
$ curl localhost:8081
"2020-10-25T13:44:54.059408243+01:00"
To explore the API, the time server also hosts a Swagger
UI under the /ui
route.
To start the server run make run
. At this point, the server will not have
any API keys configured. Add a key by calling the api-key add
sub-command:
go run cmd/timeserver/*.go api-key add --user john --role admin <API-KEY>
Now, the serve will pick up the API key from the file system, and you can start
API requests by providing the X-API-KEY
header.
The API is specified in the OpenAPI3 format. The spec file describes all the available end points. They are grouped into three groups:
config
admin
token
The config
endpoints allow interacting with the server configuration. This API
allows querying and setting the logging level of the server, and querying and
setting the time zone.
The admin
endpoints allow querying, adding, modifying and deleting API tokens.
The token
endpoint returns a JWT token that can be used to access the API.
This is mainly done to showcase how we can use both API key and JWT for
authorization at the same time.
Each user that is know to the server has a role associated with them. There are three roles, each giving varying set of access to the API.
config:reader
config:writer
admin
The config:reader
and config:writer
have access to the config and token
endpoint. The config:reader
can only use the GET endpoints of the API. The
config:writer
can use both the PUT and the GET endpoints. Both of them can
only obtain a JWT with their role or a less privileged role from the token
endpoint.
The admin
has access to all of the API.
The API key or the JWT bearer token need to be part of the headers when accessing the API.
The Swagger UI helps with the discoverability of the API. It allows us to visually explore all of the API definitions.
For example, by expanding the PUT /log/level
endpoint, we can see a sample
request body, and all of the possible response bodies and status codes.
By clicking on the lock on the top right, you can set the API key or the JWT
to authorize the requests. By clicking Try it out
, you can start API requests
from the GUI directly.
We use three tools to do code generation:
- github.com/deepmap/oapi-codegen
- github.com/markbates/pkger
- github.com/oncilla/boa
Install them in order to update the generated files.
When updating the spec, the generated API code should be updated as well:
make gen
When updating the static Swagger UI files, the packaged gile should be updated as well:
make pkger
This project is there to show case the OpenAPI 3 spec and the serving the Swagger UI from the server directly. This is not production grade code, and should not be used that way. I hope that you already have guessed it based on the lack of any testing :).