Like REST, GraphQL is a specification that tells developers how data should be passed to and from the backend
GraphQL is an alternative to REST
{
id: 1,
username: 'gql4Lyfe',
profilePic: '...',
bio: '...',
age: 26
}
GET /user
Fetching user profile
{
id: 1,
username: 'gql4Lyfe',
profilePic: '...',
bio: '...',
age: 26
}
GET /user
What if I only need id, username, and profilePic?
Option 1
Option 2
New REST API Endpoint
(e.g. GET /user-short)
Use Query Parameters
(e.g. GET /user?data=short
Problem: A lot of Endpoints and a lot of backend updating
Problem: API becomes hard to understand
Option 3
GraphQL
Expose a single endpoint that is flexible enough to handle any data request the front-end engineer may ask for.
Typically the endpoint we use is /graphql
Query Response
Query Response
With the /
In a REST API, a GraphQL query would be the equivalent of a GET request. It’s intended to fetch data from the back-end. A GraphQL query could be programmed to create, update, or delete data on the server-side, but that’s bad practice. You should use a GraphQL mutation to do that.
extend type Query {
user(id: ObjID!): User
users(
searchTerm: String
lastCreatedAt: Float
limit: Int
): [User]
followerList(
id: ObjID!
lastCreatedAt: Float
limit: Int
): [User]
followingList(
id: ObjID!
lastCreatedAt: Float
limit: Int
): [User]
showMe(id: ObjID): User
}
The GraphQL mutation is more diverse. It’s intended to create, update, or delete data on the server-side. A mutation can get data back from the server the same way an HTTP POST, PUT, or DELETE request can.
input CreateUserInput {
first_name: String
last_name: String
email: String!
bio: String
password: String!
photoId: String
age: Int
isVerified: Boolean
}
input UpdateUserInput {
first_name: String
last_name: String
email: String
bio: String
photoId: String
age: Int
isVerified: Boolean
}
extend type Mutation {
createUser(input: CreateUserInput!): User
updateUser(id: ObjID!, input: UpdateUserInput): User
removeUser(id: ObjID!): Void
activateUser(id: ObjID!): User
updatePassword(id: ObjID!, input: UpdatePasswordInput): Void
}
Queries and Mutations both use the HTTP POST method to talk to the server.
A schema is a model for the data that you are handling. In a schema is where you can define what properties are associated with your data model and what properties can be given to a Mutation or Query.
type User {
id: ObjID
first_name: String
last_name: String
email: String
bio: String
photo: Asset
dob: String
createdAt: Float
}
A resolver is a function that executes on the server-side when a specific GraphQL query or mutation is received by GraphQL Server. The same way every REST API route (URL path) is tied to an endpoint (function), Every GraphQL query and mutation is tied to a resolver (function).
Although Apollo Client and Apollo Server work together to create a communication channel between the front-end and the back-end, you don’t have to use them together. You can use Apollo Client without the Apollo Server or the Apollo Server without the Apollo Client.
Apollo Client is a wrapper for an HTTP client that is GraphQL-compliant logic within it. This wrapper library can accept queries and mutations so they can be parsed into HTTP requests and given to a GraphQL server.
Apollo Server is the GraphQL API that resides on the server-side. It takes incoming requests from GraphQL-enabled clients, parses the requests, and gives the parsed requests to functions. These functions then execute their business logic and give back a response to be returned to the client.
Loona is a state management library that's built on top of Apollo Client.
State management libraries can help with the following: