How to Create Application in React Native with Node.js backend and GraphQL
Quick Summary: To create an application in React Native with a Node.js backend and GraphQL, follow these steps: set up the React Native environment, configure the Node.js backend, integrate GraphQL for efficient data fetching, and connect the frontend and backend. Use tools like GraphQL for testing and debugging GraphQL queries. Combining these technologies enables the development of cutting-edge and high-performance mobile applications.
Introduction
You need clarification on whether you want to go towards fast application development with the backend. What framework or technology should you select? Hence, you are right to be here. An application in React Native with a Node.js backend is a perfect combination for software development.
Creating a mobile app using React Native is a perfect solution for fast and effective development.
We will explain every topic with an example with minimum complexity that helps you build a cross-platform application with a backend.
⇒ In this example, we will use React Native (for the app), Node.js (the backend API), and MongoDB (for the database).
So, hang on and read how you can create an application in React Native with a Node.js backend and GraphQL. Moreover, you can also create an application in React Native with our React Native Development Services.
You need clarification on whether you want to go towards fast application development with the backend. What framework or technology should you select? Hence, you are right to be here. An application in React Native with a Node.js backend is a perfect combination for software development.
What Is React Native?
For developing an application in React Native you must know all about it. But As a tech enthusiast, you all already know what React Native is, and If you are new to React Native, then learn it from the React Native development page.
Set Up An Environment For React Native
To build an application in React Native, you must first set up an environment. And the easiest way to set up an environment for React Native
Why React Native?
There are many benefits for building an application in React Native, some of them are below:
Cross-platform Versatility:
React Native allows you to build apps that can run on both platforms – either iOS or Android- with by using a uniform codebase that controls everything. It does for the process incredible shortening of time and cutting cost too.
Improved Native-Like Performance:
React Native initializes high performance for your app- make your users experience a fast and specified environment to enjoy the best user experience. React Native itself is by the experts with Node.js. That stated, it is worth acknowledging that the SPA-backend combination has this benefit that it makes the integration of frontend applications with backend services seemingly unbreakable. Having a js backend, the wrapper operates as a seamless link between them, responding to the changes immediately and raises user experience.
GraphQL-enabled Data Fetching:
Employing GraphQL will make the job of the data request pipelines simple and the particular data. That users request, users can obtain this data via users themselves. There is a direct relation between this optimization and data inefficiencies, as it decreases data inefficiencies and improves the working of the app.
A thriving ecosystem and community:
Further, React Native and Node. As for fees, there is no cost of owner ship. js, and GraphQL community is amazingly helpful. Through the vast libraries, tools, and resources at your disposal, each contributor will have continuous support and developmental resources for their project.
Accelerate Development Cycles:
You have couple ways to create your application, which React Native and GraphQL over. It will allow you to get start faster and flexibility of Node. js.
Through the application of this tech stack, you can create a React Native app which features scalability and is also high-performing. It also helps to broaden the community members across their several versions of the operating system.
What is Node.js?
Node. js, a strong open-source JavaScript environment, is a powerful open-source runtime.
Utilize the given sentence to give students ideas to write about. The objectives of node.js is to do that make it possible for programmers to run their javascript code outside of web browser that in turn make it suitable for server side applications.
This framework follows a reactor-based asynchronous non-blocking architecture which provides it flexibility to cope up with many connections and I/O operations simultaneously. Node. js is now universally recognized for building scalable web servers, APIs and numerous other kinds of applications because of its features like lightweightness, scalability and a large and continuously growing array of libraries.
Why Node.js?
Use Designing React Native apps with Node. I had the chance, while using the full-stack JavaScript language, to learn about the backend and node. Virtual js is a perfect solution I have tried. It is the backbone software of the modern mobile development process that is characterized by high flexibility and ease of connecting to JavaScript because of these two key factors. By hiring Node.Js developers, you can achieve all the features you need, though. On top of that, this also goes hand in hand with varied aspects in the Node framework. Js.
First, Node. js is complete with an event-driven, non-blocking architecture that professionally serves simultaneous executions of multiple requests. This feature ensures data synchronization in real time which ultimately leads to an absence of customer satisfaction.
Combining Node. Developers find it simple to share code between the front and backends of web apps using Javascript and React Native, which shortens the code cycle. It clearly plants a seed in the brain of the listener that the given issue or roadblock will be addressed in the following points.
Additionally, Node. api provided by NPM as the main package management system of js is huge and the number of open-source modules and libraries is growing all the time. This ecosystem features a high number of already-built solutions for developers, so developers don’t need to work on them over and over again, and they can also address common issues.
Lastly, developers, create with GraphQL combined with Node.js such a data-fetching that would be very engaging.
How to create a basic API in Node.Js backend?
I will explain this with an example, but you want to know only Node.Js backend API
Set up Environment for Node.Js
I hope you are also ready with the Node.Js environment setup. It only requires installing node & npm, click here to know more.
Set up Environment for MongoDB
Visit MongoDB’s official website & follow the steps to set up MongoDB on your local PC, or you can use the cloud database of MongoDB Alas.
What is GraphQL?
GraphQL is an open-source data query and manipulation language for APIs, and a runtime for fulfilling queries with existing data.
In simple language, if I explain, GraphQL works as a carrier of data between Backend & Frontend, which means we will create API in Node.Js & Application in React Native as usual, but to call Rest APIs we will use GraphQL instead of manual calling with Axios or fetch.
Start MongoDB, Create backend project, Install required libraries & Implement Backend code
Now we are ready to start after all environments are set up.
Here we are going to build an Application with a frontend & backend. So first we will start to develop basic backend APIs for Book & Author. We will not implement complicated things. So let’s start.
So let’s start
Here I am assuming you have completed all the setup. After that, we will follow steps to start MongoDB in the local machine( I am doing all the things in MacOs)
Step-1: Open terminal and this fire below command to in MongoDB directory.
cd /usr/local/var/log/mongodb [if Intel Processor] cd /opt/homebrew/var/log/mongodb [if Apple M1 Processor]
Step-2: Fire the below command to start the MongoDB database server locally brew services start [email protected] After your work is done, if you want to stop MongoDB then fire the below command in the same path brew services stop [email protected]
Step-3: Here we will start to create APIs in Node.Js & Connect the MongoDB database.
-
- Create a folder for your project I named “LibraryM_backend”, you can name anything as you want.
- Open that folder path in terminal & fire command npm init -y. After this command, you can see a package.json file in your folder. And after that, we will install all required libraries (npm packages)
- We will install the below packages.
- npm install mongoose
- npm install express
- Create an index.js file in the root directory of a project like “/LibraryM_backend/index.js” and paste the following code.
-
const express = require('express'); const mongoose = require('mongoose'); const app = express(); //Establish database connection const connectDb = async () => { await mongoose.connect('mongodb://localhost:27017/book_db', { useUnifiedTopology: true, useNewUrlParser: true }).then(() => { console.log("DB connected successfully...."); }).catch(() => { console.log("DB connection failed..."); }) } connectDb() //listening server on port 4000 app.listen(4000, () => { console.log("Server is running on port: 4000"); })
- Mongoose. Connect is connecting to the “book_db” MongoDB database. If you already create that, combine it with the existing one; otherwise, create a new one & then click “mongodb://localhost:27017/book_db” as a connection string to connect with the MongoDB database.
- Run command npm start & you will find in console “Server is running on port: 4000”.
- Here every time we will need to start the server after changes to get reflect changes, to avoid this we need to install a dev dependency nodemon: npm install –save-dev nodemon
- Change the following code in package.json
-
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "nodemon server.js" },
- Now we are done with the database connection & server started.
Integrate GraphQL in backend side (Using Apollo Server)
After we will install npm for GraphQL
npm install apollo-server
npm install graphql
What is Apollo Server?
Apollo Server is an open-source, spec-compliant 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.
In simple language, Apollo Server is used on Backend Side, and Apollo Client is used on Frontend Side(React JS, React Native, or other frameworks). So Apollo Client makes it enabled to interact with backend APIs.
Create folder structure for backend
I will create a folder structure like below. You can create according to your convenience.
Configure Apollo Server, Connect to DB & Start Server
Now time to integrate GraphQL with backend in index.js file
const express = require('express'); const mongoose = require('mongoose'); const { ApolloServer } = require('apollo-server-express'); //Resolvers const BookResolver = require('/src/resolvers/BookResolver'); const AuthorResolver = require('/src/resolvers/AuthorResolver'); const UserResolver = require('/src/resolvers/UserResolver'), ; //Type Defs const AuthorTypedef = require('/src/typesDefs/AuthorTypeDef'); const BookTypedef = require('/src/typesDefs/BookTypeDef'); const UserTypedef = require("./src/typesDefs/UserTypedef'); // function to create graphql apollo server async function startServer() { const app = express(); const apolloServer = new ApolloServer({ typeDefs: [BookTypeDef, Author TypeDef, UserTypeDef], resolvers: [BookResolver, AuthorResolver, UserResolver), context: async ({ reg }) => { }, }); // Start grapql server await apolloServer.start(); // Apply express (app) as middleware await apolloServer.applyMiddleware({ app: app }); // MongoDb database connection await mongoose.connect('mongodb://localhost:27017/book_db', { useUnifiedTopology: true, useNewUrlParser: true }) console.log("Mongodb connected ........"); app.listen(4000, () => { console.log("Server is running on port: 4000"); startServer(); }) } startServer()
Explanation of GraphQL Keywords
In the above code, you can see how you can configure and start GraphQL
I think you are familiar with express & mongoose, and now ApolloServer. We use three keywords here “typeDefs” & “resolvers”, the next “context” that will need to be explained.
typeDefs: Document or documents that represent your server’s GraphQL schema.
That needs to pass in typeDefs props while creating ApolloServer. A typeDefs looking like
const { gql } = require('apollo-server-express'), const BookTypedef = gql` # AuthorInput type Author { id: ID authorName: String description: String email: String } # Book type Book { id: ID title: String bookescription: String publishedYear: Int author: Author, bookImage: File } type Query { getAllBooks: [Book] getBooksByAuthor(id: ID): [Book] getSingleBook(id:ID): Book } input BookInput { title: String bookdescription: String publishedYear: Int author: String } type Mutation { createBook (book: BookInput): Book updateBook(id: String, book: BookInput) : Book deleteBook (id: String): String deleteAllBook: String } ` module.exports = BookTypeDef
Explanation:
- “Mutation”:
- Mutation queries modify data in the data store and return a value.
- “resolvers”:
- A resolver is a function that’s responsible for populating the data for a single field in your schema.
- “Query”:
- A GraphQL query is used to read or fetch values, which means to perform the “GET” method, we can use query.
- “Book” & “Author”:
- “Book” & “Author” are types that contain which fields are allowed to send as a response. It is user-defined, & we need the “type” keyword to define it.
- “BookInput”:
- “BookInput” is an input type that contains what fields we are going to receive in the request body.
- Note: If we declare any field as “äuthorName”: String! It indicates the required field.
-
// BookModal that defined for MongoDB Book Schema. const Book = require('../models/BookModal'); const BookResolver = { Query: { getAllBooks: async (parent, args, context, info) => { return await Book.find().populate("author"); }, getSingleBook: async (parent, args, context, info) => { return await Book.findById(args.id).populate("author"); } getBooksByAuthor: async (parent, args, context, info) => { let books = await Book.find({ author: args.id }) return books; } } Mutation: { createBook: async (parent, args, context, info) => { const book = new Book(args.book); await book.save(); return book; } updateBook: async (parent, args, context, info) => { const { id } = args const book = await Book.findByIdAndUpdate(id, args.book); return book; } deleteBook: async (parent, args, context, info) => { const { id } = args await Book.findByIdAndDelete(id) console.log("Book deleted successfully"); return "Book deleted successfully"; } deleteAllBook: async (parent, args, context, info) =>{ await Book.deleteMany() return "Books deleted successfully"; } }} module.exports = BookResolver
- Explanation:
- It is a resolver for “Book”, in this, we defined Query, & Mutation’s methods that were declared in typeDefs. You can understand better by looking at the above image, let’s see.
-
Mutation: { createBook: async (parent, args, context, info) => { const book = new Book(args.book); await book.save(); return book; } }
- All parameters (parent, args, context, info) are predefined & are explained very well in the doc: https://graphql.org/learn/execution/
- The operations which were performed in the controller to insert or update data into the database, perform here in the resolver for particular operations.
- : Hereafter save data into the database, it is returning a “book” object & “book” object may have many fields value, but because of graphQL, it will check “Book” type in typeDefs & return only those filed that will match in Book type.
-
Query: { getAllBooks: async (parent, args, context, info) => { return await Book.find().populate("author"); } }
- Here all methods that are declared in typeDefs’ Query are defined. It performs fetch operations & returns “Book” objects with only those fields which are declared in “Book” type in typeDefs.
- “Configure GraphQL Apollo Server”:
- : After creating typeDefs & resolver, We will create Apollo Server & start that.
-
const apolloServer = new ApolloServer({ typeDefs: [BookTypeDef, Author TypeDef, UserTypeDef], resolvers: [BookResolver, AuthorResolver, UserResolver), context: async ({ reg }) => { }, });
- in the above image, you can see “context”. This means inside that we can verify user credential & header’s auth token before going in the resolver, & can throw Authentication error from here, and in the resolver, there is a parameter “context” that contains login user information. We can throw errors if not get user data.
Creating React Native project & Implement GraphQL (Apollo Client)
- Step-1: Now finally, We are done with the backend all stuff
- Create a React Native app : npx react-native init LibraryM_frontend
- Step-2: Open App in VS code & install required npm packages
- For Navigation, you can use the react-navigation library:
- npm install @apollo/client graphql
There are two libs needed to install “@apollo/client” & “graphql”.
- Step-3: You can create a folder structure like below.
Create folder structure for React Native app (Frontend)
Write queries & mutations in the book.js file, that will be used to fetch & update data.
The below image represents “query” which means fetch operations.
Integrate & Configure GraphQL in React Native App (Apollo Client)
import { gql, useMutation } from '@apollo/client' // Queries const GET_ALL_AUTHOR = gql` query getAllAuthors { getAllAuthors { id authorName description email } } `; const GET_SINGLE_AUTHOR = gql` query getSingleAuthor { getSingleAuthor { id authorName description email } } `;
The below image represents the insert operation, similarly, we can write for the update & delete.
import {gql} from '@apollo/client' // Mutations const ADD_NEW_AUTHOR = gql` mutation createAuthor($authorName:String, $description:String, $email:String) { createAuthor(author:{ authorName: $authorName, description: $description, email: $email }) { id authorName description email } } `; const UPDATE_AUTHOR = gql` mutation updateAuthor($id: String, $authorName:String, $description:String, $email:String) { updateAuthor(id:$id, author:{ authorName: $authorName, description: $description, email: $email }) { id authorName description email } } `; const DELETE_AUTHOR_BY_ID = gql` mutation deleteAuthor($id: String) { deleteAuthor(id: $id) } `; const DELETE_ALL_AUTHOR = gql` mutation deleteAllAuthor { deleteAllAuthors } `; export { GET_ALL_AUTHOR, GET_SINGLE_AUTHOR, ADD_NEW_AUTHOR, UPDATE_AUTHOR, DELETE_AUTHOR_BY_ID, DELETE_ALL_AUTHOR }
Configure Apollo client in App.js file
import React from 'react'; import { ApolloClient, createHttpLink, InMemoryCache, ApolloProvider} from '@apollo/client'; import RootNavigation from './src/RootNavigation'; //create http link based on base url const httpLink = createHttpLink({ uri: 'http://192.168.1.34:4000/graphql', }); //Create apollo client object const client = new ApolloClient({ link: httpLink , cache: new InMemoryCache(), // credentials:'include' }); export default function App() { return ( <ApolloProvider client={client}> <RootNavigation /> </ApolloProvider> ) }
- Explanation:
- In the above image “http://192.168.1.34” is the IP of my backend server PC & “4000” is port, “/graphql” is the default URL that is automatically added if you don’t specify in “apolloServer.applyMiddleware({})” “path” param ( It is part of backend )
-
await apolloServer.start(); await apolloServer.applyMiddleware({ app: app, path:"/graphql" })
- <ApolloProvider client={client}/>: That wraps our root component, Hence all child components or screens can access the “client”‘s instance & using that we can perform operations of fetch & update.
-
import React, { useState } from 'react' import { useMutation, useQuery, useApolloClient } from '@apollo/client'; import { View, Text, Flatlist, SafeAreaView, Alert, Image } from 'react-native' import { GET_ALL BOOKS }_from '../graphQLAPI/book'; export default function Home (props) { // local states const_[books, setBooks] = useState( []), // get apollo client instance const client = useApolloclient(); //fetch book data const { loading, error, data } = useQuery(GET_ALL_BOOKS), // delete book data const [deleteBook, { data: deletedData, loading: deleteLoading, error: deleteError }] = useMutation (DELETE_BOOK_BY_ID); return( <SafeAreaView style={{ flex: 1, backgroundColor: "#E8F3F3"}}> <FlatList data={data?.getAllBooks || []} // data.getAllBooks returns all book data renderItem={_renderItem} keyExtractor={(item, index) => index.toString() } refreshing={true} /> </SafeAreaView> ) }
- “useQuery()”: Above example fetch books data from backend using “useQuery()” hook.
- And “data.getAllBooks” contains all book data here “getAllBooks” is clear in /graphQLAPI/book.js
-
// Queries const GET_ALL_AUTHOR = gql` query getAllAuthors { getAllAuthors { id authorName description email } } `;
- “useMutation()” : This apollo client hook is used to perform insert, update, delete operations. The below image represents how that works
I hope the above code makes it clear to understand how we can insert data using the “useMutation” hook.
Troubleshooting Common Issues
1. Identifying and resolving common React Native errors
React Native app development services may have various issues, including unexpected behavior, crashes, or unresponsive components. It is crucial to start by looking through the application’s logs and console output for error messages to address these issues. These communications frequently offer critical cues about the nature of the case. Examples of often occurring errors include syntax errors, missing dependencies, and problems with native modules.
When this occurs, checking dependencies, updating packages, and testing the application on various hardware or simulators can all help to pinpoint the problem’s fundamental cause. Additionally, using tools like React Native Debugger or Reactotron can offer deeper insights into the state and behavior of the application, assisting with troubleshooting.
2. Debugging common GraphQL and Node.js issues
Unexpected data retrieval may result from problems with GraphQL queries and Node.js server requests. One of the first steps in debugging such issues is carefully reviewing the query and mutation requests and contrasting them with the server’s schema. The schema definitions and resolvers have to match the appropriate data structure.
Utilizing tools like GraphiQL or GraphQL Playground can be very helpful in testing and troubleshooting GraphQL queries. These technologies enable a more informative and participatory method of query examination.
Also, the server logs use to identify the slowing down of performance and faults in the Node. js backend. You can use the server as a valuable tool in discovering clues for fixing the problems and bettering the performance of GraphQL.
3. Troubleshooting server-client communication problems
Typically, the communication problems occur between the React Native client and the Node. jss server lead to the misbehavior of the applications. Have the server running and available from the client application.
Thus, the possible problems with cross-origin resource sharing (CORS) might be the reasons of the client not being able to connect to the server.
Moreover, network debugging tools such as Charles Proxy or Wireshark that allow to trace network requests and responses are also good. These technologies enable one to identify and understand the communication issues thereby making it possible to deal with the root of the problems.
How can Bigscal help Create an Application In React Native With Node.Js Backend And GraphQL?
The whole of the process to begin building an application in React Native with Node is still in the world of ambiguity for you. The JS backend and graphQL are headed towards the same goal, so you can contact us if you have any issues.
Our gifted team of creators is good at developing strong backends with Node. js is a great example of a perfect combination of scalability and speed which makes it suitable for a high-end performance.
The GraphQL integration contributes to the data fetching process. It is that is streamline and eliminates both the over-fetching and under-fetching issues. Thus, optimizing your app’s performance.
At Bigscal, we offer React Native development services covering every aspect of app development, from ideation to deployment, providing tailored end-to-end solutions that perfectly match your requirements.
Experience the remarkable potential of React Native and Node.js, combined with the flexibility of GraphQL, all skillfully brought together by Bigscal’s proficiency, making your app development journey an undeniable success.
Conclusion
GraphQL makes it easy & efficient to fetch & update data. And it also provides the benefits of graphQL features. So, start work on your app development project today.
At Bigscal Technologie, you can Hire React Native Developers & Offshore React Native Developers And Save up to 60% On Costs And Time, With No Hiring Fees.
FAQ
How does React Native work with Node.js?
React Native is the front end, while Node.js powers the backend API, enabling seamless communication between the app and server.
What are the advantages of using Node.js for the backend?
Node.js offers high scalability, non-blocking I/O, and a vast array of libraries, making it ideal for building fast and responsive APIs.
How does GraphQL benefit the application?
GraphQL streamlines data fetching, reducing network overhead and enabling clients to request only the required data, improving app performance.
Can I use existing React components in React Native?
In most cases, yes! React Native allows reusing many React components, easing development and ensuring consistency.
Is React Native suitable for complex applications?
React Native’s flexibility and community support make it viable for developing complex and feature-rich applications.