GraphQL is a query language for APIs that allows you to request exactly the data you need, making it a powerful alternative to REST. It helps optimize network performance by reducing over-fetching and under-fetching of data, and it gives developers more control over the structure of the data they query.
GraphQL is an open-source data query language developed by Facebook. It allows clients to request only the data they need and get it in a structured and predictable format. Unlike REST, where multiple endpoints may be needed for different resources, GraphQL has a single endpoint where you can query for specific fields across multiple resources.
When building React applications, especially those that interact with APIs, managing data can become challenging. GraphQL solves many of these challenges by offering:
Before we connect GraphQL with React, let’s first set up a GraphQL server. We’ll use Apollo Server, a popular tool for building GraphQL APIs.
To get started, install the required dependencies:
npm init -y
npm install apollo-server graphql
Here is a simple GraphQL server using Apollo Server:
// index.js
const { ApolloServer, gql } = require('apollo-server');
// Define the GraphQL schema
const typeDefs = gql`
type Query {
hello: String
}
`;
// Define the resolvers
const resolvers = {
Query: {
hello: () => 'Hello, GraphQL!',
},
};
// Create the Apollo Server instance
const server = new ApolloServer({ typeDefs, resolvers });
// Start the server
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
typeDefs
: Defines the GraphQL schema, which includes a query hello
that returns a String
.resolvers
: Functions that resolve the queries. In this case, hello
returns the string "Hello, GraphQL!"
.Output: When you run the server with node index.js
, it starts at a URL (e.g., http://localhost:4000/
) where you can query for hello
:
{
hello
}
{
"data": {
"hello": "Hello, GraphQL!"
}
}
To connect GraphQL with a React application, we use Apollo Client. It simplifies the process of querying data from a GraphQL API and managing state in a React app.
First, we need to install Apollo Client and its dependencies:
npm install @apollo/client graphql
In a React application, we need to wrap our components with Apollo’s ApolloProvider
to allow any child components to query data.
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { ApolloProvider, InMemoryCache, ApolloClient } from '@apollo/client';
import App from './App';
// Initialize Apollo Client
const client = new ApolloClient({
uri: 'http://localhost:4000/', // GraphQL server URI
cache: new InMemoryCache(),
});
ReactDOM.render(
,
document.getElementById('root')
);
http://localhost:4000/
.Now that Apollo Client is set up, let’s fetch data using GraphQL queries in React.
To fetch data in a React component, we use the useQuery
hook provided by Apollo.
// src/App.js
import React from 'react';
import { useQuery, gql } from '@apollo/client';
// GraphQL query to fetch 'hello'
const HELLO_QUERY = gql`
query GetHello {
hello
}
`;
const App = () => {
const { loading, error, data } = useQuery(HELLO_QUERY);
if (loading) return Loading...
;
if (error) return Error: {error.message}
;
return {data.hello}
;
};
export default App;
gql
: Tagged template literal used to define the GraphQL query.useQuery
: A React hook that executes the query. It returns an object containing loading
, error
, and data
.Output: If the query is successful, the app will display:
Hello, GraphQL!
GraphQL queries often require variables (parameters). You can pass variables to queries using Apollo Client.
Let’s modify our GraphQL server to accept a variable for the hello
query:
// Server: index.js
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type Query {
hello(name: String!): String
}
`;
const resolvers = {
Query: {
hello: (_, { name }) => `Hello, ${name}!`,
},
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
Now, we need to modify our React app to pass a name
variable in the query:
// src/App.js
import React, { useState } from 'react';
import { useQuery, gql } from '@apollo/client';
const HELLO_QUERY = gql`
query GetHello($name: String!) {
hello(name: $name)
}
`;
const App = () => {
const [name, setName] = useState("John");
const { loading, error, data } = useQuery(HELLO_QUERY, {
variables: { name },
});
if (loading) return Loading...
;
if (error) return Error: {error.message}
;
return (
{data.hello}
setName(e.target.value)}
/>
);
};
export default App;
name
variable to the query and passed it using useQuery
.name
dynamically.
Hello, John!
[Input Box]
A mutation in GraphQL is used to create, update, or delete data. It’s similar to POST, PUT, DELETE in REST.
Let’s extend our server to handle a mutation that adds a user:
const typeDefs = gql`
type User {
id: ID!
name: String!
}
type Query {
users: [User]
}
type Mutation {
addUser(name: String!): User
}
`;
const users = [];
const resolvers = {
Query: {
users: () => users,
},
Mutation: {
addUser: (_, { name }) => {
const newUser = { id: users.length + 1, name };
users.push(newUser);
return newUser;
},
},
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
Now, let’s modify the React app to execute this mutation:
import React, { useState } from 'react';
import { useMutation, gql } from '@apollo/client';
const ADD_USER = gql`
mutation AddUser($name: String!) {
addUser(name: $name) {
id
name
}
}
`;
const App = () => {
const [name, setName] = useState('');
const [addUser, { data }] = useMutation(ADD_USER);
return (
setName(e.target.value)}
placeholder="Enter user name"
/>
{data && Added User: {data.addUser.name}
}
);
};
export default App;
useMutation
: Executes the mutation when the button is clicked.data
returned after the mutation is displayed on the screen.Subscriptions enable real-time communication between the server and the client. We can implement them using websockets in Apollo.
Using GraphQL with React offers tremendous flexibility and efficiency in data handling. By allowing you to fetch exactly what you need, GraphQL optimizes both frontend and backend performance. Apollo Client makes the integration seamless, enabling you to build powerful and scalable applications. Happy Coding!❤️