A surfer who won dozens of international surfing competitions became a surfing coach and wants to build a new tool to help surfers train for the Olympic Games. The development team that works with the surfing coach has years of experience working with the Pyramid web framework, and therefore, he wants us to build a simple RESTful API with Pyramid to work with the data provided by an IoT board connected to multiple sensors in the surfboards.
Each IoT board will provide the following data:
- Status: Many wearable wireless sensors embedded in each surfer's wetsuit and other sensors included in the surfboard will provide data, and the IoT board will perform a real-time analysis to indicate the action that the surfer is performing
- Speed: A sensor will measure the surfboard's speed in miles per hour (MPH)
- Altitude: A sensor will measure the surfboard's altitude in feet
- Water temperature: A sensor located in one of the surfboard's fins will measure the water temperature in degrees Fahrenheit
Some third-party software is running on the IoT board and makes calls to a RESTful API. There is a team writing code to interact with the RESTful API and retrieve the previously explained surfing metrics provided by the IoT board. Hence, we will have an IoT board and an application interacting with the RESTful API. Another team has to start working on a mobile app and a website that has to interact with the RESTful API to perform create, read, and delete operations with surfing metrics.
We don't need an ORM (short for Object-Relational Mapping) because we won't persist the metrics on a database. We will just work with an in-memory dictionary as our data source. It is one of the requirements we have for this RESTful API. In this case, the RESTful web service will be running on a low-power IoT device capable of running Python 3.6.6 and Pyramid.
The team has chosen Pyramid because they already have experience building web applications with this framework and they want to be able to easily maintain the code for the RESTful API. Pyramid is a lightweight and simple framework; we don't need to configure an ORM and we want to start running the RESTful API on the IoT device as soon as possible to allow all the teams to interact with it.
The IoT board and its connected sensors are capable of distinguishing between the following five possible statuses of a surfer and their surfboard:
Status key |
Meaning |
0 |
Idle |
1 |
Paddling |
2 |
Riding |
3 |
Ride finished |
4 |
Wiped out |
First, we must specify the requirements for our main resource: a surfboard metric. We need the following attributes or fields for a surfboard metric:
- An integer identifier
- A string status
- A speed expressed in MPH
- An altitude (expressed in feet)
- A water temperature (expressed in degrees Fahrenheit)
The following table shows the HTTP verbs, the scope, and the semantics for the methods that our API must support. Each method is composed by an HTTP verb and a scope, and all the methods have a well-defined meaning for all metrics and collections. In our API, each metric has its own unique URL:
HTTP verb |
Scope |
Semantics |
GET |
Collection of metrics |
Retrieves all the stored metrics in the collection |
GET |
Metric |
Retrieves a single metric |
POST |
Collection of metrics |
Creates a new metric in the collection |
DELETE |
Metric |
Deletes an existing metric |
In the previous table, we have many methods and scopes. The following list enumerates the URIs for each scope mentioned in the previous table, where {id} has to be replaced with the numeric id of the resource. We want our API to differentiate collections from a single resource of the collection in the URLs.
When we refer a collection, we will use a slash (/) as the last character for the URL, and when we refer a single resource of the collection, we will omit this slash (/):
- Collection of metrics: /metrics/
- Metric: /metrics/{id}
Let's consider that http://localhost:6543/ is the URL for the API running on the Pyramid development server. We have to compose and send an HTTP request with the following HTTP verb (GET) and request URL (http://localhost:6543/metrics/) to retrieve all the stored metrics in the collection:
GET http://localhost:6543/metrics/
We will always provide the request body in JSON, and all the response bodies will be in JSON. We don't need additional parsers or renderers. Notice that we support neither PATCH nor PUT methods because we don't need them in this API.