DEV Community

Cover image for Create and Deploy your first GraphQL API with Apollo Server 4, TypeGraphQL and Render
Eder
Eder

Posted on • Edited on

Create and Deploy your first GraphQL API with Apollo Server 4, TypeGraphQL and Render

TL;DR
Repo:
https://github.com/emunhoz/graphql-api-with-apollo-server-railway

Client side (React + Vite) consuming our API demo:
https://codesandbox.io/p/sandbox/xenodochial-rain-6pt9ld

Update (13/10/2023)

Playground in production:
https://graphql-apollo-api-3ybl.onrender.com/

Intro

In this step-by-step guide, we will learn how to create a GraphQL API from scratch using Apollo Server 4, type-graphql, and Railway.

We will explore the necessary steps to set up the development environment, install the relevant dependencies, define resolvers, and finally deploy the API using Railway.

Initial Configuration

Create a new folder:

mkdir graphql-api-with-apollo-server-railway
Enter fullscreen mode Exit fullscreen mode

Create a package.json file:

cd graphql-api-with-apollo-server-railway && npm init -y
Enter fullscreen mode Exit fullscreen mode

Add typescript:

npm install typescript -D
Enter fullscreen mode Exit fullscreen mode

Generate a tsconfig.json file:

npx tsc --init
Enter fullscreen mode Exit fullscreen mode

We are going to use tsx to run local scripts.

npm install tsx -D
Enter fullscreen mode Exit fullscreen mode

tsx is a TypeScript runtime that allows you to run TypeScript files directly without the need for additional build steps during development.

We are going to use tsup to build the api.

npm install tsup -D
Enter fullscreen mode Exit fullscreen mode

tsup is a zero-config TypeScript bundler that simplifies the process of building and bundling TypeScript code for deployment.

Add new scripts to package.json file:

  // ...
  "scripts": {
    "dev": "tsx src/index.ts",
    "dev:watch": "tsx watch src/index.ts",
    "build": "tsup src",
    "start": "npm run build && node dist/index.js" // `start` command is necessary in order to use Railway
  },
  // ...
Enter fullscreen mode Exit fullscreen mode

These scripts allow you to run the development server, watch for file changes, build the API, and start the production server.

Create an index.ts file inside src

// src/index.ts

interface LogProps {
  message: string
}

function log({ message }: LogProps): string {
  console.log(message)
  return message
}

log({ message: 'Hello' })
Enter fullscreen mode Exit fullscreen mode

This is a simple example code that logs a message to the console. It serves as a placeholder to demonstrate the build process.

if you run npm run build you will see the dist folder:

// dist/index.js

"use strict";

function log({ message }) {
  console.log(message);
  return message;
}
log({ message: "Hello" });
Enter fullscreen mode Exit fullscreen mode

The npm run build command transpiles the TypeScript code to JavaScript and outputs the compiled code in the dist folder.

Here we finished the initial config!

Setting up type-graphql

The type-graphql library allows us to use the "code first" approach instead of the traditional "schema first" approach in GraphQL development. With the "code first" approach, we define our functions and classes first, and then the schema is automatically generated based on those definitions.

This approach offers a more intuitive and convenient way to build GraphQL APIs, as it eliminates the need to write the schema manually and keeps it in sync with the code.

npm i graphql class-validator type-graphql
Enter fullscreen mode Exit fullscreen mode

These are the necessary dependencies for setting up Apollo Server with type-graphql. graphql is the core GraphQL library, class-validator allows for input validation, and type-graphql provides decorators and utilities for building GraphQL schemas and resolvers with TypeScript.

npm i reflect-metadata
Enter fullscreen mode Exit fullscreen mode

reflect-metadata is a package that enables reflection and metadata introspection for TypeScript, which is required by type-graphql.

Update the tsconfig.json file by adding lib, emitDecoratorMetadata, strictPropertyInitialization and experimentalDecorators:

{
  "compilerOptions": {
    "lib": ["es2018", "esnext.asynciterable"],
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "strictPropertyInitialization": false,
    // ...
  }
}
Enter fullscreen mode Exit fullscreen mode

These configuration options enable the necessary features and support for decorators and metadata used by type-graphql.

If you need, check out the documentation for more: https://typegraphql.com/docs/installation.html

Adding @apollo/server

Apollo Server is a GraphQL server development framework that makes it easy to create complete GraphQL servers.

Install @apollo/server:

npm install @apollo/server
Enter fullscreen mode Exit fullscreen mode

Create a new file src/main/graphql/apollo/setup.ts

// src/main/graphql/apollo/setup.ts

import { ApolloServer } from '@apollo/server'
import { buildSchema } from 'type-graphql'
import { startStandaloneServer } from '@apollo/server/standalone'
import { HelloWorldResolver } from '../resolvers/hello-world'

export async function setupApolloServer() {
  const schema = await buildSchema({
    resolvers: [HelloWorldResolver],
  })

  const server = new ApolloServer({ schema })

  const { url } = await startStandaloneServer(server, {
    listen: { port: Number(process.env.PORT) || 4000 },
  })

  console.log(`🚀 Server ready at ${url}`)
}
Enter fullscreen mode Exit fullscreen mode

Then, import the setupApolloServer function into the index.ts file:

// src/index.ts

import 'reflect-metadata'
import { setupApolloServer } from './main/graphql/apollo/setup'

async function main() {
  await setupApolloServer()
}

main()
Enter fullscreen mode Exit fullscreen mode

Let's create our first resolver

Create a new file src/main/graphql/resolvers/hello-world.ts.
We will convert our log() function from index.ts into a resolver.

// src/main/graphql/resolvers/hello-world.ts

import { Arg, Query, Resolver } from 'type-graphql'

@Resolver()
export class HelloWorldResolver {
  @Query(() => String)
  async log(@Arg('message', (type) => String) message: string) {
    return `Hey there! This is the message: ${message}`
  }
}
Enter fullscreen mode Exit fullscreen mode

Now we are good to go! Run npm run dev to open the Apollo Server Playground:

Apollo playground local

Add the variable message:

{
  "message": "My message here!"
}
Enter fullscreen mode Exit fullscreen mode

Then run the Query. You should receive the following response:

{
  "data": {
    "log": "Hey there! This is the message: My message here!"
  }
}
Enter fullscreen mode Exit fullscreen mode

Deploying with Railway

1 - Go to https://railway.app, log in or create an account, and import your repository via Github account.

2 - After importing the project, Railway will start the deployment process automatically.

Railway app deploying

3 - To generate a public domain, click on your project name, go to "Settings", "Domain", and click on "Generate domain".

Generate domain

Here is an example of the generated domain: https://graphql-railway-api-production.up.railway.app/

Please note that the query documentation is only available in the local environment. Remember to avoid exposing it in production mode. However, if you want generate the query doc in production, you can try setting up GraphQL Code Generator for documentation generation.

Update (13/10/2023)

Deploying using Render

Deploying using Render is easier as deploying with Railway. First, you need to specify your node version:

Then, connect to Render with your Github account.

In the Build & Deploy follow the commands:

  • In the build command use: npm install.
  • Start Command use: npm run start.

Demo: https://graphql-apollo-api-3ybl.onrender.com/

Deploy! Have fun!

Wrapping up

We now have a ready-to-go production endpoint: https://graphql-railway-api-production.up.railway.app/

In this case, to consume it on the client side, we can configure @apollo/client.

I created a simple application using Vite (React) and @apollo/client using our production URL API.

Check out this link: https://codesandbox.io/p/sandbox/xenodochial-rain-6pt9ld

Hope you enjoyed it!

Top comments (0)