Guest Post by Fred Williams
A majority of apps developed for mobile devices retrieve their data through an application programming interface (API). In our getting started document, we define an API as a concept in computer programming where a set of services, tooling and protocols make data accessible to applications. Many APIs use Representational State Transfer (REST) that returns data in JSON format as a way to make that data available. Developers hoping to build a robust and flexible REST API usually follow a set of best practices.
This blog post will focus on best practices and tips to follow when developing a REST API, with a special emphasis on those endpoints who have a good chance to be used by mobile clients.
Develop Your APIs to Produce JSON Data
When designing a REST API that mobile apps built with Dropsource will use, it is important to remember that Dropsource apps are designed to connect to a REST API that returns JSON data. Therefore, the REST API must produce and return JSON data. Most modern programming languages allow an environmental setting to specify what the service will produce. Check the documentation to find where to set the MIME type for JSON as application/json in the REST Controllers. If the back end is built using something like Spring Boot, the default is most likely JSON for all REST Controllers marked with a @RestController annotation.
Design APIs Using Key REST Principles
It can be rather difficult to make significant changes to a REST API once it’s been published, so designing it correctly upfront becomes essential. Roy Fielding introduced Representational State Transfer (REST) principles in his network-based dissertation as key architectural designs that developers should follow when designing REST APIs. One of Fielding’s key principles is to separate an API into logical resources. These logical resources should be represented using nouns and the resources should be manipulated using common HTTP verbs.
The URL for each endpoint should use nouns to clearly state what resource is represented. Remember to be consistent with resource names and strive towards using plural nouns. For example, favor “persons” over “person” and “books” over “book”. Do not mix up singular and plural nouns in your API. This way when users are developing against the API, they will not have to guess which way to go.
For REST APIs, common HTTP verbs provide us the action counterpart to our noun based resources. The most commonly used HTTP verbs (or methods as they are also referred to) are POST, GET, PUT, PATCH, and DELETE. These are not a complete list of all available verbs (OPTIONS and HEAD can also be used) but are the ones to become most familiar with. Here is a summary of what each HTTP verb can do:
- POST – Save a new representation of a resource.
- GET – Request the state of a specified resource. Get is not used to save or update data.
- PUT – Update the state of an existing resource.
- PATCH – Partially update the state of an existing resource. This is helpful when dealing with complex data.
- DELETE – Delete a specified resource.
PUT and PATCH may seem to almost mean the same thing as they both are designed to make updates on an existing resource. PATCH is not used as often as PUT but it’s important to understand the difference. The difference is that PUT is used to entirely replace a resource where PATCH is used to only partially replace a resource.
REST API Route Example
Consider the following example for a user management system. When managing users, a system should be able to add new users to the database, modify the user’s attributes, delete a user and assign roles. The following Swagger example show a series of simple API endpoints defining a top level resource called ‘persons’. Each endpoint clearly states the noun (persons) each endpoint represents and the action (HTTP verb) being taken:
Swagger Implementation of Person REST API Example.
Resources do not exist in isolation but most of the times have relationships to other resources. A best practice to follow when deciding how to model relationships in your REST API is to consider which way would be the most clear for the API user. A good rule is to use a “belongs to” relationship. For example, in the previous user management system, a person could have a set of roles associated with their profile. To represent a resource that returns a person’s roles given a user name, the following URL would be used:
In this example, the roles can be thought of as ‘belonging to’ a person. A potential API user could look at this URL and without knowing anything about the overall API structure, could figure out what this resource does.
Here are a few more examples of URLs that model a relationship between a top level resource and sub resources. These examples show how HTTP verbs work to manipulate resource relationships.
Document your API using the OpenAPI Specification
The world’s best REST API could be developed but how useful is it if no developer can discover it or figure out what it offers? In order for API users gain visibility into your REST API and make it as user friendly as possible, document the API using the OpenAPI specification. When using Dropsource to develop mobile apps, Dropsource requires that any REST API being used have all the endpoints documented using an OpenAPI specification.
OpenAPI allows your documentation to grow interactively as you write code. This is crucial. For anyone who has ever been responsible for writing documentation, it becomes very clear that it usually lags behind the code. Or worse yet, it lacks complete API coverage. Without concise documentation, API users may not necessarily know what each field represents. A On top of that, many IT shops have development, staging, and production environments with different URLs. Building an interactive documentation set will handle those differences as well. When API documentation is online it encourages developers to visualize and consume your endpoints.
OpenAPI and Java Spring Boot Example (using annotations)
Here is an example of how to wire in OpenAPI into a Java Spring Boot application built using Gradle. Spring Boot provides annotations that make it easy to document your rest services for OpenAPI. By embedding the OpenAPI dependencies in the project, even a nice UI will be automatically created and updated. This provides a nice interface for client developers to discover your REST API and examine what types of objects will be returned. Developers can even see examples of the JSON represented objects, all return codes, and even try out the API directly in the Swagger UI.
Java code to configure Swagger for use within the application. After writing the Swagger configuration object, then a developer will add annotations to the REST objects that describe what each endpoint will produce.
After writing the Swagger configuration object, a developer will add annotations to the REST objects that describe what each endpoint will produce. Note: most modern programming languages contain support for OpenAPI, so if Spring Boot is not being used, consult the documentation for the chosen language to get more information.
Java code that uses annotations to document REST API endpoints
Once this code is in place, the developer can open up a browser and go to the URL generated within the application to view the Swagger UI.
Swagger UI that shows an example REST API endpoint
Let the server do the work
When developing a REST API, it is expected that a wide variety of different clients including mobile devices will be accessing it. Whether the client is an Android, IOS, Ipad or a Windows 10 desktop, all of the intensive processing, number crunching, and business rules should be done on a powerful remote server. Offloading this processing is critical because of the hardware restrictions imposed by mobile devices. Battery life, limited memory and potential costly data charges are a few restrictions that dictate that much of the processing be offloaded to back end servers.
Paging, filtering and sorting using query parameters
Offload filtering, pagination, and sorting processing to the server by using query parameters. This gives the REST API flexibility while keeping the API endpoint count small and manageable. This is especially important for mobile clients so the client doesn’t have to process larger amounts of data.
For example, the following endpoints allow a mobile client to change the desired sorting direction and still use the same endpoint:
To limit response data, URL parameters can represent pagination and specify the maximum results to get back from an endpoint. This can significantly reduce the amount of data going over the network. For example, consider this request for all users in a system that will return data for the first page in a list where only 50 results will be returned.
Then, if a user clicks ‘next’ to go to the next page, the URL can be constructed to change the ‘page’ query parameter to 2 and return the next 50 records in a result set.
Two Ways to Version an API
During the design phase of the first version of a REST API, a versioning scheme should be implemented. This way, when subsequent releases are being deployed, current clients can continue to use the existing API while new features are being released on the new API. There are two general mechanisms for REST API versioning:
- URL versioning – Add the version as part of the URL structure
- Vendor-specific media type versioning – Versioning the resource representation
Both ways are considered valid so which mechanism to adopt is up to the individual team to decide. URL versioning allows API users to explore the API a little easier since a browser can be used for most requests. Media type versioning requires a more programmatic effort since tools such as Postman must be used to see header and body information. URL versioning also has a benefit of easily being able to figure out the version of a service at a glance. Remember again to be consistent once a versioning scheme is implemented.
URL versioning is implemented by adding the version number directly in the URL. Building upon our previous user management system example, say a first release of the system goes out the door using URL versioning. The following endpoint to get a list of all users in a system would then be available:
- Then say some deprecated fields need to be removed from the returning payload, so version 2 is released. The endpoint for this release would be the following:
- The result is that for each new release of the API, new URLs are created.
Media Type Versioning
Compare this approach to media type versioning. In media type versioning, the URLs stay the same and the version scheme is represented in a custom vendor MIME media type. The custom vendor MIME media type is used instead of a generic IANA registered media type such as application/json. In order to specify the version in this way, an accept header is sent in the request in the following format:
- Accept: application/vnd.myname.v1+json
- Accept: application/vnd.myname.v2+json
Github uses media type versioning for its REST API versioning
Authentication and Authorization
It’s important to understand how authentication and authorization work in REST APIs and what the distinction is between the two. After all, almost every REST API has some sort of authentication built into it. It is also considered a best practice to include at least a basic level of authentication so at least you understand who is using your API and being able to limit requests in case of a security attack like DDOS.
- Authentication – Stating who you are and supplying credentials to the server to be verified that you are who you say you are.
- Authorization – Occurs after authentication. Involves the verification that connecting to a resource is allowed.
The simplest way to implement authentication is to use HTTP basic authentication. Basic authentication is sent in an HTTP header with each request that is encoded in base64. Remember that even though the credentials are encoded, they are not encrypted and therefore not secure at all. For more secure industry standard authentication, consider OAuth2. Most major programming languages including Spring Boot and Java support OAuth2 authentication and provide tons of documentation online on how to implement.
HTTP Status Codes
In order to build a robust REST API, it is necessary to communicate any error messages and invalid inputs back to the API user. Which error messages to use depends on the error encountered and the situation involved. When communicating error conditions to the client, use HTTP status codes. Most API providers do not use every single code available but pick a small subset. At the very least, using the 3 most common HTTP status codes 200, 400 and 500 should cover almost all outcomes.
- 200 (OK) – Send this HTTP status code back to the client when the request was received, everything processed as normal and any return data is successfully returned to the client. Do not communicate any errors back to the client in a 200 status code.
- 400 (Bad Request) – Send this HTTP status code along with a detailed error message in the response body when a client sends an invalid request.
- 500 (Internal Server Error) – This HTTP status code usually indicates a problem within the API code that generates an exception.
More than likely a REST API will have to address other conditions where other HTTP status codes must be used in order to convey the appropriate information. For example, a 401 (Unauthorized) status code will be returned from the OAuth2 token server when a request for an access token is made with bad credentials.
This article proposed best practices for building REST APIs and presented several challenges and solutions specifically targeted for mobile clients. When designing a REST API, most teams understand there are pros and cons of each decision so a good rule of thumb in these situations is to be consistent in your approach. For more information and reading, refer to the following resources:
Useful links and more reading:
- Documenting REST API with OpenAPI
- Using API tools to Connect Data to Dropsource
- How to Connect a Dropsource application to a REST API
- Register a New Media Type
- Spring Boot Tutorial – Using Java to Build OAuth2 Authentication into REST APIs
- Kenneth Lange’s Tips for Designing a Better REST API
- Pros and Cons of URL Versioning
- REST Error Code Tutorial
About the Author: Fred Williams is a Software Engineer with over 20 years of experience in software development, data modeling, architecture, REST APIs, and infrastructure.