Installing GraphQL Apollo Server

yarn add apollo-server graphql type-graphql graphql-scalars graphql-fields
yarn add typegraphql-prisma @types/graphql-fields -D

Initializing Apollo Server

app.ts

import { ApolloServer } from 'apollo-server';

const app = new ApolloServer({
  typeDefs: [],
  resolvers: {},
});

export default app;

server.ts

import app from './app';
const port = process.env.PORT || 5002;

app
  .listen({ port })
  .then(() => console.log(`Server is running on port :${port}`));

Installing Prisma

yarn add prisma@3.0.1 -D
yarn add pg @prisma/client@3.0.1

Configuring

Make sure these configuration are on your tsconfig.json

{
  "compilerOptions": {
    "sourceMap": true,
    "outDir": "dist",
    "strict": true,
    "lib": ["esnext"],
    "esModuleInterop": true
  }
}

Initializing a prisma project

npx prisma init

This command created a new directory called prisma which contains a file named schema.prisma and a .env file in the root of the project. schema.prisma contains the Prisma schema with your database connection and the Prisma Client generator. .env is a dotenv file for defining environment variables (used for your database connection).

Setting up the database connection

Edit your prisma/schema.prisma file:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

Add the connection string to your .env file:

DATABASE_URL="postgresql://<USER>:<PASSWORD>@localhost:5432/<DB_NAME>?schema=public"

Configuring typegraphql-prisma

Add to your prisma/schema.prisma file:

generator client {
  provider = "prisma-client-js"
}

generator typegraphql {
  provider = "typegraphql-prisma"
  output   = "./generated/type-graphql"
}

Then run npx prisma generate - this will emit the generated TypeGraphQL classes to the src/prisma/generated/type-graphql folder

Running migrations

npx prisma migrate dev --name init

Integration tests

Install Jest dependencies

yarn add jest-environment-node jest ts-jest @types/jest -D

Initializing Jest

yarn jest --init

Add these configurations to jest.config.ts

import { compilerOptions } from './tsconfig.json';
import { pathsToModuleNameMapper } from 'ts-jest/utils';

{
  ...otherConfigs,
  preset: 'ts-jest',
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
    prefix: '<rootDir>'
  })
}

Execute migrations on your jest-environment-node file using execSync lib.

const { execSync } = require('child_process');
const prismaCli = './node_modules/.bin/prisma';

execSync(`${prismaCli} migrate dev --skip-generate --skip-seed`);

You can load your test environment variables on jest-environment-file using the lib dotenv

require('dotenv').config({
  path: '.env.test',
});

You can overwrite environment variables this way:

this.global.process.env.DATABASE_URL = process.env.DATABASE_URL = 'NEW_VALUE';

Invoke the jest environment file before you execute your tests adding a comment block on the top of your test file

/**
 * @jest-environment ./src/configs/jest-environment
 */

import app from '~/app';

describe('User resolvers', () => {
  it('should query all users', async () => {
    const response = await app.executeOperation({
      query: `
        query GetAllUsers {
          users {
            id
            age
            email
            name
          }
        }
      `,
    });
    expect(response.data?.users).toBeTruthy();
    expect(response.errors).toBeUndefined();
  });
});

Tooling

Transpiling with Babel

Install Babel plugins as dev dependencies to transpile the code

yarn add @babel/plugin-transform-typescript babel-plugin-transform-typescript-metadata @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties @babel/preset-typescript -D

Make sure that your babel.config.js includes the following configuration:

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: 'current',
        },
      },
    ],
    '@babel/preset-typescript',
  ],
  plugins: [
    ['@babel/plugin-transform-typescript'],
    ['babel-plugin-transform-typescript-metadata'],
    ['@babel/plugin-proposal-decorators', { legacy: true }],
    ['@babel/plugin-proposal-class-properties'],
  ],
  ignore: ['**/*.spec.ts'],
};

Eslint with GraphQL

Install eslint-plugin-graphql

yarn add eslint-plugin-graphql -D

Change configuration of your .eslintrc.json

module.exports = {
  rules: {
    'graphql/template-strings': [
      'error',
      {
        env: 'apollo',
        // Import your schema JSON here
        schemaJson: require('./schema.json'),
      },
    ],
  },
  plugins: ['graphql'],
};

Tips

  • Install Prisma extension on your VSCode

Useful links


Enjoy! 🍺