Design-based APIs and microservices in Go

Overview

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/[email protected]

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.

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.

    need example 
    opened by joeblew99 24
  • 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

    opened by ZjMNZHgG5jMXw 20
  • 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
    
    opened by kwk 20
  • 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

    opened by hectorj2f 19
  • 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?

    enhancement wontfix 
    opened by JKhawaja 18
  • 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.

    v2 v2 release 
    opened by raphael 17
  • 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
    }
    
    opened by rootpd 15
  • 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

    opened by jeffreylim-foodpanda 14
  • 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

    opened by maleck13 14
  • 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.

    enhancement 
    opened by jarlefosen 14
  • 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.

    opened by konstantin-dzreev 13
  • 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.

    opened by JeffKahn1212 0
  • Broken references to user types used within other user types that have a struct:pkg:path Meta() tag

    Broken references to user types used within other user types that have a struct:pkg:path Meta() tag

    When using a line like:

    	Meta("struct:pkg:path", "types")
    

    within a user type definition that contains an attribute of another user type, a compilation error occurs in the struct definition because the package of the second type has not been imported in that file.

    Example:

    var FirstType = Type("FirstType", func() {
    	Meta("struct:pkg:path", "types")
    	Attribute("id", String)
    	Attribute("name", String)
    	Attribute("description", String)
    	Attribute("thing", SecondType)
    })
    
    var SecondType = Type("SecondType", func() {
    	Attribute("Description", String)
    })
    

    yields

    package types
    
    // FirstType is the payload type of the TestService service create method.
    type FirstType struct {
    	ID          *string
    	Name        *string
    	Description *string
    	Thing       *SecondType
    }
    

    where the following line fails to compile because SecondType is in a different package but not imported.

    	Thing       *SecondType
    

    Run the following in this example repo to reproduce the issue:

    make goa-gen
    make build
    
    opened by c-reeder 3
  • No 'request' in openapi when using SkipRequestBodyEncodeDecode

    No 'request' in openapi when using SkipRequestBodyEncodeDecode

    I'm using SkipRequestBodyEncodeDecode very similar to the Upload/Download example.

    I've been using one of the code generators using openapi files as input and it was not creating any code for the body portion of the respective command. When looking at the generated openapi section, there is no "requestBody" declared similar to when I would declare one in Payload.

    I'm not an expert on openapi, and don't really know what exactly I would be expecting.

    However, I have two use cases I would like to define:

    1. The HTTP body is some unspecified json (required Content-Type json and maybe yaml)
    2. The body could be anything as long as Content-Type is provided

    In both case I would like to get a Reader on the content, exactly as it happens now when using SkipRequestBodyEncodeDecode, but have the right info included in openapi(3).json which would allow code generators to do the right thing.

    Thanks

    opened by maxott 2
  • HTTP router lookupFunc panics with index out of range when given bad URLs

    HTTP router lookupFunc panics with index out of range when given bad URLs

    👋 hello!

    we often see panics coming from our router when we get hit by people vuln scanning our app. we use lookupFunc to serve our frontend if no backend routes match. I think we're just missing a range check before evaluating. Obviously this isn't your code, but it's in the router in the code generated by goa. I'll raise this issue on the treemux repo too, but figured it was worth reporting here.

    for what it's worth, it looks like the router hasn't been actively maintained in the last year, perhaps switching to a maintained router would be worthwhile?

    an example URL that panics: GET /images/../cgi/cgi_i_filter.js

    Here's the rough shape of our setup:

    // LookupFunc is associated with a mux router. It permits querying the router to see if it
    // can respond to a request.
    type LookupFunc func(w http.ResponseWriter, r *http.Request) (httptreemux.LookupResult, bool)
    
    func SinglePageApp(urlPrefix, dirPath string, includeSourcemaps bool) func(h http.Handler, lookupFunc LookupFunc) http.Handler {
    	fs := static.LocalFile(dirPath, true)
    	fileserver := http.FileServer(fs)
    	if urlPrefix != "" {
    		fileserver = http.StripPrefix(urlPrefix, fileserver)
    	}
    
    	return func(h http.Handler, lookupFunc LookupFunc) http.Handler {
    		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    			// If we have an official route for this request, we should skip our handler. We
    			// only run when we can't find a match.
    			if _, found := lookupFunc(w, r); found {
    				h.ServeHTTP(w, r)
    				return
    			}
    
    			if !fs.Exists(urlPrefix, r.URL.Path) {
    				r.URL.Path = "/"
    			}
                             // serving the SPA goes here
    

    thanks! 🙏

    opened by arussellsaw 1
  • About the error return parameter problem

    About the error return parameter problem

    // Login implements Login. func (s *abcsrvc) Login(ctx context.Context, p *abc.LoginPayload) (res *abc.LoginResult, err error) { res = &abc.LoginResult{} fmt.Println(p.Account, "::::", p.Password) is := true res.ID = is return res, errors.New("error") }

    The error I want is { "code": 200, "msg": "", "data": null, // interface{} "success": true }

    actual error return { "name": "fault", "id": "evRYMdXV", "message": "error", "temporary": false, "timeout": false, "fault": true }

    请问怎么去更改呢?

    opened by isqiguo 1
  • Streaming: unable to write error status code

    Streaming: unable to write error status code

    We noticed a change in behavior with https://github.com/goadesign/goa/pull/3001: if no results are streamed back but an error is returned, Goa is unable to write the correct status code.

    The new call to w.Write(nil) has a side-effect of writing out the "200 OK" status code: https://github.com/goadesign/goa/blob/7698ee44c9111e26eb0ce4f3b264af44530caf0c/http/codegen/server.go#L498-L506

    So for the non-hijacked case, the subsequent call to encodeError will be unable to write out the correct status code, printing an error:

    http: superfluous response.WriteHeader call
    

    The rest of the response body can still be written, fortunately, but the status code will be 200.

    bug 
    opened by jim-slattery-rs 2
Releases(v3.10.2)
  • v3.10.2(Oct 30, 2022)

    What's Changed

    • Ignore default values when decoding proto fields by @raphael in https://github.com/goadesign/goa/pull/3168
    • Fix required path params request init by @raphael in https://github.com/goadesign/goa/pull/3170
    • Bump google.golang.org/grpc from 1.50.0 to 1.50.1 by @dependabot in https://github.com/goadesign/goa/pull/3172
    • Bump golang.org/x/text from 0.3.7 to 0.3.8 by @dependabot in https://github.com/goadesign/goa/pull/3173
    • Bump github.com/getkin/kin-openapi from 0.104.0 to 0.106.0 by @dependabot in https://github.com/goadesign/goa/pull/3174
    • Test test coverage by @raphael in https://github.com/goadesign/goa/pull/3175
    • Update README.md by @raphael in https://github.com/goadesign/goa/pull/3176
    • Tweak Foresight job settings by @raphael in https://github.com/goadesign/goa/pull/3177
    • Qualify streaming CLI payload builder name by @raphael in https://github.com/goadesign/goa/pull/3178
    • Bump actions/setup-go from 3.3.0 to 3.3.1 by @dependabot in https://github.com/goadesign/goa/pull/3179
    • Bump golang.org/x/tools from 0.1.12 to 0.2.0 by @dependabot in https://github.com/goadesign/goa/pull/3180
    • Fix generate code for exclusive min and max by @raphael in https://github.com/goadesign/goa/pull/3184

    Full Changelog: https://github.com/goadesign/goa/compare/v3.10.1...v3.10.2

    Source code(tar.gz)
    Source code(zip)
  • v3.10.1(Oct 30, 2022)

    What's Changed

    • Make Goa proto wrapper field optional for arrays by @raphael in https://github.com/goadesign/goa/pull/3167

    Full Changelog: https://github.com/goadesign/goa/compare/v3.10.0...v3.10.1

    Source code(tar.gz)
    Source code(zip)
  • v3.10.0(Oct 11, 2022)

    What's Changed

    • X-Ray segment Namespace omitempty by @dvictor in https://github.com/goadesign/goa/pull/3161
    • Use proto optional fields for non required primitive object attributes. by @raphael in https://github.com/goadesign/goa/pull/3162
    • Bump github.com/getkin/kin-openapi from 0.103.0 to 0.104.0 by @dependabot in https://github.com/goadesign/goa/pull/3163
    • Fix issue with union validations by @raphael in https://github.com/goadesign/goa/pull/3164

    Full Changelog: https://github.com/goadesign/goa/compare/v3.9.1...v3.10.0

    Source code(tar.gz)
    Source code(zip)
Owner
Goa
The design-based microservice framework
Goa
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

null 0 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 Microservices MonoRepo in GO/Python Create a new production-ready project with backend (Golang), (Python) by running one CLI command. Focus on

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

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

Hao-Ming, Hsu 1 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,

ZYallers 1 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

Mario Carrion 576 Nov 22, 2022
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

Google Cloud Platform 13.3k Nov 29, 2022
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

Oguzhan 147 Nov 16, 2022
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

Bit Project 5 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

null 0 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.

Nicklas Frahm 0 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

Baalaji 0 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.

Madeira Madeira 11 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

Go kit 24.2k Nov 27, 2022
Zeebe.io - Workflow Engine for Microservices Orchestration

Distributed Workflow Engine for Microservices Orchestration

null 2.6k Nov 23, 2022
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.

null 30 Sep 24, 2022
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

null 290 Nov 18, 2022
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

null 1 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.

smallnest 7.3k Nov 28, 2022
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

Artem 0 Nov 8, 2021