liveBook · Manning

Code generation

As explained in gRPC Microservices in Go

Code generation is the automated production of source code from a higher-level specification.

Code generation turns a service contract into language-specific source code. In gRPC, a `.proto` file defines request and response messages and service methods independently of the server’s programming language. Generating client stubs lets another service call those methods without maintaining its own copy of the wire-level API. section 1.1.2 section 3.1

For a Go order service, the path from contract to client is:

  • Define messages such as `CreateOrderRequest` and `CreateOrderResponse`, plus an `Order.Create` RPC, in `order.proto`. section 3.2.2
  • Install `protoc` and the Go message and gRPC plugins, then run `protoc` with separate output flags for each kind of generated code. section 3.2.1 section 3.2.2
  • Use `order.pb.go` for message operations and `order_grpc.pb.go` for gRPC functionality. Create an `OrderClient` with `NewOrderClient(...)`, then call `Create` with a request. section 3.2.2
Listing 3.1 Generation Go source code
protoc -I ./proto \                         #1
   --go_out ./golang \                      #2
   --go_opt paths=source_relative \         #3
   --go-grpc_out ./golang \                 #4
   --go-grpc_opt paths=source_relative \    #5
   ./proto/order.proto                      #6

The `protoc` command sets an import path, directs message and gRPC output into `./golang`, and preserves source-relative paths for both outputs. section 3.2.2

Generated code can stay in the service project or become a dependency for other projects. For shared Order, Payment, and Shipping contracts, a tagged GitHub Actions workflow can run generation per service, initialize Go modules, and push the results for clients to consume. Automating publication does not remove the need for backward- and forward-compatible contract changes: incompatible changes can disrupt services or lose data. section 3.3.2 section 3.5

name: "Protocol Buffer Go Stubs Generation"
on:
  push:
    tags:
      - v**                                                                #1
jobs:
  protoc:
    name: "Generate"
    runs-on: ubuntu-latest
    strategy:
      matrix:
        service: ["order", "payment", "shipping"]                          #2
    steps:
      - name: Install Go
        uses: actions/setup-go@v2
        with:
          go-version: 1.17
      - uses: actions/checkout@v2
      - name: Etract Release Version
        run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV   #3
      - name: "Generate for Golang"
        shell: bash
        run: |
          chmod +x "${GITHUB_WORKSPACE}/run.sh"                            #4
          ./run.sh ${{ matrix.service }} ${{ env.RELEASE_VERSION }}        #5

The workflow runs on pushed version tags and uses a service matrix to invoke the generator for order, payment, and shipping. section 3.3.2

How gRPC Microservices in Go covers it

How deep it goes
Works through compiler flags, generated Go files, client use, and CI automation; defers complete client-server wiring.
Examples
Uses an order-creation RPC, its generated Go client, and a tagged workflow for order, payment, and shipping services.
What it assumes
Starts with .proto message and service definitions, then identifies the compiler and Go plugins needed for generation.
What you can do after
Apply it via protoc and GitHub Actions to generate, publish, and consume Go gRPC code.
How it connects
Connects protocol buffers, gRPC stubs, Go modules, GitHub Actions, and service-contract compatibility.

Also explained in

Compare how 17 books explain code generation →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of gRPC Microservices in Go. The section links point to the parts of the book it draws on.