Call GraphQL APIs from React Native
Here is an example to show how to call GraphQL Query, Mutation and Subscribe from React Native App. GraphQL is becoming the new way to use APIs in modern web and mobile apps. GraphQL is an alternative to REST that has been steadily gaining popularity since its release. Whereas with REST a developer would usually collate data from a series of endpoint requests, GraphQL allows the developer to send a single query to the server that describes the exact data requirement. For more information about GraphQL you can visit Official GraphQL website.
In this example we are not going to talk about GraphQL in deep as it is a huge topic in itself, we will see how to call GraphQL APIs by creating your React Native App as an Apollo Client.
Apollo Server and Apollo Client
Apollo Server is an open-source GraphQL server that’s compatible with any GraphQL client, including Apollo Client. It’s the best way to build a production-ready, self-documenting GraphQL API that can use data from any source.
Apollo Client helps you structure code in an economical, predictable, and declarative way. The core @apollo/client
library provides built-in integration with React, and the larger Apollo community maintains integrations for other popular view layers.
Call GraphQL Query, Mutation and Subscription
Before moving further lets understand what is GraphQL Query, Mutation and Subscription?
Query is used to fetch/get records. It is simply like any GET request which can take some query params to filter the records.
Mutation is used to create/update records. We can imagine it as POST / PUT / PATCH / DELETE request.
Subscriptions maintain an active connection to your GraphQL server (most commonly via WebSocket). This enables your server to push updates to the subscription’s result over time. Subscriptions are useful for notifying your client in real time about changes to back-end data, such as the creation of a new object or updates to an important field.
Example Description
In this example, we will have 3 buttons to call
-
Simple Query without payload
-
Dynamic Query with payload by passing payload as variable
-
Mutation by passing payload as variable
We will also Subscribe to GraphQL Subscription for creation of record, which means whenever a record got created GraphQL will publish a message for all the subscribers which we receiver in real time.
I hope after going through this example you will have a proper understanding of how to call GraphQL query and mutation and subscribe GraphQL subscription from React Native App. If you want to add some points then feel free to share them with us in comment below.
Let’s start with the example.
GraphQL Server Setup
For this example you will need GraphQL server to call query and mutation, if you have your own GraphQL server then you can ignore this section else can follow below steps to setup dummy GraphQL server.
1. Clone Repo
git clone https://github.com/SnehalAgrawal/about-react-dummy-graphql-apis.git
2. Jump into the directory
cd about-react-dummy-graphql-apis
3. Install node_module
npm install
4. Run GraphQL Server
npm start
This will start your GraphQL server for you
Once you start your GraphQL server you can move to next step to create React Native App which will subscribe and call Query and Mutation from this GraphQL server.
To Make a React Native App
Getting started with React Native will help you to know more about the way you can make a React Native project. We are going to use react native command line interface to make our React Native App.
If you have previously installed a global react-native-cli package, please remove it as it may cause unexpected issues:
npm uninstall -g react-native-cli @react-native-community/cli
Run the following commands to create a new React Native project
npx react-native init ProjectName
If you want to start a new project with a specific React Native version, you can use the --version argument:
npx react-native init ProjectName --version X.XX.X
Note If the above command is failing, you may have old version of react-native
or react-native-cli
installed globally on your pc. Try uninstalling the cli and run the cli using npx.
This will make a project structure with an index file named App.js in your project directory.
Installation of Dependencies
To install any dependency open the terminal and jump into the project using
cd ProjectName
As mentioned above to call GraphQL query and mutation from React Native App we will use Apollo Client library. To use it install @apollo/client
and graphql
@apollo/client: This single package contains virtually everything you need to set up Apollo Client. It includes the in-memory cache, local state management, error handling, and a React-based view layer.
graphql: This package provides logic for parsing GraphQL queries.
npm install @apollo/client graphql --save
Because subscriptions maintain a persistent connection, they can’t use the default HTTP transport that Apollo Client uses for queries and mutations. Instead, Apollo Client subscriptions most commonly communicate over WebSocket, via the community-maintained subscriptions-transport-ws
library. So install that also
npm install subscriptions-transport-ws --save
This command will copy all the dependencies into your node_module directory. –save is optional, it is just to update the dependency in your package.json file.
Code To Call GraphQL Query and Mutation
Open App.js in any code editor and replace the following code to call GraphQL Query, Mutation and to subscribe GraphQL subscription. Please check for the GraphQL URL if you are using your own GraphQL server.
App.js
// How to Call GraphQL Query and Mutation from React Native
// https://aboutreact.com/react-native-call-graphql-query-mutation-subscribe/
// import React in our code
import React, {useEffect, useState} from 'react';
// import all the components we are going to use
import {
SafeAreaView,
StyleSheet,
View,
Text,
TouchableOpacity,
} from 'react-native';
import {
ApolloClient,
InMemoryCache,
ApolloProvider
} from '@apollo/client';
import {gql} from '@apollo/client';
import {WebSocketLink} from '@apollo/client/link/ws';
const App = () => {
const [user, setUser] = useState({});
// Connection for the subscription
const wsLink = new WebSocketLink({
uri: `ws://localhost:4000/graphql`,
options: {
reconnect: true,
},
});
// Initialize Apollo Client
const client = new ApolloClient({
uri: 'http://localhost:4000/graphql',
headers: {
// Header(if any)
authorization: 'a1b2c3d4-a1b2-a1b2c3d4e5f6',
},
cache: new InMemoryCache(),
// link WebSocketLink subscription
link: wsLink,
});
useEffect(() => {
// Creating Suscription Observer
let observer = client.subscribe({
query: gql`
subscription userAdded {
userAdded {
name
age
email
address
password
}
}
`,
});
// Observer callback
let subscriptionObj = observer.subscribe((result) => {
console.log('Subscription data => ', result.data.userAdded);
setUser(result.data.userAdded);
});
return () => {
// Unsubscribe subscription
console.log('Unsubscribed');
subscriptionObj.unsubscribe();
};
}, []);
const simpleQuery = async () => {
// Calling Simple Graph Query
const {data, error} = await client.query({
query: gql`
query users {
users {
name
age
email
address
password
}
}
`,
});
// In case Error in Response
if (error) {
alert(`error + ${JSON.stringify(error)}`);
console.log('error', JSON.stringify(error));
return;
}
alert(`Got Record of ${data.users.length} Users`);
console.log('data', JSON.stringify(data));
};
const dynamicQuery = async () => {
// Calling Graph Query with variables
const {data, error} = await client.query({
query: gql`
query user($email: String!) {
user(email: $email) {
name
age
email
address
password
}
}
`,
variables: {
email: 'netus.et.malesuada@ornarelectusjusto.co.uk'
},
});
// In case Error in Response
if (error) {
console.log('error', JSON.stringify(error));
alert(`error + ${JSON.stringify(error)}`);
return;
}
console.log('data', JSON.stringify(data.user));
alert(`Response: ${JSON.stringify(data.user)}`);
};
const simpleMutation = async () => {
// Calling Graph Mutation with variables
const {data, error} = await client.mutate({
mutation: gql`
mutation createUser(
$name: String!
$email: String!
$age: Int!
$address: String!
$password: String!
) {
createUser(
name: $name
email: $email
age: $age
address: $address
password: $password
)
}
`,
variables: {
name: `New User ${Math.random()}`,
//'newuser@gmail.com',
email: `newuser${Math.random()}@gmail.com`,
age: 30,
address: 'Demo Address',
password: '12345',
},
});
// In case Error in Response
if (error) {
alert(`error => ${JSON.stringify(error)}`);
console.log('error', JSON.stringify(error));
return;
}
alert(`Response: ${JSON.stringify(data.createUser)}`);
console.log('data', JSON.stringify(data.createUser));
};
return (
<ApolloProvider client={client}>
<SafeAreaView style={styles.container}>
<View style={styles.container}>
<Text style={styles.titleText}>
How to Call GraphQL Query and Mutation from React Native
</Text>
<View style={styles.innerContainer}>
<Text style={styles.textStyle}>
Run Simple Query (Get All User)
</Text>
<TouchableOpacity
activeOpacity={0.7}
style={styles.buttonStyle}
onPress={simpleQuery}>
<Text style={styles.buttonTextStyle}>Get Data</Text>
</TouchableOpacity>
</View>
<View style={styles.innerContainer}>
<Text style={styles.textStyle}>
Run Dynamic Query by passing payload as variable {'\n'}
(Get Single User by Email)
</Text>
<TouchableOpacity
activeOpacity={0.7}
style={styles.buttonStyle}
onPress={dynamicQuery}>
<Text style={styles.buttonTextStyle}>Get Data</Text>
</TouchableOpacity>
</View>
<View style={styles.innerContainer}>
<Text style={styles.textStyle}>
Run Mutation by passing payload as variable {'\n'}
(Create User)
</Text>
<TouchableOpacity
activeOpacity={0.7}
style={styles.buttonStyle}
onPress={simpleMutation}>
<Text style={styles.buttonTextStyle}>Add User</Text>
</TouchableOpacity>
</View>
<View style={styles.innerContainer}>
<Text style={styles.textStyle}>
Subscription Data {'\n'}
(Subscribed for Successfull user Creation)
</Text>
<Text style={{textAlign: 'center'}}>
Last Added User: {JSON.stringify(user)}
</Text>
</View>
</View>
<Text
style={{
fontSize: 16,
textAlign: 'center',
color: 'grey',
}}>
www.aboutreact.com
</Text>
</SafeAreaView>
</ApolloProvider>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
padding: 10,
textAlign: 'center',
},
innerContainer: {
marginTop: 16,
backgroundColor: '#f5f5f5',
padding: 16,
marginBottom: 10,
},
titleText: {
fontSize: 22,
textAlign: 'center',
fontWeight: 'bold',
},
textStyle: {
fontSize: 16,
textAlign: 'center',
marginBottom: 10,
},
buttonStyle: {
justifyContent: 'center',
padding: 10,
backgroundColor: '#8ad24e',
},
buttonTextStyle: {
color: '#fff',
textAlign: 'center',
},
});
export default App;
To Run the React Native App
Open the terminal again and jump into your project using.
cd ProjectName
1. Start Metro Bundler
First, you will need to start Metro, the JavaScript bundler that ships with React Native. To start Metro bundler run following command:
npx react-native start
Once you start Metro Bundler it will run forever on your terminal until you close it. Let Metro Bundler run in its own terminal. Open a new terminal and run the application.
2. Start React Native Application
To run the project on an Android Virtual Device or on real debugging device:
npx react-native run-android
or on the iOS Simulator by running (macOS only)
npx react-native run-ios
Output Screenshots
This is how you can call GraphQL query and mutation from React Native. If you have any doubts or you want to share something about the topic you can comment below or contact us here. There will be more posts coming soon. Stay tuned!
Hope you liked it. 🙂
App.js (0:1)
Unable to resolve module ‘module://graphql/language/printer.js’
(Device)
App.js (74:6)
React Hook useEffect has a missing dependency: ‘client’. Either include it or remove the dependency array. (react-hooks/exhaustive-deps)