How to create a React Native app with PostgreSQL and GraphQL: Part 1
Tags: graphql, postgres, reactnative, tutorial
Published: 2019-09-03 13:09:48

---
title: How to create a React Native app with PostgreSQL and GraphQL: Part 1
published: true
tags: graphql,postgresql,reactnative,tutorial
canonical_url: https://blog.logrocket.com/create-a-react-native-app-with-postgresql-and-graphql-part-1/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ltzxkvwdjn7iwvjoit4x.png
---
**Written by [Austin Roy Omondi](https://blog.logrocket.com/author/austinroyomondi/)**✏️

React Native is a great option when it comes to developing mobile applications for both iOS and Android smartphones. With React Native you can write an application that works on both platforms with the only difference coming at the view level, with iOS and Android rendering differently. In this two-part series, we’ll be looking at how we can develop an application with React Native and GraphQL. To do this, we’ll be building a simple note-taking app that allows our user to add notes, view, edit and delete them.

For the first part, we’ll be building a GraphQL server with a PostgreSQL database that will serve as the backend of our application. In the second part (blog post to come later) we will build an application with React Native that will consume data from our server.

Let’s get started with our server setup. The folder structure for our project will be as shown in [this repo](https://github.com/jimmykimani/GraphQL-Server-Tutorial-with-Apollo-Server-and-Express/tree/notes/starter-files).

In order to build our application, you will need to be familiar with:

- NodeJS
- Express
- Databases
- Mobile development

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## How to set up an Apollo server with Express

Our backend server will run on [Node JS](https://nodejs.org/en) and [Express](https://expressjs.com/). We’ll have a few initial dependencies to install, but first, we’ll need to initiate our app, run:

```jsx
npm init
```

Now let us install our first set of dependencies:

```jsx
npm install apollo-server apollo-server-express express graphql cors --save
```

One of the dependencies we have installed is `apollo-server`, Apollo Server is the best way to quickly build a production-ready, self-documenting API for GraphQL clients, using data from any source. While we are using it with Express, it may be used with several popular libraries such as [Hapi](https://github.com/hapijs/hapi) and [Koa](https://koajs.com/).

Now we are all set to start creating our server. Add the following code to `src/index.js`.

```jsx
import cors from 'cors';
import express from 'express';
import {
    ApolloServer
} from 'apollo-server-express';

const app = express();

app.use(cors());

const server = new ApolloServer({});

server.applyMiddleware({
    app,
    path: '/graphql'
});

app.listen({
    port: 8000
}, () => {
    console.log('Apollo Server on http://localhost:8000/graphql');
});
```

Let’s go through what we have so far, in the code above, we have initialized an Express application as well as an Apollo server instance. Using Apollo Server’s `applyMiddleware()` method, you can opt-in any middleware, which in our case is the Express app. Also, you can specify the path for your GraphQL API endpoint.

You may also note we applied `cors` to our Express application, this is to allow external domains to access our application.

Our next step would be to define our schema and resolvers for the Apollo Server instance. But first, let’s cover schema and resolvers.

## Schema

The [GraphQL schema](https://graphql.org/learn/schema/) provided to the Apollo Server is all of the available data for reading and writing data via GraphQL. The schema contains type definitions from a mandatory top-level `Query` type that allows reading of data followed by field and nested fields. These are defined using the GraphQL Schema Language and allows us to talk about GraphQL schemas in a language-agnostic way.

Here’s what’s in our `schema/notes.js`:

```jsx
import {
  gql
} from 'apollo-server-express';

export default gql `
  extend type Query {
    notes: [Note!]
    note(id: ID!): Note!
  }

  type Note {
    id: ID!
    text: String!
  }
`;
```

Let’s take a look at our schema definition for some notable terms we need to be aware of. We have already covered the `Query` type, but let’s look at the rest:

- `notes` is defined as `[Note!]` which represents an array of `Note` objects. The exclamation mark means it is **non-nullable,** this means you can always expect an array (with zero or more items) when you query the `notes` field
- Each `Note` object contains an `id` field defined as `ID` . The `ID` scalar type represents a unique identifier, often used to re-fetch an object or as the key for a cache. It is serialized the same way a String is serialized. However, defining it as an `ID` signifies that it is not intended to be human‐readable
- The `Note` object also has a `text` field defined as `String` which is one of the built-in **scalar** types that is a sequence of UTF-8 characters
- You will also notice the `note` field is provided with `id` options in the form of `(id: ID!)`. This allows for the use of [GraphQL arguments](https://graphql.org/learn/queries/#arguments) to refine queries. This allows us to fetch a single note by providing it’s `ID` in our query. The argument is also _non-nullable_ as it must be provided when fetching a single note.

The schema above shall be placed in `src/schema/notes.js`. We can then have a `index.js` file inside the `src/schema` directory with the following code:

```jsx
import { gql } from "apollo-server-express";
    
    import noteSchema from "./notes";
    
    const linkSchema = gql`
      type Query {
        _: Boolean
      }
    
      type Mutation {
        _: Boolean
      }
    
      type Subscription {
        _: Boolean
      }
    `;
    
    export default [linkSchema, noteSchema];
```

## Resolvers

Resolvers are responsible for manipulating and returning data, think of them as the query handlers. Each top-level query in the `Query` type has a resolver but we’ll make our own per field. The resolvers are grouped in a JavaScript object, often called a **resolver map**.

Let’s create a `notes.js` file inside `src/resolvers` and add the following code to it:

```jsx
export default {
    Query: {
        notes: (parent, args, {
            models
        }) => {
            return Object.values(models.notes)
        },
        note: (parent, {
            id
        }, {
            models
        }) => {
            return models.notes[id]
        }
    }
}
```

The above resolvers allow us to query either individual notes using the `note` field and provide an `id` argument or an array of notes using the `notes` field. We’ll clean up our resolvers once we link our app to the database using [sequelize](https://sequelize.org) and add Mutations which will allow us to carry out operations other than reading on our data. For now, these resolve dummy data that we’ll have in `src/models/index.js` which contains the following code:

```jsx
let notes = {
    1: {
        id: '1',
        text: 'Hello World',
    },
    2: {
        id: '2',
        text: 'By World',
    },
};

export default {
    notes
};
```

Now that we have the framework set up for how our data will be stored let’s look at how data manipulation will be done using [queries and mutations](https://graphql.org/learn/queries/).

## Queries and mutations

Queries and mutations in GraphQL allow us to access and manipulate data on a GraphQL server. Queries are in charge of read operations whereas mutations are in charge of create, update and delete operations.

To create our queries and mutations, we must first define them in our schema. Let’s edit `src/schema/notes.js` as follows:

```jsx
import {
  gql
} from 'apollo-server-express';

export default gql `
  extend type Query {
    notes: [Note!]
    note(id: ID!): Note!
  }

  extend type Mutation {
    createNewNote(text: String!): Note!
    deleteNote(id: ID!): Boolean!
    updateNote(id: ID!, text: String!): Note!
  }

  type Note {
    id: ID!
    text: String!
  }
`;
```

Queries have already been defined earlier so our new addition is the `Mutation` type. From the types defined, you can get an idea of what the returned data will look like. For instance, `createNewNote` takes a `text` argument that is a string and generates and returns a `Note` object, `updateNote` is similar but it also takes the `id` so that it can find the note to be updated. Meanwhile, `deleteNote` takes an `id` boolean that is used to identify the target note and returns a boolean indicating whether the note has been deleted successfully or not.

This is how you can test your queries. Type the following code in your [graphql playground:](https://github.com/prisma/graphql-playground)

### Get all notes

Fetches and returns all notes saved.

```jsx
query {
  notes {
    id
    text
  }
}
```

Next hit the _Execute Query_ button and you should be able to see the following result:

### Result

```jsx
{
  "data": {
    "notes": [
      {
        "id": "1",
        "text": "Hello World"
      },
      {
        "id": "3",
        "text": "By World"
      }
    ]
  }
}
```

### Get note by id

This returns a piece of the data matching the given argument `id`

```jsx
query{
  note(id: "1") {
    id
   text
  }
}
```

### Result

```jsx
{
  "data": {
    "note": {
      "id": "1",
      "text": "Hello World"
    }
  }
```

Next, we’ll need to write a Mutation resolver. Let’s edit`src/resolvers/notes.js`  
like this:

```jsx
import uuidv4 from 'uuid/v4';

export default {
    Query: {
        notes: (parent, args, {
            models
        }) => {
            return Object.values(models.notes)
        },
        note: (parent, {
            id
        }, {
            models
        }) => {
            return models.notes[id]
        }
    },
    Mutation: {
        createNewNote: (parent, {
            text
        }, {
            models
        }) => {
            const id = uuidv4();
            const newNote = {
                id,
                text
            }
            models.notes[id] = newNote;
            return newNote;
        },

        deleteNote: (parent, {
            id
        }, {
            models
        }) => {
            const {
                [id]: note, ...otherNotes
            } = models.notes
            if (!note) {
                return false
            }
            models.notes = otherNotes
            return true
        },
}
```

For the `createNewNote` Mutation we are generating the unique `id` using the `uuid/v4` library so we’ll need to install it by running:

`npm install uuid/v4 --save`

The resolver takes a text argument, generates a unique `id` and uses them to create a `Note` object which is then appended to the list of notes. It then returns the new note that has been created.

The `deleteNote` Mutation takes an `id` argument, finds a note and creates a new `notes` object without the note to be deleted and replaces the old `notes` object with the new one. It returns `false` if the note is not found and `true` when the note is found and deleted.

The `updateNote` Mutation takes the `id` and `text` as arguments and updates the `Note` in the `notes` object accordingly, returning the updated note at the end.

We can now access these endpoints through the GraphQL playground when we run our application by running `npm start` and going to [`localhost:3000/graphql`](http://localhost:3000/graphql) on the browser. You can then try out these actions:

### Create a new note

Takes a text argument and creates and returns a note.

```jsx
mutation {
  createNewNote( text: "Hello GraphQl") {
    id
    text
  }
}
```

### Result

```jsx
{
  "data": {
    "createNewNote": {
      "id": "3",
      "text": "Hello GraphQl"
    }
  }
}
```

### Update note

Takes text and id arguments and updates and returns a note.

```jsx
mutation {
  updateNote(id:3, text:"Graphql is awesome") {
    id
    text
  }
}
```

### Result

```jsx
{
  "data": {
    "updateNote": {
      "id": "4",
      "text": "Graphql is awesome"
    }
  }
}
```

### Delete note

Takes an id argument and deletes the matching note.

```jsx
mutation {
  deleteNote(id:5)
}
```

## Adding PostgreSQL with Sequelize

We have most of our app ready to go so the next thing we need to look at is how we can save our data to a database. Our database will be [PostgreSQL](https://www.postgresql.org/) so go ahead and install it from their site then start it.

After that, create a database called `mynotes`. To do this you can run the command `psql` in your terminal to open up the PosgreSQL CLI. Once open run:

```jsx
CREATE DATABASE mynotes;
CREATE USER postgres;
GRANT ALL PRIVILEGES ON DATABASE members TO postgres;
```

Next you’ll want to add [PostgreSQL for Node.js](https://github.com/brianc/node-postgres) and [Sequelize (ORM)](https://github.com/sequelize/sequelize) to your project. Run:

```jsx
npm install pg sequelize --save
```

The next step is to update our models to prepare to link to the database as shown below. The model defines the shape of each piece of data as it will be stored in the database:

```jsx
const note = (sequelize, DataTypes) => {
  const Note = sequelize.define("note", {
    text: DataTypes.STRING
  });
  return Note;
};

export default note;
```

Next, connect to your database from within your application in the `src/models/index.js` file:

```jsx
import Sequelize from "sequelize";

const sequelize = new Sequelize(
  process.env.DATABASE,
  process.env.DATABASE_USER,
  process.env.DATABASE_PASSWORD,
  {
    dialect: "postgres"
  }
);

const models = {
  Note: sequelize.import("./notes")
};

Object.keys(models).forEach((key) => {
  if ("associate" in models[key]) {
    models[key].associate(models);
  }
});

export { sequelize };
export default models;
```

You’ll need to define the database name, a database super-user, and the user’s password. You may also want to define a database dialect because Sequelize supports other databases as well.

In the same file, you can physically associate all your models with each other if you have multiple models (hence the `foreEach` loop above) to expose them to your application as data access layer (models) for the database. In our case, we only have one model but this is still good to know.

Now let’s create a `.env` file at the root directory of the project to hold some critical data as environment variables. The database credentials (database name, database super user name, database super-user password) can be stored as environment variables along with the port on which we wish to run our server.

In the `.env` file add the following variables or change them to your liking:

```jsx
PORT=3000
DATABASE=mynotes
DATABASE_USER=postgres
DATABASE_PASSWORD=postgres
```

Next, let’s update `src/index.js` to get our databases synchronized when our application is started. Make the following changes:

```jsx
...
import 'dotenv/config';
import models, {
    sequelize
} from './models';
...

sequelize.sync().then(async () => {
    app.listen({
        port: 8000 // you could change this to process.env.PORT if you wish
    }, () => {
        console.log('Apollo Server on http://localhost:8000/graphql');
    });
});
```

We’ve now linked our application to the database so what we need to do next is replace the logic in our resolvers.

## How to connect resolvers to the database

We had dummy data before but with Sequelize we can now allow us to sync our data with our database, allowing for data persistence. To make this happen, we need to update our resolver in `src/resolvers/notes.js` to integrate the Sequelize API.

```jsx
export default {
  Query: {
    notes: async (parent, args, { models }) => {
      return await models.Note.findAll();
    },

    note: async (parent, { id }, { models }) => {
      return await models.Note.findByPk(id);
    }
  },
  Mutation: {
    createNewNote: async (parent, { text }, { models }) => {
      return await models.Note.create({
        text
      });
    },

    deleteNote: async (parent, { id }, { models }) => {
      return await models.Note.destroy({
        where: {
          id
        }
      });
    },
    updateNote: async (parent, { id, text }, { models }) => {
      await models.Note.update(
        {
          text
        },
        {
          where: {
            id: id
          }
        }
      );
      const updatedNote = await models.Note.findByPk(id, {
        include
      });
      return updatedNote;
    }
  }
};
```

You will notice we no longer need `uuid/v4` as Sequelize automatically handles the assignment of ids in our database. The `findAll()` and `findByPk()` are commonly used Sequelize methods for database operations, `findAll()` returns all entries in a certain table whereas `findPk()` identifies and returns entries that fit a certain criterion such as a matching `id` in our case.

Other Sequelize methods we make use of include `update()` and `destroy()` to update and delete records respectively.

Along with these, we use [async/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) to implement promise-based asynchronous Javascript requests to our database.

## Conclusion

Great! We are all ready to go, the next step is to integrate our GraphQL backend with our front-end app, which we’ll build for mobile in part two of this tutorial. We’ll be working with Apollo and React Native which should be exciting. Stay tuned!
* * *
**Editor's note:** Seeing something wrong with this post? You can find the correct version [here](https://blog.logrocket.com/create-a-react-native-app-with-postgresql-and-graphql-part-1/).

## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps
 
![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)
 
[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
[Try it for free](https://logrocket.com/signup/).
* * *
The post [How to create a React Native app with PostgreSQL and GraphQL: Part 1](https://blog.logrocket.com/create-a-react-native-app-with-postgresql-and-graphql-part-1/) appeared first on [LogRocket Blog](https://blog.logrocket.com).