1. Create a new Go file named
ent/entc.go, and paste the following content:
2. Edit the
ent/generate.go file to execute the
ent/entc.go is ignored using a build tag, and it's executed by the
go generate command
generate.go file. The full example can be found in the ent/contrib repository.
3. Run codegen for your ent project:
After running codegen, the following add-ons will be added to your project.
A new file named
ent/node.go was created that implements the Relay Node interface.
If you are using the Universal IDs option in the schema migration, the NodeType is derived from the id value and can be used as follows:
However, if you use a custom format for the global unique identifiers, you can control the NodeType as follows:
Here's a configuration example for a todo app as exists in ent/contrib/entgql/todo.
The pagination template adds a pagination support according to the Relay Cursor Connections Spec. More info about the Relay Spec can be found in its website.
The ordering option allows us to apply an ordering on the edges returned from a connection.
- The generated types will be
autobinded to GraphQL types if a naming convention is preserved (see example below).
- Ordering can only be defined on ent fields (no edges).
- Ordering fields should normally be indexed to avoid full table DB scan.
- Pagination queries can be sorted by a single field (no order by ... then by ... semantics).
Let's go over the steps needed in order to add ordering to an existing GraphQL type. The code example is based on a todo-app that can be found in ent/contrib/entql/todo.
Ordering can be defined on any comparable field of ent by annotating it with
Note that the given
OrderField name must match its enum value in graphql schema.
That's all the schema changes required, make sure to run
go generate to apply them.
Next we need to define the ordering types in graphql schema:
Note that the naming must take the form of
autobinding to the generated ent types.
Alternatively @goModel directive can be used for manual type binding.
That's all for the GraphQL schema changes, let's run
gqlgen code generation.
Head over to the Todo resolver and update it to pass
orderBy argument to
The collection template adds support for automatic GraphQL fields collection
for ent-edges using eager-loading. That means, if a query asks for nodes and their edges, entgql will add automatically
steps to the root query, and as a result, the client will execute constant number of queries to the database - and it works recursively.
For example, given this GraphQL query:
The client will execute 1 query for getting the users, 1 for getting the photos, and another 2 for getting the posts, and their comments (4 in total). This logic works both for root queries/resolvers and for the node(s) API.
In order to configure this option to specific edges, use the
entgql.Annotation as follows:
The GraphQL extension generates also edge-resolvers for the nodes under the
edge.go file as follows:
However, if you need to explicitly write these resolvers by hand, you can add the
forceResolver option to your GraphQL schema:
Then, you can implement it on your type resolver.
The enum template implements the MarshalGQL/UnmarshalGQL methods for enums generated by ent.
entgql.Transactioner handler executes each GraphQL mutation in a transaction. The injected client for the resolver
is a transactional
Hence, code that uses
ent.Client won't need to be changed. In order to use it, follow these steps:
1. In the GraphQL server initialization, use the
entgql.Transactioner handler as follows:
2. Then, in the GraphQL mutations, use the client from context as follows:
The ent/contrib contains several examples at the moment:
- A complete GraphQL server with a simple Todo App with numeric ID field
- The same Todo App in 1, but with UUID type for the ID field
- The same Todo App in 1 and 2, but with a prefixed ULID or
PULIDas the ID field. This example supports the Relay Node API by prefixing IDs with the entity type rather than employing the ID space partitioning in Universal IDs.