Package: ripozo-oasis
# How to turn your database into a ReSTful API in under 10 lines of codeA package to turn your database into a ReSTful API in just 10 lines of code.You can either install the package and simply start the API from thecommand line or you can follow this tutorial to build it yourself.## Installation```bashpip install ripozo-oasis```## Running your APITo turn your database into a ReSTful API simply run the following command.```bashauto-api "mysql://localhost:3306/mydatabase"```You will need to pass a Database URI according to the[SQLALchemy Engine Configuration documentation](http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html).The format is `'dialect+driver://username:password@host:port/database_name'`.The driver is optional and only necessary if you do not wish to use the default.  If you get import errorsyou will need to install a specific driver for your database.  For example, with MySQL you'll needto run ``pip install mysql-python`` or for postgresql you'll need to run ``pip install psycopg2``.Now we can curl the base to get all available endpoints```bashcurl -X OPTIONS http://localhost:5000/```We may see something like this assuming we had two tables, groups and users.```javascript{"_embedded": {},"_links": {"group": {"href": "/group/"},"user": {"href": "/user/"},"self": {"href": "http://localhost:5000/"}}}```We could additionally vary the accept type to get a SIREN formatted response```bashcurl -X OPTIONS -H "Accept: application/vnd.siren+json" http://localhost:5000/``````javascript{"entities": [],"class": [""],"links": [{"href": "http://localhost:5000/","rel": ["self"]},{"href": "http://localhost:5000/group/","rel": ["group_list"]},{"href": "http://localhost:5000/group/<id>/","rel": ["group"]},{"href": "http://localhost:5000/user/","rel": ["user_list"]},{"href": "http://localhost:5000/user/<id>/","rel": ["user"]}],"actions": [{"fields": [],"href": "http://localhost:5000/","title": "All Options","method": "OPTIONS","name": "all_options"}],"properties": {}}```We have full CRUD+L (Create, Retrieve, Update, Delete and List) operations: a POST to ``/user/`` createsa new user, a GET to ``/user/`` returns a list of all users, a GET on ``/user/<id>/``returns an individual user and so forth.## TutorialThis tutorial uses a powerful and extensible ReST framework called[ripozo](https://github.com/vertical-knowledge/ripozo) and a couplepackages in the ripozo ecosystem: [flask-ripozo](https://github.com/vertical-knowledge/flask-ripozo)and [ripozo-sqlalchemy](https://github.com/vertical-knowledge/ripozo-sqlalchemy).  Ripozois web framework independent, meaning you can use it in any desired web framework.Official integrations include [flask-ripozo](https://github.com/vertical-knowledge/flask-ripozo)and [django-ripozo](https://github.com/vertical-knowledge/django-ripozo) with more to come.In addition to building seamless ReSTful API's, ripozo can expose [Hypermedia/HATEOAS](http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)driven API's with *no additional effort*.### Step 1: Create the Flask AppThe first step is to setup our [Flask](https://github.com/mitsuhiko/flask) application.You can use [django-ripozo](https://github.com/vertical-knowledge/django-ripozo)with minimal deviations from this tutorial.Unfortunately, bootstrapping a django project requires more than 10 lines of code.First, install Flask.```bashpip install Flask```Now instantiate a Flask Application.```pythonfrom flask import Flaskapp = Flask(__name__)```### Step 2: Setup SQLAlchemy[SQLAlchemy](http://www.sqlalchemy.org/) is another favorite tool of mine.  It providesan excellent ORM and allows us to generate an ORM from an existing databasewith no additional work.```bashpip install SQLAlchemy```Creating a sqlalchemy engine is incredibly simple.  We simplypass SQLAlchemy a database URI in the expected format.  Seethe [Engine Configuration documentation](http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html)for more details. TL;DR this is the general format:`'dialect+driver://username:password@host:port/database_name'````pythonfrom sqlalchemy import create_enginefrom sqlalchemy.ext.automap import automap_basedatabase_uri = 'mysql://localhost:3306/mydatabase'engine = create_engine(database_uri)base = automap_base()base.prepare(engine, reflect=True)```This creates an ORM where we can access tables in the databaseas python objects.### Step 3: Bind ripozoNow that we have our database and web application working, we need to bind[ripozo](https://github.com/vertical-knowledge/ripozo) to Flask and SQLAlchemy.```bashpip install ripozo flask-ripozo ripozo-sqlalchemy``````pythonfrom flask_ripozo import FlaskDispatcherfrom ripozo import adaptersfrom ripozo_sqlalchemy import ScopedSessionHandler# Attach the previously create Flask applicationdispatcher = FlaskDispatcher(app)# Adapters inform ripozo how to represent the resources over HTTP (typically a# protocol for a JSON response).  In this case, we've chosen the Hal and SIREN protocols.dispatcher.register_adapters(adapters.SirenAdapter, adapters.HalAdapter)# Create a session handler to cleanly handle database transactions and cleanupsession_handler = ScopedSessionHandler(engine)```### Step 4: Expose our databaseNow that we have completed all necessary setup, we canexpose our database as a ReSTful API.```python# The create_resource method is a shortcut for creating ripozo resources# containing common sets of endpoints.# We need to pass append_slash=True due to a quirk in how flask handles routingresources = [create_resource(model, session_handler, append_slash=True) for model in base.classes]# Register the resources with the adapter to expose them in the API.dispatcher.register_resources(*resources)# and now we run our Flask appapp.run()```The ``create_resource`` method is highly customizable.  Additionally, you can use adeclarative, class based implementation that is incredibly flexible.  In fact,the ``create_resource`` method uses the declarative implementation under the covers.### Step 5: Putting it all togetherNow that we have everything we need, let's put it all togetherinto one function.```pythonfrom flask import Flaskfrom flask_ripozo import FlaskDispatcherfrom ripozo import adaptersfrom ripozo_sqlalchemy import ScopedSessionHandler, create_resourcefrom sqlalchemy.ext.automap import automap_basefrom sqlalchemy import create_enginedef create_app(database_uri):app = Flask(__name__)engine = create_engine(database_uri)base = automap_base()base.prepare(engine, reflect=True)dispatcher = FlaskDispatcher(app)dispatcher.register_adapters(adapters.HalAdapter, adapters.SirenAdapter)session_handler = ScopedSessionHandler(engine)resources = [create_resource(model, session_handler, append_slash=True) for model in base.classes]dispatcher.register_resources(*resources)app.run()```And just like that we have exposed our database as a ReSTful API.  Additionally,because this is [ripozo](https://github.com/vertical-knowledge/ripozo), if a tablehas a relationship to another table, a link to the corresponding row/resource isautomatically generated.  For example, consider a user table has a Many-to-One relationship with a group table.When we go to a user's endpoint, we'll get a fully qualified URL linking to the associated group's endpoint.## ConclusionWe can see how easy [ripozo](https://github.com/vertical-knowledge/ripozo) makescreating ReSTful API's.  With [ripozo](https://github.com/vertical-knowledge/ripozo),you can include authentication and authorization, additional endpoints and much more.[Ripozo](https://github.com/vertical-knowledge/ripozo) is designed to be flexible andefficient at the same time.  It provides shortcutswhile priotizing extensibility.  It unleashes more flexibility and power thanany other Hypermedia/HATEOAS ReSTful framework.  Ripozo: less effort, better APIs.