REST, or Representational State Transfer, is an architectural style for building web services. Rest APIs are a flexible and efficient way for different systems and applications to communicate with each other and are widely used in modern web development. In this article we will learn about the concept of REST APIs, their importance, and how to effectively implement them into your own systems and applications.
#Components of a Rest API
REST architecture
Rest APIs are based on the REST architecture, which is a set of principles for building scalable and maintainable web services. The key principles of REST are
Statelessness - Systems that follow Rest APIs are stateless, which means that the server and client are decoupled. There is no session data that the server needs to maintain for the client. Every client request will contain all the necessary information for the server to identify the client and process the request.
Caching - Rest APIs can leverage caching, basically storing frequently accessed data temporarily in memory or for backend applications in a data store like redis. This improves performance and latency of the API. Every response should contain if it can be cached and if yes then for how long.
Uniform Interface - This principle suggests that there should be a uniform way to interact with the server irrespective of what type of client (web apps, mobile apps, desktop apps) wants to communicate with the server.
REST methods
RESTful APIs use a set of standard methods to access and manipulate web resources. The most commonly used methods are
- GET: Retrieving an existing resource. For Example:
- GET /users to fetch a list of all users.
- GET /users/121 to retrieve details of the user with ID
121
.
- POST: Creating a new resource.
- POST /users with a JSON payload like {"name":"John Doe", "email" : "john@hygraph.com"} creates a new user.
- PUT: Update an existing resource.
- PUT /users/121 with a JSON payload like { "name": "Jane Doe", "email": "jane@example.com" } replaces all details of the user with ID 121 -
- PATCH: Partially update an existing resource.
- PATCH /users/123 with a payload like { "email": "newemail@example.com" } updates only the email of the user with ID 123.
- DELETE: Delete a resource.
- DELETE /users/123 removes the user with ID 123.
REST protocols
RESTful APIs use HTTP (Hypertext Transfer Protocol) as the communication protocol. HTTP is the same protocol that is used by the World Wide Web and it is a standard protocol for transmitting data over the internet.
Data formats
RESTful APIs support different data formats for exchanging information between client and server.
They mainly include JSON (JavaScript Object Notation) and XML (Extensible Markup Language). JSON is the preferred format used while building REST APIs today as it is lightweight and easy to parse. XML has become less popular in recent decades.
Endpoints
RESTful APIs have a set of endpoints that are used to access and manipulate various resources. Endpoints are URLs that define the location of a resource on the server. Each endpoint corresponds to a specific resource and uses different methods to access the resource.
For example
- GET /orders - API endpoint to get a list of orders
- POST /users - API endpoint to create a new user
Example
Here is an example of how you can use the axios
library in a Next.js application to make a GET request to Github’s REST API.
import axios from 'axios';async function getData() {try {const response = await axios.get('https://api.github.com/search/repositories', {params: {q: 'nextjs',sort: 'stars',per_page: 10}});console.log(response.data);} catch (error) {console.log(error);}}getData();
The axios.get()
function is used to send a GET request to the public API exposed by Github
The params
object allows us to add query parameters (q
, sort
, and per_page
in this example)
Overall in this code, we are searching for the repositories related to next.js
, sorting by stars and limiting the number of results to 10. If the request is successful, if the promise is resolved, the response data is logged to the console. If there is an error, the promise is rejected and the error is logged to the console.
This is a very simple example of how to make a GET request to an external REST API in Next.js, we can similarly make POST, PUT, and DELETE requests and customize it by adding query parameters, headers, or request bodies depending on what the API endpoint supports.
#Integrating Rest APIs
Use cases
Integrating external APIs is becoming common for businesses. Connecting various systems saves a lot of time and effort for businesses and also provides a user experience for the customers.
Accessing wide range of data and functionality
One of the main reasons for integrating multiple REST APIs is to access a wider range of data and functionality. A software system can have many moving components, and there are two options when it comes to building new features: do we want to build it from scratch or use something that is a one-stop solution for that feature? It totally depends on the scale, and finances of the company, If it is a big company operating on a massive scale, building the product in-house might benefit them, whereas for smaller companies it might be cost effective to leverage and integrate existing APIs from some vendor.
For example -
A small retail business can be more efficient and benefit by integrating
- A payment vendor and it’s APIs to process transactions
- A shipping vendor and it’s APIs to manage shipping and delivery
Building entire payment and shipping systems might be very unreasonable for small scale retail businesses..
Improving process efficiency & user experience
Another reason for integrating multiple REST APIs is to improve the efficiency of any part of your system. You might not be able to cover all use cases when building things in house, but some vendor who has been in that field for years might have everything you need to scale up your business from zero to one.
For example, a logistics company may need to integrate with multiple external APIs to track packages, calculate shipping rates, and check delivery status. This eliminates the need for manual data entry and improves the accuracy of the package information.
Integrating multiple REST APIs can also help to enhance the user experience. For example, a travel application may integrate with multiple flight, hotel, and car rental APIs to provide a one-stop shop for customers to plan their trips. By integrating these different vendors, the application can offer a wider range of services for the user very quickly.
Cost benefits
It can also help save enormous costs, integrating multiple REST APIs can save a significant amount of money for businesses compared to building the functionality in-house. By using pre-existing APIs, businesses can take advantage of the development and maintenance that has already been done, rather than having to invest in building and maintaining their own systems. Additionally, the costs associated with integration, such as testing and development, are typically lower than those associated with building from scratch.
Furthermore, building an API in-house can be a time-consuming and complex process, especially for businesses that lack the necessary technical expertise. By using existing APIs from proper vendors, businesses can get up and running quickly, without having to invest the time and resources required to build those functionalities from scratch.
In addition to cost and time savings, integrating REST APIs also allows businesses to leverage the expertise of the API provider. For example, an API provider may have more experience in a specific area or have more resources to devote to security and compliance. This can help to ensure that the integrated API is of high quality and meets the necessary standards.
We shall understand how to integrate multiple external APIs with the help of two examples
Example 1
We can have scenarios where we need to consume GraphQL APIs and Rest APIs to build a particular functionality. If you are unaware of GraphQL, please check our detailed guide to get started.
Use Case - Getting User’s Weather Details
Imagine we want to display weather details on a user dashboard, here’s the scenario
- User Details - Stored in Hygraph
- Weather Information - Weather API is supported by OpenWeatherMap
We will write code for a Next.js API that will fetch user details by making an API call to HyGraph and then we will use the location details of the user to get the weather details from OpenWeatherMap.
First, let us write a function to get user details from Hygraph using a GraphQL API call.
import { GraphQLClient, gql } from 'graphql-request';const { HYGRAPH_URL, HYGRAPH_PERMANENTAUTH_TOKEN } = process.env;const client = new GraphQLClient(HYGRAPH_URL, {headers: {Authorization: `Bearer ${HYGRAPH_PERMANENTAUTH_TOKEN }`,},});export async function getUserLocation(userEmail) {const defaultReturnObject = { user: null };try {const getUserLocationQuery = gql`query getUserLocation($email: String!) {nextUser(where: { email: $email }, stage: DRAFT) {firstnamelastnamelocation}}`;const getUserResponse = await client.request(getUserLocationQuery, { email: userEmail });const { nextUser } = getUserResponse;if (!nextUser) {res.status(400).json(defaultReturnObject);return;}res.status(200).json({ user: nextUser });}catch (err) {console.log('getUserLocation, Something Went Wrong', err);res.status(400).json(defaultReturnObject);}}
The getUserLocation
function makes a GraphQL API request using the graphql-request
library with a query to Hygraph requesting user details for a user. Any runtime errors that might occur have been handled in the code. Next, let's create a function to fetch weather details using the user’s location.
import axios from 'axios';import { getUserLocation } from './getUserLocation';export default async function getUserWeatherDetails(req, res) {const { email } = req.query;if (!email) {res.status(400).json({ message: 'email not provided' });return;}try {// Fetch user details from Hygraphconst userData = await getUserLocation(email);const { user } = userData;if (!user) {res.status(400).json({ message: 'user not found' });return;}// Fetch weather details from OpenWeatherMapconst OPENWEATHER_API_URL= 'https://api.openweathermap.org/data/2.5/weather'const OPENWEATHER_API_KEY= '';const weatherResponse = await axios.get(OPENWEATHER_API_URL, {params: {q: user.location,appid: OPENWEATHER_API_KEY,},});const weatherData = weatherResponse.data;res.status(200).json({ weather: weatherData });} catch (err) {console.log('getUserWeatherDetails, Something Went Wrong', err);res.status(400).json({ message: 'Failed to get weather details' });}}
getUserWeatherDetails
is the main exported function where we are expecting email as a parameter in the query string of a request. We are using the getUserLocation
function to fetch the user details by email from Hygraph. Then we use the user’s location to make a GET request to the OpenWeatherMap API and fetch the weather data. Any runtime errors are handled in the catch block and an appropriate message is returned to the client.
Note: Please replace OPENWEATHER_API_KEY
with your own API key, this will be provided by the external service provider (i.e OpenWeatherApp in this case)
This is how we can integrate multiple APIs into our application.
Example 2
Another common use case is when we have a headless CMS and we want to query some external data. Many systems provide the capability to integrate and query external APIs and return them in a seamless way. In HyGraph, it is very easy to integrate external sources with the help of remote sources feature.
Use case: We have a user model in Hygraph that stores the basic details of the user like firstname, lastname, userId, and email. We want to query an external API to get the user’s company and address details. For demonstration purposes, we can use the free JSONPlaceHolder REST API.
Steps
- In our Hygraph application, go to
Schema → Remote Sources → Add
- Enter the Display name -
userDetails
, - Choose an API type in this case it will be
Rest
. - Enter this Base URL -
https://jsonplaceholder.typicode.com/users
- The user fields that we want to pick up from the JSON placeholder API look something like this
{"address": {"street": "Kulas Light","suite": "Apt. 556","city": "Gwenborough","zipcode": "92998-3874","geo": {"lat": "-37.3159","lng": "81.1496"}},"phone": "1-770-736-8031 x56442","website": "hildegard.org","company": {"name": "Romaguera-Crona","catchPhrase": "Multi-layered client-server neural-net","bs": "harness real-time e-markets"}}
Copy this JSON object above and convert it to SDL using something like JSON2SDL, copy the output SDL. Inside our Remote source configuration in HyGraph click
Add Custom Type Definition
and paste the generated SDL over there. This will help Hygraph to map the fields from the REST API so that it can be seamlessly queried from the Hygraph GraphQL playground.Hit Save
Now that we have our remote source and its mapping configured in Hygraph, we can consume it in our user model.
Steps
1. Go to the Hygraph user model, and from the right-hand side, select - REST field
.
2. Select the Remote Source that we configured in the previous steps, add /{{doc.userId}}
in the path field, and click submit. This is because we want to query an endpoint like https://jsonplaceholder.typicode.com/users/:id
3. Now we can go to the API playground and seamlessly query our remote field from there.
Our documentation on Remote sources has in depth explanations for all possible configurations of using remote sources with a Hygraph schema.
#Conclusion
To conclude, in this article we learned about the fundamentals of a REST API, we discussed the importance of integrating multiple REST APIs and explored the benefits of doing so such as access to a wider range of data and functionality, improved efficiency, enhanced user experience, and cost savings compared to building the functionality in-house. Finally, we went through some examples that demonstrated how to integrate external APIs to our existing systems and using remote sources in Hygraph.
Blog Authors