Design-based APIs and microservices in Go

Goa logo

Goa is a framework for building micro-services and APIs in Go using a unique design-first approach.


Build Status Godoc Packages Godoc DSL Slack

Overview

Goa takes a different approach to building services by making it possible to describe the design of the service API using a simple Go DSL. Goa uses the description to generate specialized service helper code, client code and documentation. Goa is extensible via plugins, for example the goakit plugin generates code that leverage the Go kit library.

The service design describes the transport independent layer of the services in the form of simple methods that accept a context and a payload and return a result and an error. The design also describes how the payloads, results and errors are serialized in the transport (HTTP or gRPC). For example a service method payload may be built from an HTTP request by extracting values from the request path, headers and body. This clean separation of layers makes it possible to expose the same service using multiple transports. It also promotes good design where the service business logic concerns are expressed and implemented separately from the transport logic.

The Goa DSL consists of Go functions so that it may be extended easily to avoid repetition and promote standards. The design code itself can easily be shared across multiple services by simply importing the corresponding Go package again promoting reuse and standardization across services.

Code Generation

The Goa tool accepts the Go design package import path as input and produces the interface as well as the glue that binds the service and client code with the underlying transport. The code is specific to the API so that for example there is no need to cast or "bind" any data structure prior to using the request payload or response result. The design may define validations in which case the generated code takes care of validating the incoming request payload prior to invoking the service method on the server, and validating the response prior to invoking the client code.

Getting Started Guides

A couple of Getting Started guides produced by the community.

Video

Joseph Ocol from Pelmorex Corp. goes through a complete example writing a server and client service using both HTTP and gRPC transports.

GOA Design Tutorial

Blog

Gleidson Nascimento goes through how to create a complete service that using both CORS and JWT based authentication to secure access.

API Development in Go Using Goa

Installation

Assuming you have a working Go setup, and are using Go modules:

env GO111MODULE=on go get -u goa.design/goa/v3/...@v3

Alternatively, when NOT using Go modules (this installs Goa v2, see below):

env GO111MODULE=off go get -u goa.design/goa/...

Goa Versions and Go Module Support

Goa v2 and Goa v3 are functionally identical. The only addition in Goa v3 is support for Go modules. Goa v3 requires Go v1.11 or above, it also requires projects that use Goa to be within modules.

Projects that use Goa v3 use goa.design/goa/v3 as root package import path while projects that use v2 use goa.design/goa (projects that use v1 use github.com/goadesign/goa).

Note that the Goa v3 tool is backwards compatible and can generate code for v2 designs. This means that you don't need to swap the tool to generate code for designs using v2 or v3 (designs using v1 use a different tool altogether).

Vendoring

Since Goa generates and compiles code vendoring tools are not able to automatically identify all the dependencies. In particular the generator package is only used by the generated code. To alleviate this issue simply add goa.design/goa/codegen/generator as a required package to the vendor manifest. For example if you are using dep add the following line to Gopkg.toml:

required = ["goa.design/goa/codegen/generator"]

This only applies to Goa v2 as vendoring is not used together with Go modules.

Stable Versions

Goa follows Semantic Versioning which is a fancy way of saying it publishes releases with version numbers of the form vX.Y.Z and makes sure that your code can upgrade to new versions with the same X component without having to make changes.

Releases are tagged with the corresponding version number. There is also a branch for each major version (v1, v2 and v3).

Current Release: v3.2.6

Teaser

Note: the instructions below assume Goa v3.

1. Design

Create a new Goa project:

mkdir -p calcsvc/design
cd calcsvc
go mod init calcsvc

Create the file design.go in the design directory with the following content:

package design

import . "goa.design/goa/v3/dsl"

// API describes the global properties of the API server.
var _ = API("calc", func() {
        Title("Calculator Service")
        Description("HTTP service for adding numbers, a goa teaser")
        Server("calc", func() {
		Host("localhost", func() { URI("http://localhost:8088") })
        })
})

// Service describes a service
var _ = Service("calc", func() {
        Description("The calc service performs operations on numbers")
        // Method describes a service method (endpoint)
        Method("add", func() {
                // Payload describes the method payload
                // Here the payload is an object that consists of two fields
                Payload(func() {
                        // Attribute describes an object field
                        Attribute("a", Int, "Left operand")
                        Attribute("b", Int, "Right operand")
                        // Both attributes must be provided when invoking "add"
                        Required("a", "b")
                })
                // Result describes the method result
                // Here the result is a simple integer value
                Result(Int)
                // HTTP describes the HTTP transport mapping
                HTTP(func() {
                        // Requests to the service consist of HTTP GET requests
                        // The payload fields are encoded as path parameters
                        GET("/add/{a}/{b}")
                        // Responses use a "200 OK" HTTP status
                        // The result is encoded in the response body
                        Response(StatusOK)
                })
        })
})

This file contains the design for a calc service which accepts HTTP GET requests to /add/{a}/{b} where {a} and {b} are placeholders for integer values. The API returns the sum of a and b in the HTTP response body.

2. Implement

Now that the design is done, let's run goa on the design package. In the calcsvc directory run:

goa gen calcsvc/design

This produces a gen directory with the following directory structure:

gen
├── calc
│   ├── client.go
│   ├── endpoints.go
│   └── service.go
└── http
    ├── calc
    │   ├── client
    │   │   ├── cli.go
    │   │   ├── client.go
    │   │   ├── encode_decode.go
    │   │   ├── paths.go
    │   │   └── types.go
    │   └── server
    │       ├── encode_decode.go
    │       ├── paths.go
    │       ├── server.go
    │       └── types.go
    ├── cli
    │   └── calc
    │       └── cli.go
    ├── openapi.json
    └── openapi.yaml

7 directories, 15 files
  • calc contains the service endpoints and interface as well as a service client.
  • http contains the HTTP transport layer. This layer maps the service endpoints to HTTP handlers server side and HTTP client methods client side. The http directory also contains a complete OpenAPI 2.0 spec for the service.

The goa tool can also generate example implementations for both the service and client. These examples provide a good starting point:

goa example calcsvc/design

calc.go
cmd/calc-cli/http.go
cmd/calc-cli/main.go
cmd/calc/http.go
cmd/calc/main.go

The tool generated the main functions for two commands: one that runs the server and one the client. The tool also generated a dummy service implementation that prints a log message. Again note that the example command is intended to generate just that: an example, in particular it is not intended to be re-run each time the design changes (as opposed to the gen command which should be re-run each time the design changes).

Let's implement our service by providing a proper implementation for the add method. Goa generated a payload struct for the add method that contains both fields. Goa also generated the transport layer that takes care of decoding the request so all we have to do is to perform the actual sum. Edit the file calc.go and change the code of the add function as follows:

// Add returns the sum of attributes a and b of p.
func (s *calcsrvc) Add(ctx context.Context, p *calc.AddPayload) (res int, err error) {
        return p.A + p.B, nil
}

That's it! we have now a full-fledged HTTP service with a corresponding OpenAPI specification and a client tool.

3. Run

Now let's compile and run the service:

cd cmd/calc
go build
./calc
[calcapi] 16:10:47 HTTP "Add" mounted on GET /add/{a}/{b}
[calcapi] 16:10:47 HTTP server listening on "localhost:8088"

Open a new console and compile the generated CLI tool:

cd calcsvc/cmd/calc-cli
go build

and run it:

./calc-cli calc add -a 1 -b 2
3

The tool includes contextual help:

./calc-cli --help

Help is also available on each command:

./calc-cli calc add --help

Now let's see how robust our code is and try to use non integer values:

./calc-cli calc add -a 1 -b foo
invalid value for b, must be INT
run './calccli --help' for detailed usage.

The generated code validates the command line arguments against the types defined in the design. The server also validates the types when decoding incoming requests so that your code only has to deal with the business logic.

4. Document

The http directory contains the OpenAPI 2.0 specification in both YAML and JSON format.

The specification can easily be served from the service itself using a file server. The Files DSL function makes it possible to server static file. Edit the file design/design.go and add:

var _ = Service("openapi", func() {
        // Serve the file with relative path ../../gen/http/openapi.json for
        // requests sent to /swagger.json.
        Files("/swagger.json", "../../gen/http/openapi.json")
})

Re-run goa gen calcsvc/design and note the new directory gen/openapi and gen/http/openapi which contain the implementation for a HTTP handler that serves the openapi.json file.

All we need to do is mount the handler on the service mux. Add the corresponding import statement to cmd/calc/http.go:

import openapisvr "calcsvc/gen/http/openapi/server"

and mount the handler by adding the following line in the same file and after the mux creation (e.g. one the line after the // Configure the mux. comment):

openapisvr.Mount(mux)

That's it! we now have a self-documenting service. Stop the running service with CTRL-C. Rebuild and re-run it then make requests to the newly added /swagger.json endpoint:

^C[calcapi] 16:17:37 exiting (interrupt)
[calcapi] 16:17:37 shutting down HTTP server at "localhost:8088"
[calcapi] 16:17:37 exited
go build
./calc

In a different console:

curl localhost:8088/swagger.json
{"swagger":"2.0","info":{"title":"Calculator Service","description":...

Resources

Consult the following resources to learn more about Goa.

Docs

See the goa.design website.

Examples

The examples directory contains simple examples illustrating basic concepts.

Contributing

See CONTRIBUTING.

Owner
Goa
The design-based microservice framework
Goa
Comments
  • JSONAPI

    JSONAPI

    I cant help but notice that the DSL allows JSONAPI to be used, so that clients are able to be given info on the data relationships.

    Is this something that likely to be implemented. I ask because i am currently using this ( https://github.com/manyminds/api2go ) in golang that does the job, but woudl like to change over to goa design.

  • Add TeeReader to service.DecodeRequest

    Add TeeReader to service.DecodeRequest

    Hi,

    I changed the function DecodeRequest such that middlewares still can read the request body afterwards. In my case, this is required to implement an authentication middleware which computes a hash sum over the plain request body as part of the protocol. Currently, this does not work for non-trivial bodies, since DecodeRequest closes the body.

    Would be nice to see the patch upstream.

    Thanks!

    Cheers, Stefan

  • vendored goagen broken?

    vendored goagen broken?

    Hey,

    I'm working on a project that uses glide as its package manager. We followed these instructions but we still get an this error when calling the ./vendor/github.com/goadesign/goa/goagen/goagen binary:

    $ ./vendor/github.com/goadesign/goa/goagen/goagen app -d github.com/goadesign/goa-cellar/design
    invalid plugin package import path: cannot find package "github.com/goadesign/goa/goagen/gen_app" in any of:
        /usr/lib/golang/src/github.com/goadesign/goa/goagen/gen_app (from $GOROOT)
        /home/kkleine/go/src/github.com/goadesign/goa/goagen/gen_app (from $GOPATH)
    

    Reproducing the issue

    To reproduce this issue you can start with a clean $GOPATH by temporarily renaming your old $GOPATH to `$GOPATH.bak``

    $ mv -v $GOPATH $GOPATH.bak
    $ mkdir -p $GOPATH/src/
    $ mkdir -p $GOPATH/bin/
    $ mkdir -p $GOPATH/pkg/
    

    Download glide v0.11.0 from the release page https://github.com/Masterminds/glide/releases/tag/v0.11.0 and install in your PATH (not your GOPATH)

    Now, clone the offical goadesign/goa-cellar example repo.

    $ git clone https://github.com/goadesign/goa-cellar.git $GOPATH/src/github.com/goadesign/goa-cellar
    $ cd $GOPATH/src/github.com/goadesign/goa-cellar
    

    Run glide init and answer questions with Y and M.

    This is how the glide.yaml looks on my computer:

    package: github.com/goadesign/goa-cellar
    import:
    - package: github.com/goadesign/goa
      subpackages:
      - client
      - cors
      - design
      - design/apidsl
      - goatest
      - logging/log15
      - middleware
      - middleware/cors
      - middleware/security/basicauth
    - package: github.com/inconshreveable/log15
      version: ^2.11.0
    - package: github.com/spf13/cobra
    - package: golang.org/x/net
      subpackages:
      - context
      - websocket
    

    Run glide install to fetch the dependencies.

    Now, build the goagen tool (This is from the goa documentation)

    $ cd ./vendor/github.com/goadesign/goa/goagen
    $ go build -v
    $ cd ../../../../../
    

    Now, run goagen app to get the error I get:

    $ ./vendor/github.com/goadesign/goa/goagen/goagen app -d github.com/goadesign/goa-cellar/design
    invalid plugin package import path: cannot find package "github.com/goadesign/goa/goagen/gen_app" in any of:
        /usr/lib/golang/src/github.com/goadesign/goa/goagen/gen_app (from $GOROOT)
        /home/kkleine/go/src/github.com/goadesign/goa/goagen/gen_app (from $GOPATH)
    

    Questions

    Do you have any idea why this happens?

    Why isn't the vendor directory checked for example? Only $GOROOT and $GOPATH are checked.

    Developement Environment

    Double checking my go setup for GO15VENDOREXPERIMENT=1

    $ go env
    GOARCH="amd64"
    GOBIN="/home/kkleine/go/bin"
    GOEXE=""
    GOHOSTARCH="amd64"
    GOHOSTOS="linux"
    GOOS="linux"
    GOPATH="/home/kkleine/go"
    GORACE=""
    GOROOT="/usr/lib/golang"
    GOTOOLDIR="/usr/lib/golang/pkg/tool/linux_amd64"
    GO15VENDOREXPERIMENT="1"
    CC="gcc"
    GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
    CXX="g++"
    CGO_ENABLED="1"
    My GOPATH contains only these directories:
    

    Restore your GOPATH

    Don't forget to restore your old $GOPATH:

    mv $GOPATH /tmp
    mv -v $GOPATH.bak $GOPATH
    
  • Add new command `goagen controller`

    Add new command `goagen controller`

    Related to the discussion hold in: https://github.com/goadesign/goa/pull/1041#issuecomment-278413154

    Available Commands:
      app         Generate application code
      bootstrap   Equivalent to running the "app", "main", "client" and "swagger" commands.
      client      Generate client package and tool
      commands    Lists all commands and flags in JSON
      controller  Generate controller scaffolding
      gen         Run third-party generator
      js          Generate JavaScript client
      main        Generate application scaffolding
      schema      Generate JSON Schema
      swagger     Generate Swagger
      version     Print the version number of goagen
    
    Flags:
          --debug           enable debug mode, does not cleanup temporary files.
      -d, --design string   design package import path
      -o, --out string      output directory (default ".")
    
    Use "goagen [command] --help" for more information about a command.
    

    I set as default controller for the package name and the generated file controller.go. There are some conflicts with pkg from other commands (target pkg), so I created a new param called pkg-name. This flag specifies the name of the generated package. In the generated file, I coded a Factory function NewControllerService that returns the created controller scaffold (in gen_main is main.go).

    Generate controller scaffolding
    
    Usage:
      goagen controller [flags]
    
    Flags:
          --force             overwrite existing files
          --pkg string        Name of generated Go package containing controllers supporting code (contexts, media types, user types etc.) (default "app")
          --pkg-name string   specify the name of the generated controller package (default "controller")
          --res string        specify the name of the resource and is compulsory (default "controller")
    
    Global Flags:
          --debug           enable debug mode, does not cleanup temporary files.
      -d, --design string   design package import path
      -o, --out string      output directory (default ".")
    

    ping @raphael

  • Add a `Bytes` Primitive Type to Goa `v1`

    Add a `Bytes` Primitive Type to Goa `v1`

    A Goa primitive type that maps to a []byte in Go and possibly JSON objects in other places (e.g. swagger) could be a useful. It is upcoming in Goa v2, however a v1 update with it could be useful (and simpler/faster to implement). Any thoughts or questions?

  • Create v3 to support Go modules

    Create v3 to support Go modules

    Goal

    We want to keep supporting goa v1 but also want to make goa v2 a clearly separate framework as the differences between the two are fairly fundamental. Today one can use v1 by using the package path github.com/goadesign/goa and v2 with goa.design/goa and we'd like to keep that going forward if only for backwards compatibility. The actual source code for v2 is in the v2 branch in the github.com/goadesign/goa repo. The https://goa.design/goa endpoint redirects go get to gopkg.in/goa/v2 which points to the v2 branch.

    Problem

    The introduction of Go modules breaks the scheme described above as the go tool now does a local checkout of the branch which is incompatible with the use of gopkg.in.

    Proposed solution

    The proposal consists of moving the v2 branch to its own repo, e.g. github.com/goadesign/goa2.

    Other considered solutions

    An alternative would be to create a v2 directory in the existing repo but that does not seem attractive because:

    • It would be confusing for newcomers (v1 still leaves under the top level directory).
    • It would obfuscate where most of the work will actually happen in the future.
    • It would be a breaking changes for v2 as all the import paths would have to be modified to append v2

    Notes

    This proposal does not address Go modules support in v1.

  • Rendering Media Type with nullable primitive attribute

    Rendering Media Type with nullable primitive attribute

    Hi,

    As discussed on Slack#goa, I'm summing up problem with optional/nullable Media Type attributes.

    All primitive attributes generated by Goa are being generated with the type stated in the design. Such generation however doesn't allow these primitive types be nullable and forces producer of Media Type instance to set (keep) a default value instead.

    This problem is not present for Attributes having custom Media Type (Qux), which are being generated with type of pointer to the Media Type (Qux *Qux) - pointer is nullable.

    Hence I'm missing a possibility to state in the Media Type Attribute design that the Attribute is nullable, so it would be generated with pointer type. Something like this:

    Baz := MediaType("Baz", func() {
        Attributes(func() {
            Attribute("Count", Integer)
        }
    }
    MyMediaType := MediaType("MyMediaType", func() {
        Attributes(func() {
            Attribute("Foo", Integer, Nullable) // missing
            Attribute("Bar", Integer) // already present
            Attribute("Baz", Baz) // already present
        }
    }
    

    Would generate following:

    struct MyMediaType {
        Foo *int, // missing
        Bar int, // already present
        Baz *Baz, // already present
    }
    
  • Goa gen error

    Goa gen error

    Received the following error when we run goa gen go get: malformed module path "goa865448624": missing dot in first path element. Seems like this has got to do with the release of v3.5.1

  • make a pass at test improvements

    make a pass at test improvements

    @raphael Made a pass at the improvements discussed around test composition. I removed some test cases for brevity, but will add them back afterwards. Essentially each test case has its own DSL definition and assert func

  • Use Decoder and Encoder based on Content-Encoding header

    Use Decoder and Encoder based on Content-Encoding header

    As per now I'm unsure how to properly implement a Gzip Encoder and Decoder in Goa. I think a Middleware is the way to go, but I would like to append a Decoder to requests with header Content-Encoding: gzip, and an Encoder to Accept-Encoding: gzip.

    Is this possible to do today? The only way I see is to use either a middleware which I'm unable to set via design.go, or to create custom content types for encoded requests which isn't an optimal solution.

  • Need a way to disable unwanted examples produced for swagger

    Need a way to disable unwanted examples produced for swagger

    Lets say I have a resource that is defined as:

    var Path = ArrayOf(String)
    
    // A resource with a payload that has:
    ...
        Attribute("paths", ArrayOf(Path), "foo", func() {
            Example([][]string{{"path1"}, {"path2"}})
        })
    

    goa v1 translates it to swagger.yaml as:

          paths:
            description: foo
            example:
            - - path1
            - - path2
            items:
              example:
              - Quod voluptatem blanditiis autem maxime praesentium quia.
              items:
                example: Quod voluptatem blanditiis autem maxime praesentium quia.
                type: string
              type: array
            type: array
    

    adding unwanted Latin quotes. It would be nice to have a way to disable them, or to provide my own custom examples that would override these "Quod voluptatem blanditiis autem maxime praesentium quia"s.

  • Consider adding goa.Endpoints interface

    Consider adding goa.Endpoints interface

    Like you do with goahttp.Servers, you should consider adding the same logic of Use method interface also for an array of goa.Endpoints

    here is an example that shows why

    type Endpoint interface {
        Use(func(goa.Endpoint) goa.Endpoint)
    }
    
    endpoints := []Endpoint{
        searchEndpoints,
        hotelEndpoints,
        // ...
    }
    
    // add endpoints middleware
    endpointMiddlewares := []func(goa.Endpoint) goa.Endpoint{
        sentrymiddleware.SentryPerformanceMonitor(),
    }
    
    for _, endpoint := range endpoints {
        for _, endpointMiddleware := range endpointMiddlewares {
            endpoint.Use(endpointMiddleware)
        }
    }
    

    This can be made better if

    type Endpoints []Endpoint
    
    func (eps Endpoints) Use(m func (goa.Endpoint) goa.Endpoint) {
        for _, ep := range eps {
            ep.Use(m)
        }
    }
    
    // ...
    
    endpoints := Endpoints{
        searchEndpoints,
        hotelEndpoints,
        // ...
    }
    
    // add endpoints middleware
    endpointMiddlewares := []func(goa.Endpoint) goa.Endpoint{
        sentrymiddleware.SentryPerformanceMonitor(),
    }
    
    for _, endpointMiddleware := range endpointMiddlewares {
        endpoints.Use(endpointMiddleware)
    }
    

    I think the feature is relatively simple to implement, in the example I added the interface inside my code for compatibilty and to make it work, but I hope you get the idea

    ADDITIONAL NOTE: By making Use accept variadics we can even simplify more this code, but it might break some logics of compatibility with HTTP package

  • Required list attributes in Result are return as null if the value is empty

    Required list attributes in Result are return as null if the value is empty

    Let's say I have this design:

    import . "goa.design/goa/v3/dsl"
    
    var TodosResult = Type("TodosResult", func() {
    	Attribute("user", String, func() {
    		Description("user ID")
    	})
    
    	Attribute("todos", ArrayOf(String), func() {
    		Description("List of todos")
    	})
    
    	Required("user", "todos") // NOTE HERE todos IS REQUIRED
    })
    
    var _ = Service("todo-service", func() {
    	Description("Simple Todo Service")
    	Error("NotFound")
    
    	Method("get-todos", func() {
    		Description("Return a list of todos for user")
    		Payload(String)
    		Result(TodosResult)
    		HTTP(func() {
    			GET("/todos/{userID}")
    			Response("NotFound", StatusNotFound)
    		})
    	})
    })
    

    The above design, generates this service endpoint:

    type Service interface {
    	// Return a list of todos for user
    	GetTodos(context.Context, string) (res *TodosResult, err error)
    }
    

    And If implement it like this:

    type TodosService struct {
    }
    
    func (service *TodosService) GetTodos(ctx context.Context, userID string) (res *api.TodosResult, err error) {
    	var todos []string // empty list
    	return &api.TodosResult{
    		User:  userID,
    		Todos: todos,
    	}, nil
    }
    

    As you can see, the empty list has no memory allocated, so the returned http response is like this:

    {"user":"USER_ID","todos":null}
    

    But the expected result to be like this:

    {"user":"USER_ID","todos":[]}
    

    I checked the generated response decoder:

    // NewGetTodosResponseBody builds the HTTP response body from the result of the
    // "get-todos" endpoint of the "todo-service" service.
    func NewGetTodosResponseBody(res *todoservice.TodosResult) *GetTodosResponseBody {
    	body := &GetTodosResponseBody{
    		User: res.User,
    	}
    	if res.Todos != nil {
    		body.Todos = make([]string, len(res.Todos))
    		for i, val := range res.Todos {
    			body.Todos[i] = val
    		}
    	}
    	return body
    }
    

    It won't allocate an array if the value coming is nil. I believe the generated code in this case should be like this, specially when the attribute is marked as Required:

    // NewGetTodosResponseBody builds the HTTP response body from the result of the
    // "get-todos" endpoint of the "todo-service" service.
    func NewGetTodosResponseBody(res *todoservice.TodosResult) *GetTodosResponseBody {
    	body := &GetTodosResponseBody{
    		User: res.User,
    	}
    	if res.Todos != nil {
    		body.Todos = make([]string, len(res.Todos))
    		for i, val := range res.Todos {
    			body.Todos[i] = val
    		}
    	} else {
    		body.Todos = []string{} // NEW CODE
    	}
    	return body
    }
    

    What do you think? Could you guide me to make the change and submit a PR?

  • gprc is not working in alpine linux

    gprc is not working in alpine linux

    Ref. https://github.com/goadesign/goa/issues/3182

    The above description is a problem that occurred after updating "protoc" to v3.15.8 on Alpine Linux.

    The dynamic library connection does not seem to proceed normally on Alpine Linux.

  • Is there a way for a

    Is there a way for a "type" to reference some of the fields of another "type".

    Sorry, I just learned goa today. I want to achieve the following effect:

    Define a user type and rules

    Define a createUserRequest that references the user's partial fields.

  • Fix broken type references in custom package

    Fix broken type references in custom package

    Addresses #3198

    • Augmented the description of the struct:pkg:path Meta tag to include description of 2 two limitations
    • Added validation to check for those two cases
    • When that meta tag is set on a user type, internally copy that meta tag down the sub-type tree (for all user types that are fields within it and all user type fields within them)
    • Changed one other unrelated Unions line to use existing AddMeta() function
  • Oneof not properly populating openapi3 yaml

    Oneof not properly populating openapi3 yaml

    When using the GOA DSL to define the schema for an appropriate structure response when querying the server API, I used the following Types utilizing the built-in OneOf function.

    var Topology = Type("Topology", func() {
    	Description("Feeder Topology")
    	Attribute("nodes", ArrayOf(node), "Nodes" , func() {
    	})
    })
    
    
    var node = Type("Node", func() {
    	OneOf("Attribute", func() {
    		Description("Attributes for Devices or Neighbors")
    		Attribute("Device Attribute", device, func() {
    		})
    		Attribute("Neighbor Attribute", neighbor, func() {
    		})
    	})
    })
    
    `var device = Type("Device", func() {
    	Description("Device attributes")
    	Attribute("normal_status", String, "device", func() {
    		devStatus()
    	})
    })
    
    `var neighbor = Type("Neighbor", func() {
    	Description("Attributes for Neighbor")
    	Attribute("node", String, "node of the neighbor", func() {
    		Example("local")
    	})
    })
    

    Viewing the generated openapi3.yaml file in the Swagger Editor reveals the absence of the neighbor and device schemas. The Node type contains the union enum types, but the value section only shows a JSON formatted union value, instead of listing the attributes inside of the Device/Neighbor types. Screenshot from 2022-11-28 14-32-30 The generated yaml does not use the OpenAPI oneOf keyword.

The microservices have a loosely coupled architecture design
The microservices have a loosely coupled architecture design

ETI_Assignment1 5.1.3.1 Design consideration The microservices have a loosely coupled architecture design. The microservices created include Passenger

Dec 12, 2021
Create production ready microservices mono repo pattern wired with Neo4j. Microservices for other languages and front end repos to be added as well in future.
Create production ready microservices mono repo pattern wired with Neo4j. Microservices for other languages and front end repos to be added as well in future.

Create Microservices MonoRepo in GO/Python Create a new production-ready project with backend (Golang), (Python) by running one CLI command. Focus on

Oct 26, 2022
Go-kit-microservices - Example microservices implemented with Go Kit

Go Kit Microservices Example microservices implemented with go kit, a programmin

Jan 18, 2022
Rpcx-framework - An RPC microservices framework based on rpcx, simple and easy to use, ultra fast and efficient, powerful, service discovery, service governance, service layering, version control, routing label registration.

RPCX Framework An RPC microservices framework based on rpcx. Features: simple and easy to use, ultra fast and efficient, powerful, service discovery,

Jan 5, 2022
Go microservice tutorial project using Domain Driven Design and Hexagonal Architecture!

"ToDo API" Microservice Example Introduction Welcome! ?? This is an educational repository that includes a microservice written in Go. It is used as t

Jan 4, 2023
Sample cloud-native application with 10 microservices showcasing Kubernetes, Istio, gRPC and OpenCensus.
Sample cloud-native application with 10 microservices showcasing Kubernetes, Istio, gRPC and OpenCensus.

Online Boutique is a cloud-native microservices demo application. Online Boutique consists of a 10-tier microservices application. The application is

Dec 31, 2022
Go microservices with REST, and gRPC using BFF pattern.
Go microservices with REST, and gRPC using BFF pattern.

Go microservices with REST, and gRPC using BFF pattern. This repository contains backend services. Everything is dockerized and ready to

Jan 4, 2023
TinyHat.Me: Microservices deployed with Kubernetes that enable users to propose hat pictures and try on hats from a user-curated database.
TinyHat.Me: Microservices deployed with Kubernetes that enable users to propose hat pictures and try on hats from a user-curated database.

Click here to see the "buggy" version ?? The Scenario TinyHat.Me is an up and coming startup that provides an API to allow users to try on tiny hats v

Jun 17, 2022
Istio - An open platform to connect, manage, and secure microservices

Istio An open platform to connect, manage, and secure microservices. For in-dept

Jan 5, 2022
A suite of microservices for software-defined networking (SDN) and bare-metal provisioning

M3L is a suite of microservices for software-defined networking (SDN) and bare-metal provisioning, which store their data as Custom Resources in Kubernetes.

Jan 19, 2022
An open platform to connect, manage, and secure microservices.

Istio An open platform to connect, manage, and secure microservices. For in-depth information about how to use Istio, visit istio.io To ask questions

Feb 6, 2022
MadeiraMadeira boilerplate project to build scalable, testable and high performance Go microservices.

MadeiraMadeira boilerplate project to build scalable, testable and high performance Go microservices.

Sep 21, 2022
A standard library for microservices.

Go kit Go kit is a programming toolkit for building microservices (or elegant monoliths) in Go. We solve common problems in distributed systems and ap

Jan 1, 2023
Zeebe.io - Workflow Engine for Microservices Orchestration

Distributed Workflow Engine for Microservices Orchestration

Jan 2, 2023
goTempM is a full stack Golang microservices sample application built on top of the Micro platform.
goTempM is a full stack Golang microservices sample application built on top of the Micro platform.

goTempM is a full stack Golang microservices sample application built on top of the Micro platform.

Sep 24, 2022
Microservices using Go, RabbitMQ, Docker, WebSocket, PostgreSQL, React
Microservices using Go, RabbitMQ, Docker, WebSocket, PostgreSQL, React

Microservices A basic example of microservice architecture which demonstrates communication between a few loosely coupled services. Written in Go Uses

Jan 1, 2023
Box is an incrementally adoptable tool for building scalable, cloud native, microservices.

Box is a tool for building scalable microservices from predefined templates. Box is currently in Beta so if you find any issues or have some ideas

Feb 3, 2022
Best microservices framework in Go, like alibaba Dubbo, but with more features, Scale easily.
Best microservices framework in Go, like alibaba Dubbo, but with more features, Scale easily.

Best microservices framework in Go, like alibaba Dubbo, but with more features, Scale easily.

Dec 30, 2022
Access to b2c microservices through this service
Access to b2c microservices through this service

API service Access to b2c microservices through this service Config file Create config file with services addresses. Services: vdc - get camera inform

Nov 8, 2021