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
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
typescript
...
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
typescript
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.
Migration file
For creating the database in Postgres , we'll be using the migrations of knex
and generate the first migration running:
bash
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
bash
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
typescript
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 :
bash
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
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 :
json
...
"generate:types": "graphql-codegen --config codegen.yml"
...
once your server is up , then run :
bash
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
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!
Top comments (1)
Great write up!! Thank you for taking the time to create this