GraphQL is quickly supplanting REST as the standard for which data is changed, brought, and queried between the server-end and frontend. Technical developers are seeking to analyze and procure its advantages in their brown-field ventures.
There are many advantages of GraphQL, here are just a few:
Querying numerous assets or resources and fetching the precise information and data you need in one request. Conversely, if we do the exact thing using REST it costs us multiple requests to filter the data.
A modern era of ergonomic dev tools from API to the frontend with famous platforms like Apollo Engine, Client, and Server.
Enhanced performance, particularly on gadgets with moderate internet connections, through the diminished size of the payload and fewer round trips to the backend.
The most perfect way to integrate product architecture with GraphQl is to deploy it as a layer between existing APIs and applications.
To layer GraphQL over our existing API we’ll utilize Apollo Server. It has built-in features and support for GraphQL environment, schema sewing, effective error handling tools, data uploads, schema mandates, and simply observing integration. Let’s jump into building our schema!
In this, we use the schema first development approach. This is an advanced approach for planning and building cutting edge user interfaces that includes the frontend/client-side and backend/server-side groups concurring on a schema to begin with, which serves as a contract between the frontend and the backend ahead of any API building process. Let’s build a basic GraphQL scheme that portrays the shape of the information from the REST API.
Once we begin to build our GraphQL schema there’s a gigantic allure to form literal mappings over REST API or existing database collections data response fields. Whereas this mapping may be a quick way to urge up and running, we unequivocally recommend building the schema based on how the GraphQL API will be utilized by the client-end. This way, we’ll plan a schema that reflects how client-side developers are fetching it, without compelling ourselves to the precise shape of the information returned by our existing APIs.
The schema underneath builds up a contract that depicts precisely how we ought to bring information into our user interface or frontend. Commendable of note are the two fields of schema, “manufactureYear”, and “vehicleStatus”, named differently from the attributes: “productionYear” and “status”, returned as a response from the REST API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
import { gql, AppoloServer } from 'apollo-server'; const typeDefs = gql` type Car { id: Int! model: String! color: String! plateNumber: String! chasisNumber: String! manufactureYear: Int! vehicleStatus: String! expiryDate: String! issueDate: String! } type Query { cars: [Car] car(plateNumber: String!): Car } `;
Our GraphQL schema depicts how it’s utilized on the client-side user interface. Now, check out the Query block:
cars: [Car] - this query returns full details of all cars present in the database.
car(plateNumber: String!): Car - this query returns details of only one car matching with plateNumber argument.
When conveying GraphQL as a layer between existing APIs, services, and our applications, “Apollo Data Sources” give the finest involvement for caching and fetching information from REST endpoints. It’s a modern pattern for stacking information from a specific service, with built-in support for deduplication, error handling, and caching. To ship the data sources out of the box “Apollo Server” is used as the GraphQL layer.
Now, we have to install apollo-datasource-rest.
npm install apollo-datasource-rest
We create a file named dataSource.js with a class named MVRP (it can be anything) and extend RESTDataSource class as given below-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import {
RESTDataSource
} from 'apollo-datasource-rest';
export class MVRP extends RESTDataSource {
constructor() {
super();
this.base_url = 'https://mvrp.herokuapp.com/api/';
}
async fetchAllCars() {
return this.get('cars');
}
async fetchCar(plateNumber) {
const result = await this.get('car', {
plateNumber
});
return result[0];
}
};
Here, base_url is allotted to the root domain of the API within the constructor of our DataSource class. fetchCar(plateNumber)and fetchAllCars() functions get data from the /car and /car?plateNumber endpoints respectively, and both functions invoke the HTTP GET request.