Codegen Configuration
entrest.Config is passed to
entrest.NewExtension in your entc.go file. It runs at code generation time and controls what
paths, parameters, and schemas appear in openapi.json.
//go:build ignore
// Copyright (c) Liam Stanley <liam@liam.sh>. All rights reserved. Use of// this source code is governed by the MIT license that can be found in// the LICENSE file.
package main
import ( "log"
"entgo.io/ent/entc" "entgo.io/ent/entc/gen" "github.com/lrstanley/entrest")
func main() { ex, err := entrest.NewExtension(&entrest.Config{ SpecFromPath: "../base-openapi.json", // Using a base spec to start with, not required. Handler: entrest.HandlerStdlib, WithTesting: true, StrictMutate: true, ListNotFound: true, DefaultFilterID: true, GlobalRequestHeaders: entrest.RequestIDHeader, GlobalResponseHeaders: entrest.RateLimitHeaders, }) if err != nil { log.Fatalf("creating entrest extension: %v", err) }
err = entc.Generate( "./database/schema", &gen.Config{ Target: "./database/ent", Schema: "github.com/example/my-project/internal/database/schema", Package: "github.com/example/my-project/internal/database/ent", Features: []gen.Feature{ gen.FeaturePrivacy, }, }, entc.Extensions(ex), ) if err != nil { log.Fatalf("failed to run ent codegen: %v", err) }}NewExtension(nil) is equivalent to NewExtension(&entrest.Config{}). Most fields have defaults
applied in Validate before
generation runs.
If you do not provide Spec or
SpecFromPath, entrest
starts from an empty spec and sets:
| Field | Default |
|---|---|
openapi | 3.0.3 |
info.title | EntGo Rest API |
info.version | 1.0.0 |
Set API title, description, servers, security schemes, and custom paths through Extending the Spec.
DefaultOperations
lists which CRUD operations are generated for every schema by default. When unset, all five are
enabled: create, read, update, delete, and list.
Per-schema or per-edge overrides use
WithIncludeOperations and
WithExcludeOperations.
Read-only API (list and get only):
ex, err := entrest.NewExtension(&entrest.Config{ DefaultOperations: []entrest.Operation{ entrest.OperationList, entrest.OperationRead, },})An empty DefaultOperations list fails validation — at least one operation is required.
DefaultFilterID adds
id filter parameters to list endpoints when your schema does not declare an explicit id field
(ent's implicit ID). The filters use the EQ and array predicate groups. Edge list filters are not
added unless the edge is marked filterable with
WithFilter.
List endpoints are paginated by default. Global defaults:
| Option | Default |
|---|---|
ItemsPerPage | 10 |
MinItemsPerPage | 1 |
MaxItemsPerPage | 100 |
DisablePagination
turns pagination off globally; per-schema overrides use
WithPagination.
See Pagination for query parameters, response shape, and per-schema limits.
| Option | Default | Purpose |
|---|---|---|
DefaultEagerLoad | false | Eager-load every edge |
EagerLoadLimit | 1000 | Max items per eager-loaded edge (-1 disables) |
DisableEagerLoadNonPagedOpt | false | Keep pagination on eager-loaded edge endpoints |
DisableEagerLoadedEndpoints | false | Skip edge endpoints when the edge is eager-loaded |
DisableEdgeEndpoints | false | Skip all edge endpoints |
Per-edge behavior is controlled with annotations such as
WithEagerLoad and
WithEdgeEndpoint.
See Eager Loading for usage and when not to eager-load.
AddEdgesToTags adds
eager-loaded edge entity names to the tags array on parent schema operations. Edge endpoints
already include both parent and child tags. This is mainly useful for large schemas where tags help
clients find related resources in the spec.
StrictMutate documents and
enforces 400 responses when create or update bodies contain fields not defined on the schema.
ListNotFound documents 404
on list endpoints when filters match no rows. The default is 200 with an empty content array.
See Error handling for the response shape.
AllowClientIDs allows an
id field in create request bodies (for client-supplied UUIDs or natural keys). This is a security
sensitive option — see
Auth and permissions. Per-schema
control uses
WithAllowClientIDs.
DisablePatchJSONTag
skips entrest's JSON tag hook that removes omitempty from generated struct tags. With the hook
enabled (default), optional and defaulted fields still appear in JSON responses. Fields marked
json:"-" are unchanged.
Global request headers, response headers, and error response schemas are configured on
GlobalRequestHeaders,
GlobalResponseHeaders,
and GlobalErrorResponses.
When unset, error responses default to
DefaultErrorResponses
(400, 401, 403, 404, 409, 429, 500).
See Extending the Spec for presets (RequestIDHeader,
RateLimitHeaders), custom headers, and hooks.
| Option | Effect on the spec |
|---|---|
Handler | HandlerNone generates only openapi.json — no rest handler package. HandlerStdlib or HandlerChi also generate handler code. See Mount the Handler. |
DisableSpecHandler | Omits GET /openapi.json from the spec, disables embedding the spec in the binary, and turns off /docs and Link header support in the handler. |
Writer | Write the spec to a custom io.Writer instead of <ent>/rest/openapi.json. |
Templates | Additional or replacement gen.Template values for handler codegen. |
WithTesting generates
resttest helpers; it requires a non-HandlerNone handler. See
Testing.
When handler generation is enabled and the spec handler is not disabled, the embedded spec is served
at GET {BasePath}/openapi.json. See API Docs.
PreGenerateHook runs
before paths are merged into the base spec. PostGenerateHook
runs after merge but before global headers and error responses are applied — use it when custom paths
should receive those globals. PreWriteHook
runs after the full spec is resolved, immediately before it is written.
Examples are in Extending the Spec.
Most global options have matching annotations on schemas, edges, or fields. The full list is on Annotation Reference.

