Understanding and Using RESTful APIs
Yi Sun
December 2, 2022
In the era of Internet of Everything, there are many different APIs, and it is important to standardize them. The RESTful API is one of the most popular API architecture styles, which can help you separate client-side and server-side concerns, allowing the front and back ends to iterate separately thus improving efficiency. Its stateless feature can make the application more scalable and easier to implement caching policies to improve user experience and performance. In this article, we will introduce what is RESTful API and how we can use it.
What Is API
Putting aside what an API is for a moment, let's talk about how we deliver information in our lives.
When you take your money to the owner at the store and tell him you need to buy batteries, the owner receives the money, finds the batteries on the shelf and hands them to you. A transaction to buy a battery is successfully completed.
Computer software, on the other hand, completes this through APIs. Let's start with the Wikipedia definition:
An application programming interface (API) is a way for two or more computer programs to communicate with each other. It is a type of software interface, offering a service to other pieces of software.
Software A makes a request to Software B through the API, and Software B returns the response to A through the API after querying its resources.
Software A making a request to Software B through the API is like you telling your boss that you need a battery, and Software B returning the data to Software A is like your boss finding the battery and giving it to you.
This process does not require Software B to know why Software A wants the data, just as a store owner would not ask you why you bought the battery. Software A also does not need to know how software B found the data, just as you would not ask the owner where the batteries were purchased when you bought them. Each software passes information to each other through APIs, and each does its own thing, making the programming world orderly and reliable.
What Is RESTful API
Roy Fielding defined REST (Representational state transfer) in his 2000 Ph.D. dissertation, "Architectural Styles and Web-Based Software Architecture Design," and the REST architectural style defines six guiding constraints. A system that conforms to some or all of these constraints is loosely referred to as RESTful.
(Source: Seobility)
Constraints of RESTful APIs
Constraints | Details | Benefits |
---|---|---|
Client–server architecture | Improve portability of the user interface across multiple platforms by separating user interface issues from data storage issues, and improve scalability by simplifying server components. | 1. Client-side and server-side decoupling. 2. Enhance the portability of user platforms across platforms. 3. Enhance server-side scalability. |
Statelessness | Each request from the client to the server must contain all the information required for the request and must not make use of any context stored on the server, and the session state is stored entirely on the client. | 1. Easy to scale, no session dependencies and any server can handle any request. 2. Easy for caching to improve program performance. |
Cacheability | Require the data in a request or response to be implicitly or explicitly marked as cacheable or non-cacheable. If a response is cacheable, then the client cache is granted the right to reuse that response data for subsequent equivalent requests. | 1. Reduce bandwidth. 2. Reduced latency. 3. Reduce server load. 4. Hide the network status. |
Layered system | Constrained component behaviour allows the architecture to be composed of layers so that each component cannot "see" beyond the immediate layer with which they interact. By limiting system knowledge to a single layer, the complexity of the whole system is reduced and underlying independence is promoted. | 1. Reduce the complexity of the overall system. 2. Promote independence at the bottom. 3. Load balancing can be easily implemented. 4. Business logic and security policies can be decoupled. |
Code on demand (optional) | Allow client functionality to be extended by downloading and executing code in the form of applets or scripts. | 1. Improve the scalability of the system. |
Uniform interface | Contain four main points: 1. Resource identification in requests. Clients are able to identify a resource by the URI contained in the request, decoupling the server-side resource from the client-requested resource. 2. Resource manipulation through representations. When a client has the representation of a resource, such as a URI, then there is enough information to modify or delete the resource. 3. Self-descriptive messages. Every message includes enough information to inform the client what to do with the message. 4. Hypermedia as the engine of application state (HATEOAS). The client does not need any additional coding to make all the resources available to the user via the resource links returned by the server. | 1. Simplify the overall system architecture. 2. Improve visibility of interactions. |
Restful API Best Practice
The emphasis on unified interfaces between components is a core feature that sets the REST architectural style apart from other web-based styles, and based on this feature, best practices are sorted out here to help you better design your API.
Avoid Verbs in Path Name
Use HTTP methods to express resource manipulation behavior, instead of defining behavior verbs into paths.
// Good
curl -X GET http://httpbin.org/orders
// Bad
curl -X GET "http://httpbin.org/getOrders"
- Get the resource information for the specified URI using GET
// Represents getting all the order information for the current system
curl -X GET http://httpbin.org/orders
// Represents getting the order detail information for order number 1
curl -X GET http://httpbin.org/orders/1
- Create a resource from the specified URI using POST
// Represents the creation of a resource with the name order
curl -X POST http://httpbin.org/orders \
-d '{"name": "awesome", region: "A"}' \
- Create or fully replace resources on the specified URI using PUT
// Represents data replacement for an order with id 1
curl -X PUT http://httpbin.org/orders/1 \
-d '{"name": "new awesome", region: "B"}' \
- PATCH performs a partial update of a resource
// Represents changing the region field of the order with id 1, while keeping the rest of the data unchanged
curl -X PATCH http://httpbin.org/orders/1 \
-d '{region: "B"}' \
- Remove a resource by specifying a URI using DELETE
// Represents the deletion of the order with id 1
curl -X DELETE http://httpbin.org/orders/1
URIs Use the Plural Form
If you want to use the singular form to indicate access to a particular type of resource:
curl -X GET "http://httpbin.org/order"
Using the singular form will confuse the user that there is only one order in the system, but using the plural form will make it much smoother to understand.
curl -X GET "http://httpbin.org/orders"
Making Good Use of HTTP Status Codes
The HTTP standard defines status codes, which can be broadly classified into the following categories:
Status Codes | Meaning |
---|---|
2xx | Success, the operation was successfully received and processed |
3xx | Redirect, further action is required to complete the request |
4xx | Client error, the request contained a syntax error or the request could not be completed |
5xx | Server error, an error occurred while the server was processing the request |
Using standard status codes, developers can immediately identify problems and can reduce the time it takes to find different types of errors.
Version Control
As business requirements change, the APIs that are already online will most likely have to be adjusted accordingly. If our APIs are used by third parties, it is obviously impossible to let every client change according to the changes of our APIs, so it is time to introduce the concept of API version management, which can ensure the normal use of historical APIs and iterate new APIs to meet new business requirements.
Common means of version control are:
- Version Control via Paths in Requests
// Request v1 API
curl http://httpbin.org/v1/orders
// Request v2 API
curl http://httpbin.org/v2/orders
- Version Control via Query Parameters
// Request v1 API
curl http://httpbin.org/orders?version=v1
// Request v2 API
curl http://httpbin.org/v2/orders?version=v2
- Version Control via Header
// Request v1 API
curl http://httpbin.org/orders -H "custom-version: v1"
// Request v2 API
curl http://httpbin.org/orders -H "custom-version: v2"
How APISIX Empowers RESTful API
Apache APISIX is a dynamic, real-time, high-performance API gateway. It can run in front of any RESTful API service and use plugins to add new services and extend its functionality, which is in line with the RESTful definition of Layered System. In addition, for some historical services that do not follow the RESTful API definition, APISIX can also help you convert your interface without changing the original business code so that your interface fulfills the REST restriction of Uniform Interface, making your API better comply with the RESTful API specification.
Layered System: Supports Splitting of Business Logic and Security Logic
You can just focus on the implementation of the business logic, the security logic of the interface can be left to the APISIX Authentication class plugins, e.g. key-auth. APISIX supports a large number of Authentication plugins, let's take openid-connect for example, as shown in the following figure:
We can see that using APISIX (API Gateway) to add a layer of authentication logic in front of our business server can serve to protect the upstream services, and this architectural pattern can be a good way to decouple your business logic from the security logic.
Layered System:Multi-load Balancing Protocol Support
APISIX, as an API gateway, can be set up between the client and server side to fulfill different load requirements. You can even customize the load-balancing logic.
The supported load-balancing algorithms are:
roundrobin
: Round robin balancing with weights.chash
: Consistent hash.ewma
: Pick the node with minimum latency. See EWMA Chart for more details.least_conn
: Picks the node with the lowest value of(active_conn + 1) / weight
. Here, an active connection is a connection being used by the request and is similar to the concept in Nginx.- user-defined load balancer loaded via
require("apisix.balancer.your_balancer")
Uniform Interface: Make Historical APIs More RESTful
For historical APIs that have been around for a long time and do not follow the RESTful API guidelines well, you can re-encapsulate the new API through APISIX to meet different business scenarios without modifying the original API logic.
- Use proxy-rewrite to rewrite client requests
As mentioned above, we should not have verbs in our path.
For example, if the historical API has the /getOrder
interface, we can proxy the API request to the historical API via the proxy-rewrite plugin.
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/orders",
"plugins": {
"proxy-rewrite": {
"uri": "/getOrder",
"scheme": "http",
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:80": 1
}
}
}'
You can also use the plugin for API versioning operations.
- Use the response-rewrite plugin to rewrite server-side responses
When our historical API has unstandardized response status codes, we can use response-rewrite to proxy the response to modify the response status code.
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/orders",
"plugins": {
"response-rewrite": {
"status_code": 201,
"body": "{\"code\":\"ok\",\"message\":\"new json body\"}",
"vars":[
[ "status","==",200 ]
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:80": 1
}
}
}'
The above example represents a request to modify the status of 200 to 201 in the API requesting the /orders path.
Since APISIX supports very rich plugins, I am looking forward to you exploring more ways to play.
Summary
This article introduces what an API is, what a RESTful API is, and its best practices. In addition, this article also introduces how to separate business logic and security logic through APISIX, and how to use APISIX to make historical API services more RESTful without changing the original business code. Hope this article will help you understand RESTful APIs.