Proposal: API for databases #52
Description
Along with providing a database hosting service, DBHub provides an API for managing your hosted database. Combined with Serverless services (e.g. AWS Lambda, Google Cloud Functions, Microsoft Azure Functions) users are able to create beautiful web applications/services by using the DBHub API.
While this Serverless computing model frees you from having to manage a server, it does not free you from writing, debugging, testing, and running code. Not to mention the disappointment of finding out that your favorite programming language is not supported, or severely restricted, by your service provider.
DBHub could provide a solution for that.
Why?
Most web applications/services that expose an API are just wrappers for a database. They do so by running a server that waits for certain URLs (endpoints) to be accessed and then query a database and return the result.
The process is simple, yet it requires you to write a lot of boilerplate code just to get your API running. And you have to change your code if you want to add/remove new endpoints or if you made any changes to the database.
DBHub could simplify this by handling all that for you.
How?
For every database hosted on DBHub, a new option/dialog to Create an API or Create an Endpoint should be available. In it, the user will edit two things:
- An endpoint (e.g.
/endpoint
) - A query to be executed when that endpoint is accessed (e.g.
"SELECT * FROM my_table"
)
DBHub then, by running a service/server at api.dbhub.io
exposes each user endpoint at api.dbhub.io/user
so /endpoint
URL for the user karim
will be accessed at api.dbhub.io/karim/endpoint
.
You can create unlimited number of endpoints and access them within minutes of creating them and without the need to write a single line of code.
Implementation
As a proof of concept, I have created a simple server that provides this functionality to DBHub. The server is located here (https://github.com/karim/randa) and can be tested and used as a standalone app. Just build it and start it and you will have your own API without writing any code at all.
The only thing you need is to create a YAML configuration file to set your database file and your API endpoints.
The file should look like this:
# The SQLite database file
database: database_file.sqlite
# The list of endpoints that the server should handle
endpoints:
- url: GET /endpoint
query: SELECT * FROM `table_name`
- url: GET /endpoint/with/{param}
query: SELECT * FROM `table_name` WHERE `column_name` = {param}
When you try to access the endpoints, and depends on your query, you will get something like this:
{
"column1": "value",
"column2": "value",
"column3": "value"
}
Note 1: The column names and values will be returned as-is without any modifications. If you have a ColumnName
and you prefer it to be returned as column_name
, just do it in the SQL query.
Something like: SELECT ColumnName AS column_name FROM ...
Note 2: NULL
values are not returned in the result. This allows you to distinguish between a column that has a value and this value is an empty string ""
(or 0
for integers) and between a column with no value.
So, just start the server and your API is ready to use. The code to create routing for urls, opening & querying the database, returning the result, and converting it to JSON is already done for you.
A real-world example should make this even more clear.
Example:
For this example I will be using Belfast Bikes Docking Stations database.
Let's say you are creating a Mobile/Web app that shows the locations of Belfast Bikes docking stations.
The app will have something like a MapView, when started it will show a map with all stations as markers/points, and you will be able to click any of them to get more information about each station.
The first thing to do is to upload this database to DBHub. Then you have to create a few endpoints to make it expose a public API that can be used by (mobile/web) clients.
The first endpoint will be /stations
. This one will just query all the stations locations (lat/long only) since that's what we need to display the markers on the map. The second endpoint will be /dock/{id}
, and this one will be used when we click on one of the markers.
The config file should be something like this:
database: Belfast+Bikes+Docking+Stations.sqlite
endpoints:
- url: GET /stations
query: SELECT Dock AS id, Latitude AS lat, Longitude AS long FROM `stations`
- url: GET /dock/{id}
query: SELECT * FROM `stations` where `Dock` = {id}
When you open the app, it should make a call to your /stations
endpoint, which should return something like:
...
{
"id": 3903,
"lat": 54.598224,
"long": -5.924024
},
{
"id": 3904,
"lat": 54.601309,
"long": -5.92187
},
...
After checking the map and finding the docking station you are interested in, you click on it, and this will make the app access the second endpoint /dock/3903
, and the returned JSON object will be:
{
"Dock": 3903,
"Name": "Victoria Square / Victoria Street",
"Latitude": 54.598224,
"Longitude": -5.924024,
"StationSize": 10
}
That's all!
Conclusion
DBHub lets you focus on your application logic and it takes care of your database/API hosting needs.
However, it is still in its early development stage. This issue is opened to get feedback about the best way to integrate this into DBhub. Your feedback is welcome. Please do share your ideas and thoughts.