Journey to the real world by cloning DEV.to backend server(part 3)
Tags: node, apollo, express, prisma
Published: 2021-05-13 04:15:33


> In the last series we have installed the required minimum dependencies to setup our project as we will move further in this project we will install our required dependencies according to requirement.

Apollo server use schema first approach to write graphql query which create not much problem in smaller project but when your project grows and required better type for your schema then you should go through `nexus schema` which is code first approach to write graphql schema.

> In this project we will use apollo server schema first approach for simplicity and we will explore the Query , Mutation and Subscription to design our application.

At first we will setup prisma with javascript and postgresql.
If you want to setup prisma for typescript or any other database you can explore [here](https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch-typescript-postgres).

we have already install prisma as a dev dependencies in our previous series. You can setup postgresql on ubuntu using [this](https://www.digitalocean.com/community/tutorials/how-to-install-postgresql-on-ubuntu-20-04-quickstart) blog post on digital ocean

open the terminal at the root of your project devblog_server and generate prisma project.

```
npx prisma init

```
This will initialize a brand new prisma project containing a folder `prisma` which contain `schema.prisma` file `schema.prisma` is a only one source of truth for our database model . If we want to create any table in and connect to any type of database whole configuration and model creation can be done in this file.

You will notice `prisma init ` also create a `.env` file . `.env` file is a configuration file which is useful in case of storing any secrets that your application required. We can install it manually using `pnpm add dotenv` if you are working on nodejs.But prisma automatically install it in our dependencies so we have not required to install it here.

open `.env` file you will see there is one field which prisma create for you to connect to database. Here we will using postgresql so it will seem like

```
DATABASE_URL="postgresql://postgres:harsh12345@localhost:5432/devblog"
```

`DATABASE_URL is field that can used as a environment variable in our nodejs file to get data stored in it `

`postgres:harsh12345` contain postgresql username and password  `username:password` it use UNIX like authentication flow which contain role for different user.

`@localhost:5432` is a host and port on which postgresql server is up and running.

`devblog` is our database name which  prisma will automatically create for us when we will apply our first migration

> do not push `.env` file to github always add `.env` in you `.gitignore` file because it contain all of your secrets and connection url when we will deploy this project we will see how we will use heroku postgres url for now we will use local postgres server on machine.


Lets create some folder structure for our project. Every one have their own way to create project structure . I also follow my own way to configure it. I have created it like this it can scale and easily add new features in future

At first create `src/` directory in your root level . for us our root level is `devblog_server` . 
Then create `server.js` file where we will configure our server

`server.js`

```javascript
const { ApolloServer ,gql} = require("apollo-server-express");
const context = require("./context");
const http = require("http");
const express = require("express");
const { PORT } = require("./config");

const typeDefs  = gql`
type Query {
   hello : String!
}

`
const resolvers = {
 Query :{
     hello(){
   return "welcome the real world"
    }
 }

async function startApolloServer() {
  const app = express();

  const server = new ApolloServer({
    typeDefs,
    resolvers,
    context,
    tracing: true, // tracing trace our request and response time and much more.
  });
  await server.start();


  server.applyMiddleware({ app });

// testing for REST endpoints through express server

  app.use((req, res, next) => {
    return res.status(200).json({
      success: true,
      message: "Express server up & running",
    });
  });

  const httpServer = http.createServer(app);

  server.installSubscriptionHandlers(httpServer);

  await new Promise((resolve) => httpServer.listen(PORT, resolve));
  console.log(`🚀 Express Server ready at http://localhost:${PORT}`);
  console.log(
    `🚀 Graphql Server ready at http://localhost:${PORT}${server.graphqlPath}`
  );
  console.log(
    `🚀 Subscriptions ready at ws://localhost:${PORT}${server.subscriptionsPath}`
  );
}

startApolloServer();
``` 


Above we have imported and instanceated Apollo server , express server and native nodejs  http server to handle all of our subscriptions , mutation and query.

 
`tracing` is work like and even better than morgan . In `REST` world we use `morgan` to log our req and res time tracing do the same job in graphql playground . we will see graphql playground in our next series when we start our first server.

create `context.js and config.js in src/ folder`

`context.js`

```javascript

const prisma = require("./prisma");

module.exports = ({ req, res }) => {
 

  return {
    prisma,
  };
};


```


here we imported prisma and pass to context of apollo server so that prisma can available in all of our resolvers. 

>  Be careful do not create new instance of PrismaClient in your every resolvers because it will impact your application performance . you can read about performance optimization in prisma docs [here](https://www.prisma.io/docs/guides/performance-and-optimization/connection-management).


`config.js`

```javascript
exports.PORT = process.env.PORT

```

`.env`


```
...
PORT=4000
```


> we knew that when we will deploy our backend on heroku their PORT randomly assigned hence there PORT will automatically configured using heroku environment variable


In our next series we start our server on localhost and apply our first migration by creating user and post model.