Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 133 additions & 5 deletions types/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Types Plugin

The `types` plugin is a [Goa](https://github.com/goadesign/goa/tree/v3) plugin
that generates Go data types and validation functions for all user types defined
in a Goa design package.
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:

Expand All @@ -17,7 +17,9 @@ var _ = Type("MyType", func() {
})
```

The plugin generates the file `gen/types/types.go` with the following code:
The plugin generates two files:

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

```go
package types
Expand All @@ -43,6 +45,24 @@ func ValidateMyType(v *MyType) (err error) {
}
```

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

```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
Expand All @@ -53,6 +73,12 @@ 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:
Expand All @@ -71,5 +97,107 @@ necessary as the package is imported solely for its side-effects
## Effects on Code Generation

Enabling the plugin changes the behavior of the `gen` command of the `goa` tool.
The command generates an additional `types/types.go` file under the `gen` folder
containing the type definitions and validations.
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:

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

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

Generates:

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

message Order {
repeated OrderItem items = 1;
}
```

### Maps

The plugin supports map types:

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

Generates:

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

### Any Type Support

The plugin supports the `Any` type for dynamic content:

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

Generates:

```proto
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:

```bash
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.
1 change: 1 addition & 0 deletions types/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const Gendir = "types"
// init registers the plugin generator function.
func init() {
codegen.RegisterPlugin("types", "gen", nil, Generate)
codegen.RegisterPlugin("types-proto", "gen", nil, GenerateProto)
}

// Generate produces the documentation JSON file.
Expand Down
Loading
Loading