The Garage is a RESTful API based on an OpenApi specification spec/garage.openapi.yml
.
The project is based on the generated server stub of the swagger-codegen project. The code generated from the OpenAPI-Spec uses the Connexion library on top of Flask.
The persistence layer makes intentionally no use of an ORM to show transaction handling and some advanced SQL statements.
- implement
decimal
format validation where swagger-codegen falls short - provide default value for
garage.date_created
, ensure ISO8601 format - generate fixtures using https://mockaroo.com
- enforce foreign keys in sqlite settings for integrity and cascading deletions
- create database index on
car.price
for faster comparisons - centralize api response error codes and messages
- pickup host from the API spec and add CORS headers
- implement integration tests, coverage and setup travis CI hook
- move over to a postgresql database
- use gunicorn as a pre-fork production server
- setup an nginx reverse-proxy in front of it
- docker-compose all of the containers
Set up the environnement, create the sqlite database and run the development server:
pip install pipenv
pipenv --python 3.6
pipenv install
pipenv shell
(env)$ python -m database # [re]creates the database
(env)$ python -m swagger_server # may need patch for package `connexion`, see troubleshooting section
Then open your browser at http://localhost:8080/garage/api/1.0.0/ui/
To launch the integration tests, use tox:
sudo pip install tox
tox
To run the server on a Docker container, please execute the following from the root directory:
# building the image
docker build -t demo-garage .
# starting up a container, daemonized
docker run -d -p 8080:8080 demo-garage
Upon launching the server python -m swagger_server
you get the following warning:
ImportError: cannot import name 'FileStorage'
The fix is already under way in package connexion@1.1.16
. Quick fix it in python's lib/site-packages/connexion/decorators/validation.py
with the following
- from werkzeug import FileStorage
+ from werkzeug.datastructures import FileStorage
Sqlite does not enforce foreign keys by default. The setting can be changed using the following command:
PRAGMA foreign_keys = ON;
However, the sqlite installation needs to have been compiled with certain flags (see the docs) for the setting to persist and take effect. To circumvent this shortcoming, the above command can be issued with every new connection.