102 lines
4.0 KiB
Markdown
102 lines
4.0 KiB
Markdown
|
---
|
||
|
title: REST APIs with Falcon
|
||
|
---
|
||
|
|
||
|
|
||
|
## Introduction
|
||
|
|
||
|
RESTful APIs are a major component of any well-architected stack, and Python happens to have some brilliant frameworks for quickly composing APIs. One of these frameworks is called [Falcon](https://falconframework.org) - and it's great! Essentially a microframework, it ships with a sizable number of advantages:
|
||
|
|
||
|
1. It's fast. Really fast. Check out the benchmarks [here](https://falconframework.org/#sectionBenchmarks).
|
||
|
|
||
|
2. HTTP Resources are defined as classes, with class methods being used for different REST operations on these resources. This helps maintaining a clean codebase.
|
||
|
|
||
|
3. It's quite extensible - check out [this section](https://github.com/falconry/falcon/wiki/Complementary-Packages) on their wiki, to get a feel for it.
|
||
|
|
||
|
4. It's based on WSGI - the Pythonic standard for web apps - so it works with Python 2.6, 2.7, and 3.3+. And if you need more performance, run it using PyPy!
|
||
|
|
||
|
|
||
|
## Getting started
|
||
|
|
||
|
First, let's prepare our environment. Personally, it's always great to work in virtual environments - you can use `virtualenv`, `virtualenvwrapper` or `venv`. Next, install Falcon using `pip`: `pip install falcon`.
|
||
|
|
||
|
We're going to develop a small sample API that does very basic time-zone manipulations for us. It will display the current time in UTC, as well as the corresponding epoch time. To that end, we'll grab a nifty library called `arrow`: `pip install arrow`.
|
||
|
|
||
|
You can find the finished sample at [https://github.com/rudimk/freecodecamp-guides-rest-api-falcon](https://github.com/rudimk/freecodecamp-guides-rest-api-falcon).
|
||
|
|
||
|
## Resources
|
||
|
|
||
|
Think of a resource as an entity that your API needs to manipulate. In our case, the best resource would be a `Timestamp`. Our routing would typically be something like this:
|
||
|
|
||
|
```
|
||
|
GET /timestamp
|
||
|
```
|
||
|
|
||
|
Here, `GET` is the HTTP verb used to call this endpoint, and `/timestamp` is the URL itself. Now that we've gotten this bit out of the way, let's create a module!
|
||
|
|
||
|
`$ touch timestamp.py`
|
||
|
|
||
|
Time to import the Falcon library:
|
||
|
|
||
|
```python
|
||
|
|
||
|
import json
|
||
|
|
||
|
import falcon
|
||
|
|
||
|
import arrow
|
||
|
|
||
|
```
|
||
|
|
||
|
Note we've also import the `json` package and the `arrow` library. Now, let's define a class for our resource:
|
||
|
|
||
|
```python
|
||
|
|
||
|
class Timestamp(object):
|
||
|
|
||
|
def on_get(self, req, resp):
|
||
|
payload = {}
|
||
|
payload['utc'] = arrow.utcnow().format('YYYY-MM-DD HH:mm:SS')
|
||
|
payload['unix'] = arrow.utcnow().timestamp
|
||
|
|
||
|
resp.body = json.dumps(payload)
|
||
|
resp.status = falcon.HTTP_200
|
||
|
|
||
|
```
|
||
|
|
||
|
Let's go through this snippet. We've defined a `Timestamp` class, and defined a class method called `on_get` - this function tells Falcon that when a `GET` request is issued to an endpoint for this resource, run the `on_get` function and provide the request and response objects as parameters. After that, it's smooth sailing - we create an empty dictionary, fill it up with the current UTC and UNIX timestamps, convert it to JSON and attach it to the response object.
|
||
|
|
||
|
Pretty simple, right? But sadly, that's not all. We now need to create a Falcon server and hook up the resource class we've just defined to an actual endpoint.
|
||
|
|
||
|
`$ touch app.py`
|
||
|
|
||
|
Now, add the code below:
|
||
|
|
||
|
```python
|
||
|
|
||
|
import falcon
|
||
|
|
||
|
from timestamp import Timestamp
|
||
|
|
||
|
api = application = falcon.API()
|
||
|
|
||
|
timestamp = Timestamp()
|
||
|
|
||
|
api.add_route('/timestamp', timestamp)
|
||
|
|
||
|
```
|
||
|
|
||
|
Here, we've defined a Falcon API, and initialized an instance of the resource class we created earlier. Then, we've hooked up the `/timestamp` endpoint with the class instance - and now we're good to go! To test this API install `gunicorn`(`pip install gunicorn`), and run `gunicorn app`. Use Postman or simple `cURL` to test this:
|
||
|
|
||
|
```
|
||
|
|
||
|
$ curl http://localhost:8000/timestamp
|
||
|
{"utc": "2017-10-20 06:03:14", "unix": 1508479437}
|
||
|
|
||
|
```
|
||
|
|
||
|
And that does it!
|
||
|
|
||
|
## Moving on
|
||
|
|
||
|
Once you've got the hang of Falcon, composing powerful RESTful APIs that interact with databases or messaging queues is very easy. Do check out the [Falcon docs](https://falcon.readthedocs.io/en/stable/index.html), as well as PyPI for interesting Falcon modules that keep popping up.
|