Building a GraphQL API with Golang, Postgres, and Hasura
Check out the Go backend course. In this course, you will learn how to integrate Go in a GraphQL backend server stack with Hasura.
- Golang installed on your local development machine (see the official docs)
- Your preferred code editor (we recommend Visual Studio Code)
- A basic understanding of GraphQL, which you can find in our GraphQL tutorial
Step 1: Select a Golang GraphQL Library
Step 2: Set Up Your Golang GraphQL Project and gqlgen
- Create a directory for your project. In your working directory, open your terminal and initialize it as a Go Module.
go mod init github.com/<user-name>/golang-graphql
- Execute the following command to install the gqlgen library.
go install github.com/99designs/gqlgen@latest
- Create a file called tools.go at the root of your project, where you will list all your dependencies and paste the following code snippet.
// tools.go
package tools
import _ "github.com/99designs/gqlgen"
- Open your terminal and execute the tidy command to add all missing dependencies.
go mod tidy
- Create the Golang GraphQL project structure using the init command.
go run github.com/99designs/gqlgen init
- Open http://localhost:8080/ to test the GraphQL playground.
Step 3: Define Your GraphQL Schema
// schema.graphql
type Movie {
id: ID!
title: String!
url: String!
releaseDate: String!
}
type Query {
movies: [Movie!]!
}
input NewMovie {
title: String!
url: String!
}
type Mutation {
createMovie(input: NewMovie!): Movie!
}
Step 4: Generate Your GraphQL Resolvers
- Navigate to the schema.resolvers.go file and delete the file's contents.
- Execute the following command to use the gqlgen code generation feature to generate resolvers based on your defined schema.
go run github.com/99designs/gqlgen generate
Step 5: Provision Your Postgres Database on Hasura Cloud
- Sign in to Hasura Cloud.
- Create a new project and click on the Launch Console button.
- Navigate to the Data tab and connect an existing database or create a new managed Heroku Postgres database.
- After creating the database, click on the Create Table button in the Data tab and create the table movies with the following columns defined in your GraphQL schema.
- Head over to the Project → Settings → Env vars → Custom Env vars to copy your Postgres database URL, which you will connect to in your Golang project.
Step 6: Connect Your Postgres Database to Golang
- Create an a .env file in the root of your project folder and paste the Postgres database URL as shown below.
DB_URL=postgres://znydojgffymetm:bb7d8540de0280a0lru2oau96q3
- Execute this command to install these drivers.
go get github.com/go-pg/pg/v10 github.com/joho/godotenv
- Open your terminal and execute the tidy command to add any other missing dependencies.
go mod tidy
- In the graph project folder, create a db.go file and paste the following code block.
// db.go
package graph
import (
"os"
"github.com/go-pg/pg"
)
func Connect() *pg.DB {
connStr := os.Getenv("DB_URL")
opt, err := pg.ParseURL(connStr)
if err != nil {
panic(err)
}
db := pg.Connect(opt)
if _, DBStatus := db.Exec("SELECT 1"); DBStatus != nil {
panic("PostgreSQL is down")
}
return db
}
- Modify the contents of the server.go file using the code snippets highlighted in yellow.
// server.go
package main
import (
"github.com/joho/godotenv"
)
const defaultPort = "8080"
func main() {
// ...
err := godotenv.Load(); if err != nil {
log.Fatal("Error loading .env file")
}
// ...
Database := graph.Connect()
srv := handler.NewDefaultServer(
generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{DB: Database}}))
// ...
}
- In the graph folder, navigate to the resolver.go file to add the DB connection field in the Resolver struct as a dependency.
// resolver.go
package graph
import "github.com/go-pg/pg"
type Resolver struct {
DB *pg.DB
}
Step 7: Implement Your Generated Resolvers
- Paste the following code snippet in the createMovie function; it takes in the movie object as input and inserts it into the Postgres database.
// schema.resolvers.go
func (r *mutationResolver) CreateMovie(ctx context.Context, input model.NewMovie) (*model.Movie, error) {
movie := model.Movie{
Title: input.Title,
URL: input.URL,
}
_, err := r.DB.Model(&movie).Insert()
if err != nil {
return nil, fmt.Errorf("error inserting new movie: %v", err)
}
return &movie, nil
}
- Paste the following code snippet in the Movies function. The function retrieves a collection of movies from the Postgres database based on the defined movie model.
// schema.resolvers.go
func (r *queryResolver) Movies(ctx context.Context) ([]*model.Movie, error) {
var movies []*model.Movie
err := r.DB.Model(&movies).Select()
if err != nil {
return nil, err
}
return movies, nil
}
Step 8: Test Your Golang GraphQL API
- Start your Golang server
go run ./server.go
and head over to your browser, then navigate to http://localhost:8080 to access the in-built GraphQL playground. - To test for Mutations, paste the GraphQL Query below into the playground editor to insert a new movie object.
mutation createMovie {
createMovie(
input: {
title: "Rise of GraphQL Warrior Pt1"
url: "https://riseofgraphqlwarriorpt1.com/"
}
){
id
}
}
- To test Queries, paste the GraphQL Query below into the playground editor to fetch all created movie records.
query getMovies {
movies {
title
url
releaseDate
}
}
Get Instant GraphQL APIs on Your Databases with Hasura
Related reading