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
Create a package.json
file:
cd graphql-api-with-apollo-server-railway && npm init -y
Add typescript
:
npm install typescript -D
Generate a tsconfig.json
file:
npx tsc --init
We are going to use tsx
to run local scripts.
npm install tsx -D
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
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
},
// ...
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' })
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" });
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
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
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,
// ...
}
}
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
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}`)
}
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()
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}`
}
}
Now we are good to go! Run npm run dev
to open the Apollo Server Playground
:
Add the variable message
:
{
"message": "My message here!"
}
Then run the Query
. You should receive the following response:
{
"data": {
"log": "Hey there! This is the message: My message here!"
}
}
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.
3 - To generate a public domain, click on your project name, go to "Settings", "Domain", and click on "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)