Skip to content

Golang GraphQL API generator using gqlgen and gorm

License

Notifications You must be signed in to change notification settings

LoopContext/go-graphql-orm

 
 

Repository files navigation

graphql-orm

Godoc Reference Go Report Card

Golang GraphQL API generator using gqlgen and gorm

Why

While following microservices design patterns we ended up with many "model services". gqlgen is perfect tool, but implementing resolvers in every service is getting more and more cumbersome. Using this tool we only have to update model.graphql and all resolvers get generated automatically.

Installation

Before you start, please make sure you have goimports installed:

go get golang.org/x/tools/cmd/goimports

NOTE: Make sure you have Go installed on your system.

  1. Create new project repository
  2. run go mod init [MODULE] to initialize your project with go modules
  3. run go run github.com/loopcontext/go-graphql-orm init
  4. follow initialization instruction (creating makefile is suggested)
  5. open created model.graphql and create your custom model schema
  6. each time you change model, run make generate or go run github.com/loopcontext/go-graphql-orm to recreate generated source codes

NOTE: graphql-orm requires Go modules for installation. If you are running in $GOPATH, make sure you are running init command with GO111MODULE=on

Running locally

For running locally you can use:

make run

or without makefile:

DATABASE_URL=sqlite3://test.db PORT=8080 go run *.go

If you need to debug:

make debug

Environment variables

  • PORT - sets the default port for the API
  • DEBUG - setting to "true" enables debugging for GORM
  • DATABASE_URL - connection string for database in format db://user:password@host:port/tablename (eg. mysql://root:pass@localhost:3306/test; required)
  • EXPOSE_MIGRATION_ENDPOINT - expose /migration endpoint which triggers database migration (migrates to latest database schema; default: false)
  • EXPOSE_PLAYGROUND_ENDPOINT - expose /graphql/playground playground endpoint (allows playground; default: false)
  • TABLE_NAME_PREFIX - set global prefix for all table names (default: "")
  • EVENT_TRANSPORT_URL - destination url for sending mutation events (array supported in format EVENT_TRANSPORT_URL_[INDEX]) see Events transport
  • EVENT_TRANSPORT_SOURCE - custom value for CloudEvent source attribute (default: http://{hostname}/graphql)

Sqlite connection

In case you want to connect with sqlite, you can use local file storage: sqlite3://path/to/file.db

Or use in-memory storage: sqlite3://:memory:

Example

You can find example project at graphql-orm-example repo

Schema preview in Voyager

GraphQL Voyager is very nice tool for previewing your GraphQL Schema, you can run it locally by:

make voyager

or without makefile:

docker run --rm -v `pwd`/gen/schema.graphql:/app/schema.graphql -p 8082:80 graphql/voyager

...after voyager starts up go to https://localhost:8082

All generated files is stored in ./gen/ folder.

Building docker image

There's a provided a docker-compose.yml in the root of your generated API, use it to easily run a dev instance of the server docker-compose up dev and navigate to http://localhost:8081

If you want, use the generated Dockerfile initialization it's as easy as running:

docker build -f docker/Dockerfile -t {IMAGE_NAME} .

If you want to create your own docker image, you can check the example repository for generated Dockerfile: https://github.com/loopcontext/go-graphql-orm-example/blob/master/Dockerfile

What's this library for

While following microservices design patterns we ended up with many "model services". gqlgen is perfect tool, but implementing resolvers in every service is getting more and more cumbersome. Using this tool we only have to update model.graphql and all resolvers get generated automatically.

Events transport

For event driven architecture it's necessary that the service is able to send events about changes in state. Services built using this library automatically send event for every mutation using CloudEvents (entity created/updated/deleted and changed column and their values). Supported targets are:

For more information about event structure see: https://github.com/loopcontext/go-graphql-orm/blob/master/events/model.go

Migrations and automigrations

Since version 0.4.0 the migrations using gormigrate are introduced and it's possible to write custom migrations with rollbacks. The automigration (with foreign keys) is still available, but gormigrate migrations are used by default. You use following commands:

  • make migrate - runs gormigrate migrations
  • make automigrate - runs gorm basic automigration

The same applies for HTTP endpoints (when EXPOSE_MIGRATION_ENDPOINT=true):

  • POST /migrate - runs gormigrate migrations
  • post /automigrate - runs gorm basic automigration

To add new migration, edit src/migrations file and its GetMigrations method. For more information see gormigrate Readme

Caveats

If you need to do a relationship with a table, and you don't need it to be queried on its related records table, let's say it's a typification table (i.e: categories) then you hve to do like this:

type Category @entity {
    name String @column
    description Srting @column
    product Product @relationship(inverse: "category")
}

type Product @entity {
    code String @column
    description String @column
    category Category @relationship(inverse:"product")
}

This way when querying for categories, even though Product and ProductId will show in the list of fields, they won't get filled. This comes with the caveat that the table WILL have a productId column in the db you can always drop it, but it will be nullable and never filled.

About

Golang GraphQL API generator using gqlgen and gorm

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 91.7%
  • Gherkin 7.5%
  • Other 0.8%