Template repo for golang graphql apis
This repo contains the basis for generating an opinionated Graph API using:
- ent - insane entity mapping tool, definitely not an ORM but kind of an ORM
- atlas - Schema generation and migration
- gqlgen - Code generation from schema definitions
- gqlgenc - client building utilities with GraphQL
- openfga - Authorization
- echo - High performance, extensible, minimalist Go web framework
- koanf - configuration management
- viper - command line flags / management
Setup Taskfile by following the instructions and using one of the various convenient package managers or installation scripts. You can then simply run task install
to load the associated dependencies. Nearly everything in this repository assumes you already have a local golang environment setup so this is not included. Please see the associated documentation.
- After cloning the repo, you will need to update all occurrences of
go-template
with your repo name. For convenience, atask
command is included:
task clean-template
-
As the tooling suggests, this is schema driven api development so first up, is defining your schema
-
Create a new schema by running the following command, replacing
<object>
with your object:task newschema -- <object>
For example, if you wanted to create a user, organization, and members schema you would run:
task newschema -- User Organization Member
-
This will generate a file per schema in
internal/ent/schema
tree internal/ent/schema internal/ent/schema └── user.go └── organization.go └── member.go
-
You will add your fields, edges, annotations, etc to this file for each schema. See the ent schema def docs for more details.
-
For a simple User, this might look something like :
// Fields of the User. func (User) Fields() []ent.Field { return []ent.Field{ field.Int("age"). Positive(), field.String("name"). Default("unknown"), } } // Edges of the User. func (User) Edges() []ent.Edge { return nil } func (User) Annotations() []schema.Annotation { return []schema.Annotation{ entgql.QueryField(), entgql.Mutations(entgql.MutationCreate(), entgql.MutationUpdate()), } }
-
Now that your schema is created, you want to generate your
ent.graphql
, this will contain all your graphInput
types. The generate commands are setup in theTaskfile
to make things easier:task generate
-
This will create a
schema/ent.graphql
filetree schema schema ├── ent.graphql └── todo.graphql
As well as generated ent files, including the
openapi.json
: -
This will have created a new
internal/graphapi
directory with a resolver per schema objectinternal/graphapi ├── doc.go ├── ent.resolvers.go ├── gen_models.go ├── gen_server.go ├── helpers.go ├── resolver.go └── todo.resolvers.go
-
In the resolvers, there will be stubbed out CRUD operations based on the grapqhl schemas. The business logic and permissions checks should go in here:
// CreateTodo is the resolver for the createTodo field. func (r *mutationResolver) CreateTodo(ctx context.Context, input CreateUserInput) (*User, error) { panic(fmt.Errorf("not implemented: CreateTodo - createTodo")) }
The Datum ecosystem has additional dependencies that were not included in the vanilla template because they will not be required for all services. These include things such as:
To add these to your project, refer to the implementation in Datum
- Now that all the code is there, test it using the playground:
task run-dev
- Using the default config, you should be able to go to your browser of choice and see the playground: http://localhost:1337/playground
- Via curl,
http://localhost:1337/query
- Create DB Migrations with
atlas
:task atlas:create