Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Types Plugin

The types plugin is a Goa plugin that generates Go data types, validation functions, and Protocol Buffer message definitions for all user types defined in a Goa design package.

Given the following design:

var _ = Type("MyType", func() {
        Description("My type")
        Attribute("age", Int, "Age", func() {
                Minimum(0)
        })
        Attribute("name", String, "Name")
        Required("age", "name")
})

The plugin generates two files:

Generated Go Code (gen/types/types.go)

package types

import 	goa "goa.design/goa/v3/pkg"

type (
        // My type
	MyType struct {
        	// Age
        	Age int
        	// Name
        	Name string
        }
)

// ValidateMyType runs the validations defined on MyType
func ValidateMyType(v *MyType) (err error) {
	if v.Age < 0 {
                err = goa.MergeErrors(err, goa.InvalidRangeError("v.age", v.Age, 0, true))
        }
	return
}

Generated Protocol Buffer Definitions (gen/types/types.proto)

syntax = "proto3";

package types;

option go_package = "<your-module>/types";

// My type
message MyType {
  // Age
  int32 age = 1;
  // Name
  string name = 2;
}

Usage Pattern

This plugin makes it possible to share data types between Goa microservices and other Go based processes such as daemons or adapters. A prototypical use case is a data pipeline where messages are sent to queues (AWS SQS, AWS Kinesis, Kafka, etc.) to be consumed by an adapter. The adapter can use the data structures generated by the types plugin to decode and validate messages. The adapter can then make requests to a Goa microservice whose design package imports the original design package defining the data types thus guaranteeing compatibility.

The protobuf definitions enable:

  • Cross-language compatibility with protobuf-based systems
  • Efficient binary serialization
  • gRPC service integration
  • Schema evolution with backwards compatibility

Enabling the Plugin

To enable the plugin simply import both the types package as follows:

import (
  . "goa.design/goa/v3/dsl"
  _ "goa.design/plugins/v3/types"
)

Note the use of blank identifier to import the types package which is necessary as the package is imported solely for its side-effects (initialization).

Effects on Code Generation

Enabling the plugin changes the behavior of the gen command of the goa tool. The command generates two additional files under the gen/types folder:

  • types.go - containing the Go type definitions and validations
  • types.proto - containing the Protocol Buffer message definitions

Type Mappings

The plugin maps Goa types to both Go and Protocol Buffer types:

Goa Type Go Type Proto Type
Boolean bool bool
Int int int32
Int32 int32 int32
Int64 int64 int64
UInt uint uint32
UInt32 uint32 uint32
UInt64 uint64 uint64
Float32 float32 float
Float64 float64 double
String string string
Bytes []byte bytes
Any interface{} google.protobuf.Any
ArrayOf(T) []T repeated T
MapOf(K,V) map[K]V map<K, V>

Features

Arrays and Nested Types

The plugin handles complex nested structures:

var _ = Type("Order", func() {
    Attribute("items", ArrayOf("OrderItem"))
})

var _ = Type("OrderItem", func() {
    Attribute("name", String)
    Attribute("quantity", Int)
})

Generates:

message OrderItem {
  string name = 1;
  int32 quantity = 2;
}

message Order {
  repeated OrderItem items = 1;
}

Maps

The plugin supports map types:

var _ = Type("Config", func() {
    Attribute("settings", MapOf(String, String))
})

Generates:

message Config {
  map<string, string> settings = 1;
}

Any Type Support

The plugin supports the Any type for dynamic content:

var _ = Type("Envelope", func() {
    Attribute("metadata", MapOf(String, Any))
})

Generates:

import "google/protobuf/any.proto";

message Envelope {
  map<string, google.protobuf.Any> metadata = 1;
}

Compiling Protocol Buffers

To compile the generated .proto files to Go code, use the Protocol Buffer compiler:

protoc --go_out=. --go_opt=paths=source_relative \
    gen/types/types.proto

This generates gen/types/types.pb.go which can be used alongside the Goa-generated gen/types/types.go for maximum interoperability.