loading...
Cover image for GraphQL + TypeScript + PostgreSQL API

GraphQL + TypeScript + PostgreSQL API

wonder2210 profile image Wonder2210 ・5 min read

Introduction

In the current year, one of the most popular stacks is GraphQl and Typescript (and for a while, I think). I started recently a new project, using this stack, I did some GraphQL API's using good Vanilla Javascript before, but even I'm using Typescript for few times. I've never used it for this purpose but I didn't find a tutorial who fits with my requirements, I get it done, then I ask to my self. Why not do a guide?. Here we go

before we are starting :

Why GraphQL ?:

GraphQL provides a complete description of the data in your API, giving clients the power to ask for exactly what they need and nothing more when you have to deal with a great amount of data this is a very nice choice, you can have all the data required with just Running one Query.

Why typescript? :

Typescript is a superset of Javascript that compiles to plain JavaScript.
As JavaScript code grows it gets messier to maintain and reuse, and don't have strong type checking and compile-time error checks, that's where Typescript comes in

Why PostgreSQL?

PostgreSQL is a personal preference, is widely used, open-source, and has a great community, but I'm not going to go deep about it, You can read more about why use it here

Prerequisites

  • yarn you can use NPM no matter
  • node: v.10 or superior
  • postgresql = 12
  • some typescript knowledge

1) Folder Structure

This is how's going to be structured the project

   graphql_api/
       ...
        dist/
          bundle.js
        src/
         database/
              knexfile.ts
              config.ts
              migrations/
              models/
                User.ts
                Pet.ts
          __generated__/
          schema/
              resolvers/
                  user.ts
                  pet.ts
                  index.ts

              graphql/
                  schema.ts
              index.ts/
          index.ts       

2) Main Dependencies

  • Apollo server: Apollo Server is a community-maintained open-source GraphQL server. It works with pretty much all Node.js HTTP server frameworks

  • Objection: i used to use sequelize but i really like objection.js because it is an ORM that embraces SQL

    Development

  • Webpack : webpack is used to compile JavaScript modules, node.js by its own doesn't accept files .gql or .graphql , that's where webpack comes in

First, we are going to install

yarn add graphql apollo-server-express express body-parser objection pg knex

and some dev dependencies

yarn add -D typescript @types/graphql @types/express @types/node  graphql-tag concurrently nodemon ts-node webpack webpack-cli webpack-node-external

3) Configurations

tsconfig

Webpack

4) Hello World

Add the next scripts to your package.json

"scripts":{
     "dev": "concurrently \" nodemon ./dist/bundle.js \" \" webpack --watch\" "
}

index.ts

5) Server config

For this project we are gone to use , Executable schema from graphql-tools wich allow us to generate a GraphQLSchema instance from GraphQL schema language beside this you can also combine types and resolvers from multiple files

src/index.ts

...
const config : Config = {
    schema:schema,// schema definition from schema/index.ts
    introspection: true,//these lines are required to use  
    playground: true,//     playground

}

const server : ApolloServer = new ApolloServer(config);

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

schema/index.ts

import { makeExecutableSchema} from 'graphql-tools';
import schema from './graphql/schema.gql';
import {user,pet} from './resolvers';

const resolvers=[user,pet];

export default makeExecutableSchema({typeDefs:schema, resolvers: resolvers as any});

6) Database

Now we will be working based in the next database diagram, It will be just a register of Users and their pets.
capture
Migration file
For creating the database in Postgres , we'll be using the migrations of knex


and generate the first migration running:

npx knex --knexfile ./src/database/knexfile.ts migrate:make -x ts initial


And your migration file should look's like this


Then run the migration

npx knex --knexfile ./src/database/knexfile.ts migrate:latest


Now we have two tables then we need the models for each table to start executing queries
src/database/models:


then we need to instantiate Knex and give the instance to Objection


import dbconfig from './database/config';
const db = Knex(dbconfig["development"]);

Model.knex(db);

7) Schema

8) generating types

we need the following packages for better type safeting the resolvers :

 yarn add -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/
typescript-resolvers @graphql-codegen/typescript-operations 


create the config file for generate types :

/codegen.yml


overwrite: true
schema: "http://localhost:3000/graphql"
documents: null
generates:
  src/__generated__/generated-types.ts:
    config:
      mappers:
        User:'./src/database/User.ts'
        UpdateUserInput:'./src/database/User.ts'
        Pet:'./src/database/Pet.ts'
    plugins:
      - "typescript"
      - "typescript-resolvers"


add the follow script to packages.json :

...
"generate:types": "graphql-codegen --config codegen.yml"
...


once your server is up , then run :

yarn run generate:types


if you want to go deep generating types from graphql you can read more about here, I highly suggest to do

9) resolvers

schema/resolvers/



Now you should be able to execute all the operations defined before

BONUS:

you can see two errors from typescript

errors

it's not terrible at all, but I would prefer to don't have them

then

the first one I get it solved splitting knexfile.ts and put the configuration that is required for knex in a standalone file

And the second one, from the import of the schema , I get it solved with this useful post
and finally, you should have working your own graphql api

Conclusion

Congratulations ! Now you have a GraphQL API
if you get stucked at any of the steps here is the repo on github , In this tutorial we learned about, how to generate types for Typescript from graphql , solve some issues , I hope you enjoyed this post , if is it the case, please follow me here on DEV and also on twitter I'll be posting more often soon , if you have any suggestion for me I would love to know it , leave it below in the comments box ,Thanks!

Posted on by:

wonder2210 profile

Wonder2210

@wonder2210

Web developer / enthusiast of new technologies / hungry for learn / "the day you no learn is a day lost "

Discussion

markdown guide