React Native with Apollo— Part 1, Apollo Server

Looking to learn React Native? Check out React Native Training.

We will be using a combination of React Native, Apollo Client, Apollo Server, GraphQL, Express, and MongoDB to build a full stack mobile application.

Here is the link to the final repo.

Here is part 2, using the Apollo Client.

This tutorial covers part 1 whis is the Apollo server, part 2 is the React Native app + Apollo client.

The Apollo client is a flexible, fully-featured GraphQL client, making it easier for you to get up and running with GraphQL.

The Apollo Server Tools are a collection of tools to make it easier to get started with GraphQL and building your own GraphQL server.

Our app will fetch a president of the United States by name from our MongoDB database using our Apollo Server, and return the data to our Apollo Client React Native application.

Let’s get started.

To begin, we will be having two main projects:

  1. Apollo Server
  2. Apollo Client + React Native application

We will be using the React Native app to fetch data from our Apollo server using GraphQL queries.

1. Apollo Server with Express + MongoDB

To get going, first we will install all of the dependencies we will need for the server. We will use yarn to do so. Let’s first create the server folder and call it apolloserver. Then, in this directory, create a new new package.json with npm init (answer yes to all or configure as you would like):

npm init

Now, install all of the dependencies we will need to run the server:

yarn add apollo-server body-parser express graphql graphql-tools mongoose request request-promise

Let’s go over some of these dependencies:

  1. apollo-server — production-ready Node.js GraphQL server library that supports Express, Connect, Hapi, Koa, and other popular Node HTTP servers
  2. body-parser — middleware we will be using with express to parse json
  3. express — nodejs express server
  4. graphql — JavaScript implementation for GraphQL
  5. graphql-tools —this package allows you to use the GraphQL schema language to build your GraphQL.js schema, and also includes useful schema tools like per-type mocking.
  6. mongoose — MongoDB object modeling tool
  7. request & request-promise — HTTP request client library. We will use this to fetch our initial data.

Next, we need to create all of the files we will need:

touch app.js connectors.js model.js resolvers.js schema.js seed.js
  1. app.js — entry point of the server
  2. connectors.js — this file will hold our connector. A connector is the piece of code that links a GraphQL server to a specific backend (eg. MySQL, MongoDB, S3, neo4j).
  3. models.js — this file will hold our Mongoose model
  4. resolvers.js — this file will hold our resolver. Resolvers tell our server how to respond to a query. We will be writing a basic resolver for our app. To learn more about resolvers, check out this tutorial.
  5. schema.js — this file will hold our GraphQL schema
  6. seed.js — this file will hold the code that will seed our database with the President data

Now that we have our files and dependencies set up, we can start writing some code!

Open model.js, and create the model for our database:

As you can see, our model has three properties: name, party and term (all Strings).

Next, let’s write the code that will seed our database using this model. In seed.js:

In this file, we do the following:

  1. Import both the President model as well as the request-promise module
  2. Fetch data from the mysafeinfo api to retrieve presidents
  3. Map through the data and set it to match our schema.
  4. Use forEach function on the returned data and populate the database with this data.
  5. Export the seed function

Now, let’s create the GraphQL schema. In schema.js:

The schema uses GraphQL Type Language to define types that we will use to fetch from our service. We will have

  1. the President type that will define the fields we will be using.
  2. the RootQuery type which tells the schema to allow the president query
  3. the schema type which tells the server which types represent the root query

To learn more about how to write schemas, check out the docs.

Next, we will need to write our Connector. Remember, the connector is the piece of code that will link the GraphQL server to our MongoDB instance. In connectors.js:

Our connector is a JavaScript class with a single method: findPresident. findPresident takes a name as an argument, and searches our database for that person and return him / her. We then export the class for use in our resolver.

Next we implement this connector in our resolver method.

In order to respond to queries, a schema needs to have resolve functions. Resolve functions cannot be included in the GraphQL schema language, so they must be added separately.

The resolver will be invoked by the GraphQL engine when data is queried. In the resolver, we get access to the connector we just created through what’s known as context. context will the third argument in our rootQuery methods. The second argument will be the actual query.

In resolvers.js:

In this file, we create a resolveFunctions object. In this object we create a RootQuery object. This RootQuery object correlates directly to the schema we declared in schema.js. The RootQuery object contains a single method, president, which takes three arguments. The first argument is the rootValue, the second argument is the actual query that we will be getting, and the third is the context. I will go over how the context and rootQuery are defined when we write the app.js file.

ctx.constructor.President is creating a new instance of the President class we created in connectors.js.

Let’s go ahead and create the last file, app.js:

There is a lot going on here, so I will walk through some of it:

  1. We require all of the necessary dependencies, including apolloExpress, grqphqlExpress, and makeExecutableSchema from apollo-server and graphql-tools.
  2. We connect to MongoDB through port mongodb://localhost/apollo, and add the global Promise to the Mongoose object.
  3. We import the seed method and call it to seed the database with the data
  4. We import the Schema, Resolvers, and Connectors
  5. We pass in our Schema and Resolvers to makeExecutableSchema from graphql-tools. makeExecutableSchema takes a single argument: an object of options. Only the typeDefs and resolvers options are required.

typeDefs is a required argument and should be an array of GraphQL schema language strings or a function that takes no arguments and returns an array of GraphQL schema language strings.

resolvers is a required argument and should be an object that follows the pattern explained here.

6. We use the /graphql endpoint to call the apolloExpress method, passing in the schema and context. If you remember in our resolvers function, we had access to ctx.constructor.President. This ctx corresponds directly to the context key in the apolloExpress method.

7. We use the /graphiql endpoint to call the graphiqlExpress method and set up a graphiql instance, the in-browser IDE that will allow us to explore our GraphQL endpoint.

Now we’re ready to see if our app is working.

First, make sure MongoDB is running on your machine. You can usually fire it up with the mongod command from your command line:

mongod

Next, start the server:

node app.js

Now, we should be able to navigate to http://localhost:8080/graphiql and explore our server:

Try the following query:

query {
president(name: "Bill Clinton") {
name
term
party
}
}

This should return the requested info for Bill Clinton!

Part 2 coming soon…

Here is the link to the final repo

Thanks for reading ( ͡°( ͡° ͜ʖ( ͡° ͜ʖ ͡°)ʖ ͡°) ͡°)

To continue to part 2, click here.

My Name is Nader Dabit . I am a software consultant and trainer and the founder of React Native Training where we teach developers at top companies around the world how to quickly get up and running with React Native.
If you like React and React Native, checkout out our podcast — React Native Radio on Devchat.tv
Also, check out my book, React Native in Action now available from Manning Publications
If you enjoyed this article, please recommend and share it! Thanks for your time