Ent Contrib

repository·master·Indexed 43 days ago

https://github.com/ent/contrib

A collection of extensions, tools, and plugins for the Ent entity framework. Includes entoas for generating OpenAPI Specification documents, entproto for bidirectional generation between Ent schemas and .proto files, and protoc-gen-entgrpc for generating gRPC server code.

Tokens
6.9K
Snippets
23
Records
32
Agent score
54%

What's inside Ent Contrib

  1. Overview of ent-contrib

    master
    ent-contrib is a collection of extensions and tools designed to complement the ent framework. It provides additional functionality and utilities to extend the capabilities of the core ent ecosystem.
  2. How protoc-gen-entgrpc works

    master

    protoc-gen-entgrpc is a protoc plugin that generates server code implementing the gRPC interface derived from your ent.Schema.

    It requires a path to the ent schema directory via the --entgrpc_opt=schema_path=... flag to map schema definitions to proto definitions. While the entproto CLI generates the necessary protoc invocation for you in a generate.go file, the manual command structure looks like this:

    protoc -I=.. --go_out=.. --go-grpc_out=.. --go_opt=paths=source_relative --entgrpc_out=.. --entgrpc_opt=paths=source_relative,schema_path=../../schema --go-grpc_opt=paths=source_relative entpb/entpb.proto

    Current Limitations:

    • Only "unique" edges (O2O, O2M) are supported; multi-relations are not yet supported.
    • Mutating methods (Create/Update) currently set all fields, ignoring zero/null values and field nullability.
    • All fields are copied from the gRPC request to the ent client; there is no current way to make specific fields non-settable via the service.
  3. What are PULIDs (Prefixed ULIDs)

    master

    PULIDs are an identifier encoding scheme built upon the ULID (Universally Unique Lexicographically Sortable Identifier) scheme. They incorporate a prefix to identify the entity type within the identifier itself.

    Key characteristics:

    • Compatibility: Prefixes are designed to maintain compatibility with base32 encoding.
    • Capacity: If using a 2-character prefix for encoding the entity type, the scheme supports up to 2^32 (1024) distinct entity types.
  4. Set up entproto options in your project

    master

    The plugin requires the options/opts.proto file to be present in your project's include path to recognize the (ent.schema), (ent.field), and (ent.edge) annotations.

    You can download it from the repository into your project's proto directory:

    mkdir -p ent/proto/options
    wget -O ent/proto/options/opts.proto https://raw.githubusercontent.com/ent/contrib/master/entproto/cmd/protoc-gen-ent/options/ent/opts.proto
  5. Run entproto development in Docker

    master

    You can use the provided Dockerfile to mimic the CI environment for code generation.

    1. Build the image:
    docker build --platform='linux/x86_64' -f entproto/Dockerfile -t entproto-dev:latest .
    1. Run the container: Mount your local source code into /go/src from the root contrib/ directory:
    docker run --platform='linux/x86_64' -it -v $(pwd):/go/src -w /go/src/entproto entproto-dev bash
    1. Inside the container: Compile and install the current protoc-gen-entgrpc and protoc-gen-ent binaries, then regenerate and test:
    go install -buildvcs=false ./cmd/protoc-gen-entgrpc && \
    	go install -buildvcs=false ./cmd/protoc-gen-ent && \
    	go generate ./... && \
    	go test ./...
  6. Quick Start: Generate OpenAPI Specification with entoas

    master

    Follow these steps to integrate entoas into your Ent code generation workflow to produce an openapi.json file.

    1. Create the extension runner: Create a file at ent/entc.go with the // +build ignore constraint. Use entoas.NewExtension() to create the extension and pass it to entc.Generate via entc.Extensions(ex).
    2. Configure generation: Update ent/generate.go to point to your new entc.go file using a go:generate directive.
    3. Execute: Run go generate ./... to trigger the Ent code generation and the entoas extension.
    // ent/entc.go
    // +build ignore
    
    package main
    
    import (
    	"log"
    
    	"entgo.io/ent/entc"
    	"entgo.io/ent/entc/gen"
    	"entgo.io/contrib/entoas"
    )
    
    func main() {
    	ex, err := entoas.NewExtension()
    	if err != nil {
    		log.Fatalf("creating entoas extension: %v", err)
    	}
    	err = entc.Generate("./schema", &gen.Config{}, entc.Extensions(ex))
    	if err != nil {
    		log.Fatalf("running ent codegen: %v", err)
    	}
    }
  7. Quick Start: Generate .proto files from ent.Schema

    master

    Use entproto to facilitate the generation of .proto files from your ent.Schema. This process involves annotating your schema, running the entproto CLI, and then using go generate to create the Go code for the protocol buffers and gRPC services.

    Prerequisites

    • Install protoc
    • Install protoc-gen-go and protoc-gen-go-grpc

    Steps

    1. Install dependencies:

      go get -u entgo.io/contrib/entproto
      go get entgo.io/contrib/entproto/cmd/protoc-gen-entgrpc
    2. Annotate your schema: Add entproto.Message() to the schema annotations and assign field numbers using entproto.Field(n). Note that field number 1 is reserved for the schema's ID field.

    3. Run code generation:

      go run entgo.io/contrib/entproto/cmd/entproto -path ./ent/schema
    4. Generate Go files: The previous step creates a .proto file and a generate.go file. Run the following to generate the final Go code:

      go generate ./ent/proto/...
    package schema
    
    import (
    	"entgo.io/ent"
    	"entgo.io/ent/schema"
    	"entgo.io/ent/schema/field"
    	"entgo.io/contrib/entproto"
    )
    
    type User struct {
    	ent.Schema
    }
    
    func (User) Annotations() []schema.Annotation {
    	return []schema.Annotation{
    		entproto.Message(),
    		entproto.Service(), // also generate a gRPC service definition
    	}
    }
    
    func (User) Fields() []ent.Field {
    	return []ent.Field{
    		field.String("user_name").
    			Annotations(entproto.Field(2)),
    	}
    }
  8. Rebuild protoc-gen-entgrpc and run tests

    master

    To rebuild the protoc-gen-entgrpc plugin, regenerate the code, and run all tests, use the following command sequence:

    go generate ./cmd/protoc-gen-entgrpc/... && \
      go install entgo.io/contrib/entproto/cmd/protoc-gen-entgrpc && \
      go generate ./... && \
      go test ./...
  9. Generate Ent schemas from .proto files

    master

    To generate Ent schemas, annotate your Protobuf messages with option (ent.schema).gen = true.

    1. Annotate your message:
    syntax = "proto3";
    package entpb;
    import "options/opts.proto";
    
    option go_package = "github.com/yourorg/project/ent/proto/entpb";
    
    message User {
      option (ent.schema).gen = true;
      string name = 1;
      string email_address = 2;
    }
    1. Run protoc: Use the --ent_out flag to specify the output directory and --ent_opt=schemadir=... to specify where the generated schemas should be placed.
    protoc -I=proto/ --ent_out=. --ent_opt=schemadir=./schema proto/entpb/user.proto
  10. Define Ent schemas in Protobuf messages

    master

    To trigger schema generation for a Protobuf message, you must use the ent.schema extension in the message options. The plugin looks for the gen boolean within these options to decide whether to process the message.

    When a message is marked for generation, the plugin uses the message name (or a custom name provided in the options) as the Ent schema name. Fields within the message are then mapped to Ent fields or edges based on their type and specific Protobuf options.