{"id":13367396,"url":"https://github.com/raphael/Goa","last_synced_at":"2025-03-12T18:32:46.875Z","repository":{"id":57553098,"uuid":"224959424","full_name":"raphael/goa","owner":"raphael","description":"Design-based APIs and microservices in Go","archived":false,"fork":true,"pushed_at":"2023-09-29T08:10:39.000Z","size":43770,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"v3","last_synced_at":"2024-08-03T15:06:09.889Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://goa.design","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"goadesign/goa","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/raphael.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"security/scheme.go","support":null}},"created_at":"2019-11-30T04:30:27.000Z","updated_at":"2023-09-28T04:03:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/raphael/goa","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphael%2Fgoa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphael%2Fgoa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphael%2Fgoa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphael%2Fgoa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/raphael","download_url":"https://codeload.github.com/raphael/goa/tar.gz/refs/heads/v3","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221309978,"owners_count":16795837,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T00:01:46.966Z","updated_at":"2024-10-24T11:31:17.456Z","avatar_url":"https://github.com/raphael.png","language":"Go","funding_links":[],"categories":["Web 框架"],"sub_categories":["高级控制台界面","高級控制台界面"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cp align=\"center\"\u003e\n    \u003cimg alt=\"Goa\" src=\"https://goa.design/img/goa-banner.png\"\u003e\n  \u003c/p\u003e\n  \u003ch1 align=\"center\"\u003e\u003cb\u003eDesign First!\u003c/b\u003e\u003c/h1\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/goadesign/goa/releases/latest\"\u003e\u003cimg alt=\"Release\" src=\"https://img.shields.io/github/release/goadesign/goa.svg?style=for-the-badge\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://pkg.go.dev/goa.design/goa/v3@v3.13.1/dsl?tab=doc\"\u003e\u003cimg alt=\"Go Doc\" src=\"https://img.shields.io/badge/godoc-reference-blue.svg?style=for-the-badge\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/goadesign/goa/actions/workflows/ci.yml\"\u003e\u003cimg alt=\"GitHub Action: Build\" src=\"https://img.shields.io/github/actions/workflow/status/goadesign/goa/ci.yml?branch=v3\u0026style=for-the-badge\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://goreportcard.com/report/github.com/goadesign/goa\"\u003e\u003cimg alt=\"Go Report Card\" src=\"https://goreportcard.com/badge/github.com/goadesign/goa?style=for-the-badge\"\u003e\u003c/a\u003e\n    \u003ca href=\"/LICENSE\"\u003e\u003cimg alt=\"Software License\" src=\"https://img.shields.io/badge/license-MIT-brightgreen.svg?style=for-the-badge\"\u003e\u003c/a\u003e\n    \u003c/br\u003e\n    \u003ca href=\"https://gophers.slack.com/messages/goa\"\u003e\u003cimg alt=\"Slack: Goa\" src=\"https://img.shields.io/badge/Goa-gray.svg?longCache=true\u0026logo=slack\u0026colorB=red\u0026style=for-the-badge\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://invite.slack.golangbridge.org/\"\u003e\u003cimg alt=\"Slack: Sign-up\" src=\"https://img.shields.io/badge/Signup-gray.svg?longCache=true\u0026logo=slack\u0026colorB=red\u0026style=for-the-badge\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://twitter.com/goadesign\"\u003e\u003cimg alt=\"Twitter: @goadesign\" src=\"https://img.shields.io/badge/@goadesign-gray.svg?logo=twitter\u0026colorB=blue\u0026style=for-the-badge\"\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n# Overview\n\nGoa takes a different approach to building services by making it possible to\ndescribe the *design* of the service API using a simple Go DSL. Goa uses the\ndescription to generate specialized service helper code, client code and\ndocumentation. Goa is extensible via plugins, for example the\n[goakit](https://github.com/goadesign/plugins/tree/v3/goakit) plugin\ngenerates code that leverage the Go kit library.\n\nThe service design describes the transport independent layer of the services in\nthe form of simple methods that accept a context and a payload and return a\nresult and an error. The design also describes how the payloads, results and\nerrors are serialized in the transport (HTTP or gRPC). For example a service\nmethod payload may be built from an HTTP request by extracting values from the\nrequest path, headers and body. This clean separation of layers makes it\npossible to expose the same service using multiple transports. It also promotes\ngood design where the service business logic concerns are expressed and\nimplemented separately from the transport logic.\n\nThe Goa DSL consists of Go functions so that it may be extended easily to avoid\nrepetition and promote standards. The design code itself can easily be shared\nacross multiple services by simply importing the corresponding Go package again\npromoting reuse and standardization across services.\n\n# Sponsors\n\n\u003ctable width=\"100%\"\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\n            \u003cimg width=\"1000\" height=\"0\" /\u003e\n            \u003ca href=\"https://www.incident.io\"\u003e\n                \u003cimg src=\"https://incident.io/_next/static/media/logo-social-dark.6a523ace.png\" alt=\"incident.io\" width=\"260\" align=\"right\" /\u003e\n            \u003c/a\u003e\n            \u003ch3\u003eincident.io: Bounce back stronger after every incident\u003c/h3\u003e\n            \u003cp\u003e\n                Use our platform to empower your team to run incidents end-to-end. Rapidly fix and\n                learn from incidents, so you can build more resilient products.\n            \u003c/p\u003e\n\n[Learn more](https://incident.io/)\n        \u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\n# Code Generation\n\nThe Goa tool accepts the Go design package import path as input and produces the\ninterface as well as the glue that binds the service and client code with the\nunderlying transport. The code is specific to the API so that for example there\nis no need to cast or \"bind\" any data structure prior to using the request\npayload or response result. The design may define validations in which case the\ngenerated code takes care of validating the incoming request payload prior to\ninvoking the service method on the server, and validating the response prior to\ninvoking the client code.\n\n# Installation\n\n```bash\ngo install goa.design/goa/v3/cmd/goa@v3\n```\n\nCurrent Release: `v3.13.1`\n\n# Getting Started\n\n## 1. Design\n\nCreate a new Goa project:\n\n```bash\nmkdir -p calcsvc/design\ncd calcsvc\ngo mod init calcsvc\n```\n\nCreate the file `design.go` in the `design` directory with the following\ncontent:\n\n```go\npackage design\n\nimport . \"goa.design/goa/v3/dsl\"\n\n// API describes the global properties of the API server.\nvar _ = API(\"calc\", func() {\n        Title(\"Calculator Service\")\n        Description(\"HTTP service for multiplying numbers, a goa teaser\")\n        Server(\"calc\", func() {\n                Host(\"localhost\", func() { URI(\"http://localhost:8088\") })\n        })\n})\n\n// Service describes a service\nvar _ = Service(\"calc\", func() {\n        Description(\"The calc service performs operations on numbers\")\n        // Method describes a service method (endpoint)\n        Method(\"multiply\", func() {\n                // Payload describes the method payload\n                // Here the payload is an object that consists of two fields\n                Payload(func() {\n                        // Attribute describes an object field\n                        Attribute(\"a\", Int, \"Left operand\")\n                        Attribute(\"b\", Int, \"Right operand\")\n                        // Both attributes must be provided when invoking \"multiply\"\n                        Required(\"a\", \"b\")\n                })\n                // Result describes the method result\n                // Here the result is a simple integer value\n                Result(Int)\n                // HTTP describes the HTTP transport mapping\n                HTTP(func() {\n                        // Requests to the service consist of HTTP GET requests\n                        // The payload fields are encoded as path parameters\n                        GET(\"/multiply/{a}/{b}\")\n                        // Responses use a \"200 OK\" HTTP status\n                        // The result is encoded in the response body\n                        Response(StatusOK)\n                })\n        })\n})\n```\n\nThis file contains the design for a `calc` service which accepts HTTP GET\nrequests to `/multiply/{a}/{b}` where `{a}` and `{b}` are placeholders for integer\nvalues. The API returns the product of `a` multiplied by `b` in the HTTP response body.\n\n## 2. Implement\n\nNow that the design is done, let's run `goa` on the design package.\nIn the `calcsvc` directory run:\n\n``` bash\ngoa gen calcsvc/design\n```\n\nThis produces a `gen` directory with the following directory structure:\n\n``` text\ngen\n├── calc\n│   ├── client.go\n│   ├── endpoints.go\n│   └── service.go\n└── http\n    ├── calc\n    │   ├── client\n    │   │   ├── cli.go\n    │   │   ├── client.go\n    │   │   ├── encode_decode.go\n    │   │   ├── paths.go\n    │   │   └── types.go\n    │   └── server\n    │       ├── encode_decode.go\n    │       ├── paths.go\n    │       ├── server.go\n    │       └── types.go\n    ├── cli\n    │   └── calc\n    │       └── cli.go\n    ├── openapi.json\n    └── openapi.yaml\n\n7 directories, 15 files\n```\n\n* `calc` contains the service endpoints and interface as well as a service\n  client.\n* `http` contains the HTTP transport layer. This layer maps the service\n  endpoints to HTTP handlers server side and HTTP client methods client side.\n  The `http` directory also contains a complete\n  [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md)\n  spec for the service.\n\nThe `goa` tool can also generate example implementations for both the service\nand client. These examples provide a good starting point:\n\n``` text\ngoa example calcsvc/design\n\ncalc.go\ncmd/calc-cli/http.go\ncmd/calc-cli/main.go\ncmd/calc/http.go\ncmd/calc/main.go\n```\n\nThe tool generated the `main` functions for two commands: one that runs the\nserver and one the client. The tool also generated a dummy service\nimplementation that prints a log message. Again note that the `example` command\nis intended to generate just that: an *example*, in particular it is not\nintended to be re-run each time the design changes (as opposed to the `gen`\ncommand which should be re-run each time the design changes).\n\nLet's implement our service by providing a proper implementation for the `multiply`\nmethod. Goa generated a payload struct for the `multiply` method that contains both\nfields. Goa also generated the transport layer that takes care of decoding the\nrequest so all we have to do is to perform the actual multiplication. Edit the file\n`calc.go` and change the code of the `multiply` function as follows:\n\n```go\n// Multiply returns the multiplied value of attributes a and b of p.\nfunc (s *calcsrvc) Multiply(ctx context.Context, p *calc.MultiplyPayload) (res int, err error) {\n        return p.A * p.B, nil\n}\n```\n\nThat's it! we have now a full-fledged HTTP service with a corresponding OpenAPI\nspecification and a client tool.\n\n## 3. Run\n\nNow let's compile and run the service:\n\n```bash\ncd cmd/calc\ngo build\n./calc\n[calcapi] 16:10:47 HTTP \"Multiply\" mounted on GET /multiply/{a}/{b}\n[calcapi] 16:10:47 HTTP server listening on \"localhost:8088\"\n```\n\nOpen a new console and compile the generated CLI tool:\n\n```bash\ncd calcsvc/cmd/calc-cli\ngo build\n```\n\nand run it:\n\n```bash\n./calc-cli calc multiply -a 2 -b 3\n6\n```\n\nThe tool includes contextual help:\n\n``` bash\n./calc-cli --help\n```\n\nHelp is also available on each command:\n\n``` bash\n./calc-cli calc multiply --help\n```\n\nNow let's see how robust our code is and try to use non integer values:\n\n``` bash\n./calc-cli calc multiply -a 1 -b foo\ninvalid value for b, must be INT\nrun './calccli --help' for detailed usage.\n```\n\nThe generated code validates the command line arguments against the types\ndefined in the design. The server also validates the types when decoding\nincoming requests so that your code only has to deal with the business logic.\n\n## 4. Document\n\nThe `http` directory contains OpenAPI 2.0 and 3.0 specifications in both YAML\nand JSON format.\n\nThe specification can easily be served from the service itself using a file\nserver. The [Files](http://godoc.org/goa.design/goa/dsl/http.go#Files) DSL\nfunction makes it possible to serve a static file. Edit the file\n`design/design.go` and add:\n\n```go\nvar _ = Service(\"openapi\", func() {\n\t// Serve the file gen/http/openapi3.json for requests sent to\n\t// /openapi.json. The HTTP file system is created below.\n\tFiles(\"/openapi.json\", \"openapi3.json\")\n})\n```\n\nRe-run `goa gen calcsvc/design` and note the new directory `gen/openapi` and\n`gen/http/openapi` which contain the implementation for a HTTP handler that\nserves the `openapi.json` file.\n\nAll we need to do is mount the handler on the service mux. Add the corresponding\nimport statement to `cmd/calc/http.go`:\n\n```go\nimport openapisvr \"calcsvc/gen/http/openapi/server\"\n```\n\nand mount the handler by adding the following line in the same file and after\nthe mux creation (e.g. one the line after the `// Configure the mux.` comment):\n\n```go\nsvr := openapisvr.New(nil, mux, dec, enc, nil, nil, http.Dir(\"../../gen/http\"))\nopenapisvr.Mount(mux, svr)\n```\n\nThat's it! we now have a self-documenting service. Stop the running service\nwith CTRL-C. Rebuild and re-run it then make requests to the newly added\n`/openapi.json` endpoint:\n\n``` bash\n^C[calcapi] 16:17:37 exiting (interrupt)\n[calcapi] 16:17:37 shutting down HTTP server at \"localhost:8088\"\n[calcapi] 16:17:37 exited\ngo build\n./calc\n```\n\nIn a different console:\n\n``` bash\ncurl localhost:8088/openapi.json\n{\"openapi\":\"3.0.3\",\"info\":{\"title\":\"Calculator Service\",\"description\":...\n```\n\n# Resources\n\n## Docs\n\nThe [goa.design](https://goa.design) website provides a high level overview of\nGoa and the DSL.\n\nIn particular the page\n[Implementing a Goa Service](https://goa.design/implement/implementing/)\nexplains how to leverage the generated code to implement an HTTP or gRPC\nservice.\n\nThe [DSL Go Doc](https://pkg.go.dev/goa.design/goa/v3@v3.13.1/dsl?tab=doc)\ncontains a fully documented reference of all the DSL functions.\n\n## Instrumentation and System Example\n\nThe [clue](https://github.com/goadesign/clue) project provides observability\npackages that work in tandem with Goa. The packages cover\n[logging](https://github.com/goadesign/clue/tree/main/log),\n[tracing](https://github.com/goadesign/clue/tree/main/trace),\n[metrics](https://github.com/goadesign/clue/tree/main/metrics),\n[health checks](https://github.com/goadesign/clue/tree/main/health)\nand service client\n[mocking](https://github.com/goadesign/clue/tree/main/mock). clue also includes a fully featured\n[example](https://github.com/goadesign/clue/tree/main/example/weather)\nconsisting of three instrumented Goa microservices that communicate with each other.\n\n## Getting Started Guides\n\nA couple of Getting Started guides produced by the community.\n\nJoseph Ocol from Pelmorex Corp. goes through a complete example writing a server\nand client service using both HTTP and gRPC transports.\n\n[![GOA Design Tutorial](https://tech.pelmorex.com/wp-content/uploads/2020/07/GOA-Design-Tutorial-Screencap-800x470.png)](https://vimeo.com/437928805)\n\nGleidson Nascimento goes through how to create a complete service that using both\n[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) and\n[JWT](https://jwt.io/) based authentication to secure access.\n\n[![API Development in Go Using Goa](https://bs-uploads.toptal.io/blackfish-uploads/uploaded_file/file/275966/image-1592349920607-734c25f64461bf3c482bac1d73c26432.png)](https://www.toptal.com/go/goa-api-development)\n\n## Examples\n\nThe [examples](https://github.com/goadesign/examples) directory\ncontains simple examples illustrating basic concepts.\n\n## Troubleshooting\n\nQ: I'm seeing an error that says:\n\n\u003e generated code expected `goa.design/goa/v3/codegen/generator` to be present in the vendor directory, see documentation for more details\n\nHow do I fix this?\n\nA: If you are vendoring your dependencies Goa will not attempt to satisfy its\ndependencies by retrieving them with `go get`. If you see the above error message, it\nmeans that the `goa.design/goa/v3/codegen/generator` package is not included in your\nvendor directory.\n\nTo fix, ensure that `goa.design/goa/v3/codegen/generator` is being imported somewhere in your project. This can be as a bare import (e.g. `import _ \"goa.design/goa/v3/codegen/generator\"`)\nin any file or you can use a dedicated `tools.go` file (see [Manage Go tools via Go modules](https://marcofranssen.nl/manage-go-tools-via-go-modules) and [golang/go/issues/25922](https://github.com/golang/go/issues/25922) for more details.) Finally, run `go mod vendor` to ensure\nthe imported packages are properly vendored.\n\n# Contributing\n\nSee [CONTRIBUTING](https://github.com/goadesign/goa/blob/v3/CONTRIBUTING.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphael%2FGoa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraphael%2FGoa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphael%2FGoa/lists"}