From a755e8c78b27448e59101ffc58e04c7eb4c0b110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Mate=CC=8Cjka?= Date: Mon, 28 Feb 2022 17:22:54 +0100 Subject: [PATCH] Improvements after review --- Dockerfile-api | 4 +- Makefile | 6 -- api/openapi.json | 1 - api/openapi3.json | 1 - .../templates.go => api/templates/design.go | 31 +++++++-- api/templates/gen/openapi.json | 1 + api/{ => templates/gen}/openapi.yaml | 47 +++++++------ api/templates/gen/openapi3.json | 1 + api/{ => templates/gen}/openapi3.yaml | 46 ++++++++----- cmd/templates/http.go | 2 +- cmd/templates/main.go | 2 +- docs/DEVELOPMENT.md | 4 +- .../http/templates/server/encode_decode.go | 2 +- .../api/gen/http/templates/server/paths.go | 11 ++- .../api/gen/http/templates/server/server.go | 69 ++++++++++++------- .../api/gen/http/templates/server/types.go | 12 ++-- .../pkg/template/api/gen/templates/client.go | 12 +++- .../template/api/gen/templates/endpoints.go | 13 +++- .../pkg/template/api/gen/templates/service.go | 25 ++++--- .../template/api/gen/templates/views/view.go | 13 +++- internal/pkg/template/api/templates.go | 13 ++-- scripts/generate-api.sh | 17 +++++ scripts/tools.sh | 1 + 23 files changed, 222 insertions(+), 112 deletions(-) delete mode 100644 api/openapi.json delete mode 100644 api/openapi3.json rename design/templates.go => api/templates/design.go (51%) create mode 100644 api/templates/gen/openapi.json rename api/{ => templates/gen}/openapi.yaml (66%) create mode 100644 api/templates/gen/openapi3.json rename api/{ => templates/gen}/openapi3.yaml (55%) create mode 100644 scripts/generate-api.sh diff --git a/Dockerfile-api b/Dockerfile-api index b46b7634e5..d5249754ab 100644 --- a/Dockerfile-api +++ b/Dockerfile-api @@ -8,10 +8,10 @@ RUN GOOS=linux GOARCH=amd64 go build -v -mod mod -ldflags "-s -w" -o ./templates FROM scratch WORKDIR /app -COPY --from=buildContainer /go/src/app/templatesapi . +COPY --from=buildContainer /go/src/app/templatesapi /app/templatesapi ENV HOST 0.0.0.0 ENV PORT 8000 EXPOSE 8000 -CMD ["./templatesapi", "--http-port=8000", "--domain=0.0.0.0:8000"] +CMD ["/app/templatesapi", "--http-port=8000", "--domain=0.0.0.0:8000"] diff --git a/Makefile b/Makefile index fb60f894fa..044257a00e 100644 --- a/Makefile +++ b/Makefile @@ -36,9 +36,3 @@ fix: bash ./scripts/fix.sh ci: mod lint tests - -api-generate: - goa gen github.com/keboola/keboola-as-code/design --output ./internal/pkg/template/api - rm -rf ./internal/pkg/template/api/gen/http/cli - rm -rf ./internal/pkg/template/api/gen/http/templates/client - mv ./internal/pkg/template/api/gen/http/openapi* ./api diff --git a/api/openapi.json b/api/openapi.json deleted file mode 100644 index c28292378a..0000000000 --- a/api/openapi.json +++ /dev/null @@ -1 +0,0 @@ -{"swagger":"2.0","info":{"title":"Templates Service","description":"A service for applying templates to Keboola projects","version":""},"host":"localhost:8000","consumes":["application/json","application/xml","application/gob"],"produces":["application/json","application/xml","application/gob"],"paths":{"/":{"get":{"tags":["templates"],"summary":"index templates","operationId":"templates#index","responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/TemplatesIndexResponseBody"}}},"schemes":["http"]}},"/health-check":{"get":{"tags":["templates"],"summary":"health-check templates","operationId":"templates#health-check","responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/openapi.json":{"get":{"tags":["templates"],"summary":"Download ./gen/http/openapi.json","operationId":"templates#/openapi.json","responses":{"200":{"description":"File downloaded","schema":{"type":"file"}}},"schemes":["http"]}}},"definitions":{"TemplatesIndexResponseBody":{"title":"Mediatype identifier: application/vnd.templates.index; view=default","type":"object","properties":{"api":{"type":"string","example":"Fugit numquam quidem."},"documentation":{"type":"string","example":"Accusantium voluptas."}},"description":"IndexResponseBody result type (default view)","example":{"api":"Consequatur qui est ipsam provident omnis corporis.","documentation":"Incidunt voluptas deserunt rem sapiente."}}}} \ No newline at end of file diff --git a/api/openapi3.json b/api/openapi3.json deleted file mode 100644 index f72830913f..0000000000 --- a/api/openapi3.json +++ /dev/null @@ -1 +0,0 @@ -{"openapi":"3.0.3","info":{"title":"Templates Service","description":"A service for applying templates to Keboola projects","version":"1.0"},"servers":[{"url":"http://localhost:8000"}],"paths":{"/":{"get":{"tags":["templates"],"summary":"index templates","operationId":"templates#index","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Index"},"example":{"api":"Corrupti nisi cumque.","documentation":"Est aliquid nihil praesentium similique autem."}}}}}}},"/health-check":{"get":{"tags":["templates"],"summary":"health-check templates","operationId":"templates#health-check","responses":{"200":{"description":"OK response."}}}},"/openapi.json":{"get":{"tags":["templates"],"summary":"Download ./gen/http/openapi.json","operationId":"templates#/openapi.json","responses":{"200":{"description":"File downloaded"}}}}},"components":{"schemas":{"Index":{"type":"object","properties":{"api":{"type":"string","example":"Exercitationem assumenda quo quidem sapiente harum consequuntur."},"documentation":{"type":"string","example":"Sed dolores sunt dolorem."}},"example":{"api":"Quas voluptatum.","documentation":"Eius adipisci possimus dicta."}}}},"tags":[{"name":"templates","description":"Service for applying templates to Keboola projects"}]} \ No newline at end of file diff --git a/design/templates.go b/api/templates/design.go similarity index 51% rename from design/templates.go rename to api/templates/design.go index 1dcd0de34f..40d9b96e8a 100644 --- a/design/templates.go +++ b/api/templates/design.go @@ -1,5 +1,5 @@ // nolint: gochecknoglobals -package design +package templates import ( _ "goa.design/goa/v3/codegen/generator" @@ -9,9 +9,17 @@ import ( var _ = API("templates", func() { Title("Templates Service") Description("A service for applying templates to Keboola projects") + Version("1.0") + HTTP(func() { + Path("v1") + }) Server("templates", func() { - Host("localhost", func() { - URI("http://localhost:8000") + Host("production", func() { + URI("https://templates.{stack}") + Variable("stack", String, "Base URL of the stack", func() { + Default("keboola.com") + Enum("keboola.com", "eu-central-1.keboola.com", "north-europe.azure.keboola.com") + }) }) }) }) @@ -21,14 +29,27 @@ var index = ResultType("application/vnd.templates.index", func() { TypeName("Index") Attributes(func() { - Field(1, "api") - Field(2, "documentation") + Field(1, "api", String, "Name of the API", func() { + Example("templates") + }) + Field(2, "documentation", String, "Url of the API documentation", func() { + Example("https://templates.keboola.com/v1/documentation") + }) + Required("api", "documentation") }) }) var _ = Service("templates", func() { Description("Service for applying templates to Keboola projects") + Method("index-root", func() { + HTTP(func() { + // Redirect / -> /v1 + GET("//") + Redirect("/v1", StatusMovedPermanently) + }) + }) + Method("index", func() { Result(index) HTTP(func() { diff --git a/api/templates/gen/openapi.json b/api/templates/gen/openapi.json new file mode 100644 index 0000000000..aaafc66058 --- /dev/null +++ b/api/templates/gen/openapi.json @@ -0,0 +1 @@ +{"swagger":"2.0","info":{"title":"Templates Service","description":"A service for applying templates to Keboola projects","version":"1.0"},"host":"templates.keboola.com","consumes":["application/json","application/xml","application/gob"],"produces":["application/json","application/xml","application/gob"],"paths":{"/":{"get":{"tags":["templates"],"summary":"index-root templates","operationId":"templates#index-root","responses":{"307":{"description":"Temporary Redirect response."}},"schemes":["https"]}},"/v1":{"get":{"tags":["templates"],"summary":"index templates","operationId":"templates#index","responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/TemplatesIndexResponseBody"}}},"schemes":["https"]}},"/v1/health-check":{"get":{"tags":["templates"],"summary":"health-check templates","operationId":"templates#health-check","responses":{"200":{"description":"OK response."}},"schemes":["https"]}}},"definitions":{"TemplatesIndexResponseBody":{"title":"Mediatype identifier: application/vnd.templates.index; view=default","type":"object","properties":{"api":{"type":"string","description":"Name of the API","example":"templates"},"documentation":{"type":"string","description":"Url of the API documentation","example":"https://templates.keboola.com/v1/documentation"}},"description":"IndexResponseBody result type (default view)","example":{"api":"templates","documentation":"https://templates.keboola.com/v1/documentation"},"required":["api","documentation"]}}} \ No newline at end of file diff --git a/api/openapi.yaml b/api/templates/gen/openapi.yaml similarity index 66% rename from api/openapi.yaml rename to api/templates/gen/openapi.yaml index 7ab751261c..d90a11c0a1 100644 --- a/api/openapi.yaml +++ b/api/templates/gen/openapi.yaml @@ -2,8 +2,8 @@ swagger: "2.0" info: title: Templates Service description: A service for applying templates to Keboola projects - version: "" -host: localhost:8000 + version: "1.0" +host: templates.keboola.com consumes: - application/json - application/xml @@ -14,6 +14,17 @@ produces: - application/gob paths: /: + get: + tags: + - templates + summary: index-root templates + operationId: templates#index-root + responses: + "307": + description: Temporary Redirect response. + schemes: + - https + /v1: get: tags: - templates @@ -25,8 +36,8 @@ paths: schema: $ref: '#/definitions/TemplatesIndexResponseBody' schemes: - - http - /health-check: + - https + /v1/health-check: get: tags: - templates @@ -36,20 +47,7 @@ paths: "200": description: OK response. schemes: - - http - /openapi.json: - get: - tags: - - templates - summary: Download ./gen/http/openapi.json - operationId: templates#/openapi.json - responses: - "200": - description: File downloaded - schema: - type: file - schemes: - - http + - https definitions: TemplatesIndexResponseBody: title: 'Mediatype identifier: application/vnd.templates.index; view=default' @@ -57,11 +55,16 @@ definitions: properties: api: type: string - example: Fugit numquam quidem. + description: Name of the API + example: templates documentation: type: string - example: Accusantium voluptas. + description: Url of the API documentation + example: https://templates.keboola.com/v1/documentation description: IndexResponseBody result type (default view) example: - api: Consequatur qui est ipsam provident omnis corporis. - documentation: Incidunt voluptas deserunt rem sapiente. + api: templates + documentation: https://templates.keboola.com/v1/documentation + required: + - api + - documentation diff --git a/api/templates/gen/openapi3.json b/api/templates/gen/openapi3.json new file mode 100644 index 0000000000..048abfd7d0 --- /dev/null +++ b/api/templates/gen/openapi3.json @@ -0,0 +1 @@ +{"openapi":"3.0.3","info":{"title":"Templates Service","description":"A service for applying templates to Keboola projects","version":"1.0"},"servers":[{"url":"https://templates.{stack}","variables":{"stack":{"enum":["keboola.com","eu-central-1.keboola.com","north-europe.azure.keboola.com"],"default":"keboola.com"}}}],"paths":{"/":{"get":{"tags":["templates"],"summary":"index-root templates","operationId":"templates#index-root","responses":{"307":{"description":"Temporary Redirect response."}}}},"/v1":{"get":{"tags":["templates"],"summary":"index templates","operationId":"templates#index","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Index"},"example":{"api":"templates","documentation":"https://templates.keboola.com/v1/documentation"}}}}}}},"/v1/health-check":{"get":{"tags":["templates"],"summary":"health-check templates","operationId":"templates#health-check","responses":{"200":{"description":"OK response."}}}}},"components":{"schemas":{"Index":{"type":"object","properties":{"api":{"type":"string","description":"Name of the API","example":"templates"},"documentation":{"type":"string","description":"Url of the API documentation","example":"https://templates.keboola.com/v1/documentation"}},"example":{"api":"templates","documentation":"https://templates.keboola.com/v1/documentation"},"required":["api","documentation"]}}},"tags":[{"name":"templates","description":"Service for applying templates to Keboola projects"}]} \ No newline at end of file diff --git a/api/openapi3.yaml b/api/templates/gen/openapi3.yaml similarity index 55% rename from api/openapi3.yaml rename to api/templates/gen/openapi3.yaml index 5d73e0be11..1a7430cb56 100644 --- a/api/openapi3.yaml +++ b/api/templates/gen/openapi3.yaml @@ -4,9 +4,25 @@ info: description: A service for applying templates to Keboola projects version: "1.0" servers: -- url: http://localhost:8000 +- url: https://templates.{stack} + variables: + stack: + enum: + - keboola.com + - eu-central-1.keboola.com + - north-europe.azure.keboola.com + default: keboola.com paths: /: + get: + tags: + - templates + summary: index-root templates + operationId: templates#index-root + responses: + "307": + description: Temporary Redirect response. + /v1: get: tags: - templates @@ -20,9 +36,9 @@ paths: schema: $ref: '#/components/schemas/Index' example: - api: Corrupti nisi cumque. - documentation: Est aliquid nihil praesentium similique autem. - /health-check: + api: templates + documentation: https://templates.keboola.com/v1/documentation + /v1/health-check: get: tags: - templates @@ -31,15 +47,6 @@ paths: responses: "200": description: OK response. - /openapi.json: - get: - tags: - - templates - summary: Download ./gen/http/openapi.json - operationId: templates#/openapi.json - responses: - "200": - description: File downloaded components: schemas: Index: @@ -47,13 +54,18 @@ components: properties: api: type: string - example: Exercitationem assumenda quo quidem sapiente harum consequuntur. + description: Name of the API + example: templates documentation: type: string - example: Sed dolores sunt dolorem. + description: Url of the API documentation + example: https://templates.keboola.com/v1/documentation example: - api: Quas voluptatum. - documentation: Eius adipisci possimus dicta. + api: templates + documentation: https://templates.keboola.com/v1/documentation + required: + - api + - documentation tags: - name: templates description: Service for applying templates to Keboola projects diff --git a/cmd/templates/http.go b/cmd/templates/http.go index 3bc88f1aff..442eeca540 100644 --- a/cmd/templates/http.go +++ b/cmd/templates/http.go @@ -53,7 +53,7 @@ func handleHTTPServer(ctx context.Context, u *url.URL, templatesEndpoints *templ ) { eh := errorHandler(logger) - templatesServer = templatesSvr.New(templatesEndpoints, mux, dec, enc, eh, nil, nil) + templatesServer = templatesSvr.New(templatesEndpoints, mux, dec, enc, eh, nil) if debug { servers := goaHTTP.Servers{ templatesServer, diff --git a/cmd/templates/main.go b/cmd/templates/main.go index b9472880ad..a7a5c6beb3 100644 --- a/cmd/templates/main.go +++ b/cmd/templates/main.go @@ -72,7 +72,7 @@ func main() { switch *hostF { case "localhost": { - addr := "http://localhost:80" + addr := "http://localhost:8000" u, err := url.Parse(addr) if err != nil { fmt.Fprintf(os.Stderr, "invalid URL %#v: %s\n", addr, err) diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index f8772452b4..c9c705189b 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -69,8 +69,8 @@ API development uses [Goa code generator](https://goa.design/). When you add REST endpoints or change their behavior: -1. Change the API design first in the [design folder](../design) -2. Generate the code by running `make api-generate` +1. Change the API design first in the [api/templates/design.go](../api/templates/design.go) +2. Generate the code by running `bash scripts/generate-api.sh` 3. Implement the interfaces generated to [internal/pkg/template/api/gen/templates/service.go](../internal/pkg/template/api/gen/templates/service.go) (The service implementation is then referenced from the [cmd/templates/main.go](../cmd/templates/main.go)) To run the API locally run `docker-compose run --service-ports api`. The API is exposed to http://localhost:8000/ diff --git a/internal/pkg/template/api/gen/http/templates/server/encode_decode.go b/internal/pkg/template/api/gen/http/templates/server/encode_decode.go index 7b5b950a39..dd0a1c8f27 100644 --- a/internal/pkg/template/api/gen/http/templates/server/encode_decode.go +++ b/internal/pkg/template/api/gen/http/templates/server/encode_decode.go @@ -3,7 +3,7 @@ // templates HTTP server encoders and decoders // // Command: -// $ goa gen github.com/keboola/keboola-as-code/design --output +// $ goa gen github.com/keboola/keboola-as-code/api/templates --output // ./internal/pkg/template/api package server diff --git a/internal/pkg/template/api/gen/http/templates/server/paths.go b/internal/pkg/template/api/gen/http/templates/server/paths.go index 77cde5d2a5..a37b100887 100644 --- a/internal/pkg/template/api/gen/http/templates/server/paths.go +++ b/internal/pkg/template/api/gen/http/templates/server/paths.go @@ -3,17 +3,22 @@ // HTTP request path constructors for the templates service. // // Command: -// $ goa gen github.com/keboola/keboola-as-code/design --output +// $ goa gen github.com/keboola/keboola-as-code/api/templates --output // ./internal/pkg/template/api package server +// IndexRootTemplatesPath returns the URL path to the templates service index-root HTTP endpoint. +func IndexRootTemplatesPath() string { + return "/" +} + // IndexEndpointTemplatesPath returns the URL path to the templates service index HTTP endpoint. func IndexEndpointTemplatesPath() string { - return "/" + return "/v1" } // HealthCheckTemplatesPath returns the URL path to the templates service health-check HTTP endpoint. func HealthCheckTemplatesPath() string { - return "/health-check" + return "/v1/health-check" } diff --git a/internal/pkg/template/api/gen/http/templates/server/server.go b/internal/pkg/template/api/gen/http/templates/server/server.go index 3fa1c700dd..fb7422c8d0 100644 --- a/internal/pkg/template/api/gen/http/templates/server/server.go +++ b/internal/pkg/template/api/gen/http/templates/server/server.go @@ -3,7 +3,7 @@ // templates HTTP server // // Command: -// $ goa gen github.com/keboola/keboola-as-code/design --output +// $ goa gen github.com/keboola/keboola-as-code/api/templates --output // ./internal/pkg/template/api package server @@ -19,10 +19,10 @@ import ( // Server lists the templates service endpoint HTTP handlers. type Server struct { - Mounts []*MountPoint - IndexEndpoint http.Handler - HealthCheck http.Handler - GenHTTPOpenapiJSON http.Handler + Mounts []*MountPoint + IndexRoot http.Handler + IndexEndpoint http.Handler + HealthCheck http.Handler } // ErrorNamer is an interface implemented by generated error structs that @@ -55,20 +55,16 @@ func New( encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, errhandler func(context.Context, http.ResponseWriter, error), formatter func(err error) goahttp.Statuser, - fileSystemGenHTTPOpenapiJSON http.FileSystem, ) *Server { - if fileSystemGenHTTPOpenapiJSON == nil { - fileSystemGenHTTPOpenapiJSON = http.Dir(".") - } return &Server{ Mounts: []*MountPoint{ - {"IndexEndpoint", "GET", "/"}, - {"HealthCheck", "GET", "/health-check"}, - {"./gen/http/openapi.json", "GET", "/openapi.json"}, + {"IndexRoot", "GET", "/"}, + {"IndexEndpoint", "GET", "/v1"}, + {"HealthCheck", "GET", "/v1/health-check"}, }, - IndexEndpoint: NewIndexEndpointHandler(e.IndexEndpoint, mux, decoder, encoder, errhandler, formatter), - HealthCheck: NewHealthCheckHandler(e.HealthCheck, mux, decoder, encoder, errhandler, formatter), - GenHTTPOpenapiJSON: http.FileServer(fileSystemGenHTTPOpenapiJSON), + IndexRoot: NewIndexRootHandler(e.IndexRoot, mux, decoder, encoder, errhandler, formatter), + IndexEndpoint: NewIndexEndpointHandler(e.IndexEndpoint, mux, decoder, encoder, errhandler, formatter), + HealthCheck: NewHealthCheckHandler(e.HealthCheck, mux, decoder, encoder, errhandler, formatter), } } @@ -77,15 +73,16 @@ func (s *Server) Service() string { return "templates" } // Use wraps the server handlers with the given middleware. func (s *Server) Use(m func(http.Handler) http.Handler) { + s.IndexRoot = m(s.IndexRoot) s.IndexEndpoint = m(s.IndexEndpoint) s.HealthCheck = m(s.HealthCheck) } // Mount configures the mux to serve the templates endpoints. func Mount(mux goahttp.Muxer, h *Server) { + MountIndexRootHandler(mux, h.IndexRoot) MountIndexEndpointHandler(mux, h.IndexEndpoint) MountHealthCheckHandler(mux, h.HealthCheck) - MountGenHTTPOpenapiJSON(mux, goahttp.Replace("", "/./gen/http/openapi.json", h.GenHTTPOpenapiJSON)) } // Mount configures the mux to serve the templates endpoints. @@ -93,6 +90,36 @@ func (s *Server) Mount(mux goahttp.Muxer) { Mount(mux, s) } +// MountIndexRootHandler configures the mux to serve the "templates" service +// "index-root" endpoint. +func MountIndexRootHandler(mux goahttp.Muxer, h http.Handler) { + f, ok := h.(http.HandlerFunc) + if !ok { + f = func(w http.ResponseWriter, r *http.Request) { + h.ServeHTTP(w, r) + } + } + mux.Handle("GET", "/", f) +} + +// NewIndexRootHandler creates a HTTP handler which loads the HTTP request and +// calls the "templates" service "index-root" endpoint. +func NewIndexRootHandler( + endpoint goa.Endpoint, + mux goahttp.Muxer, + decoder func(*http.Request) goahttp.Decoder, + encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, + errhandler func(context.Context, http.ResponseWriter, error), + formatter func(err error) goahttp.Statuser, +) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept")) + ctx = context.WithValue(ctx, goa.MethodKey, "index-root") + ctx = context.WithValue(ctx, goa.ServiceKey, "templates") + http.Redirect(w, r, "/v1", http.StatusTemporaryRedirect) + }) +} + // MountIndexEndpointHandler configures the mux to serve the "templates" // service "index" endpoint. func MountIndexEndpointHandler(mux goahttp.Muxer, h http.Handler) { @@ -102,7 +129,7 @@ func MountIndexEndpointHandler(mux goahttp.Muxer, h http.Handler) { h.ServeHTTP(w, r) } } - mux.Handle("GET", "/", f) + mux.Handle("GET", "/v1", f) } // NewIndexEndpointHandler creates a HTTP handler which loads the HTTP request @@ -146,7 +173,7 @@ func MountHealthCheckHandler(mux goahttp.Muxer, h http.Handler) { h.ServeHTTP(w, r) } } - mux.Handle("GET", "/health-check", f) + mux.Handle("GET", "/v1/health-check", f) } // NewHealthCheckHandler creates a HTTP handler which loads the HTTP request @@ -180,9 +207,3 @@ func NewHealthCheckHandler( } }) } - -// MountGenHTTPOpenapiJSON configures the mux to serve GET request made to -// "/openapi.json". -func MountGenHTTPOpenapiJSON(mux goahttp.Muxer, h http.Handler) { - mux.Handle("GET", "/openapi.json", h.ServeHTTP) -} diff --git a/internal/pkg/template/api/gen/http/templates/server/types.go b/internal/pkg/template/api/gen/http/templates/server/types.go index 1efee38177..fc60a8ee69 100644 --- a/internal/pkg/template/api/gen/http/templates/server/types.go +++ b/internal/pkg/template/api/gen/http/templates/server/types.go @@ -3,7 +3,7 @@ // templates HTTP server types // // Command: -// $ goa gen github.com/keboola/keboola-as-code/design --output +// $ goa gen github.com/keboola/keboola-as-code/api/templates --output // ./internal/pkg/template/api package server @@ -15,16 +15,18 @@ import ( // IndexResponseBody is the type of the "templates" service "index" endpoint // HTTP response body. type IndexResponseBody struct { - API *string `form:"api,omitempty" json:"api,omitempty" xml:"api,omitempty"` - Documentation *string `form:"documentation,omitempty" json:"documentation,omitempty" xml:"documentation,omitempty"` + // Name of the API + API string `form:"api" json:"api" xml:"api"` + // Url of the API documentation + Documentation string `form:"documentation" json:"documentation" xml:"documentation"` } // NewIndexResponseBody builds the HTTP response body from the result of the // "index" endpoint of the "templates" service. func NewIndexResponseBody(res *templatesviews.IndexView) *IndexResponseBody { body := &IndexResponseBody{ - API: res.API, - Documentation: res.Documentation, + API: *res.API, + Documentation: *res.Documentation, } return body } diff --git a/internal/pkg/template/api/gen/templates/client.go b/internal/pkg/template/api/gen/templates/client.go index 42692ca637..a6efc77b0c 100644 --- a/internal/pkg/template/api/gen/templates/client.go +++ b/internal/pkg/template/api/gen/templates/client.go @@ -3,7 +3,7 @@ // templates client // // Command: -// $ goa gen github.com/keboola/keboola-as-code/design --output +// $ goa gen github.com/keboola/keboola-as-code/api/templates --output // ./internal/pkg/template/api package templates @@ -16,18 +16,26 @@ import ( // Client is the "templates" service client. type Client struct { + IndexRootEndpoint goa.Endpoint IndexEndpointEndpoint goa.Endpoint HealthCheckEndpoint goa.Endpoint } // NewClient initializes a "templates" service client given the endpoints. -func NewClient(indexEndpoint, healthCheck goa.Endpoint) *Client { +func NewClient(indexRoot, indexEndpoint, healthCheck goa.Endpoint) *Client { return &Client{ + IndexRootEndpoint: indexRoot, IndexEndpointEndpoint: indexEndpoint, HealthCheckEndpoint: healthCheck, } } +// IndexRoot calls the "index-root" endpoint of the "templates" service. +func (c *Client) IndexRoot(ctx context.Context) (err error) { + _, err = c.IndexRootEndpoint(ctx, nil) + return +} + // IndexEndpoint calls the "index" endpoint of the "templates" service. func (c *Client) IndexEndpoint(ctx context.Context) (res *Index, err error) { var ires interface{} diff --git a/internal/pkg/template/api/gen/templates/endpoints.go b/internal/pkg/template/api/gen/templates/endpoints.go index 81fc04316b..a947defbb1 100644 --- a/internal/pkg/template/api/gen/templates/endpoints.go +++ b/internal/pkg/template/api/gen/templates/endpoints.go @@ -3,7 +3,7 @@ // templates endpoints // // Command: -// $ goa gen github.com/keboola/keboola-as-code/design --output +// $ goa gen github.com/keboola/keboola-as-code/api/templates --output // ./internal/pkg/template/api package templates @@ -16,6 +16,7 @@ import ( // Endpoints wraps the "templates" service endpoints. type Endpoints struct { + IndexRoot goa.Endpoint IndexEndpoint goa.Endpoint HealthCheck goa.Endpoint } @@ -23,6 +24,7 @@ type Endpoints struct { // NewEndpoints wraps the methods of the "templates" service with endpoints. func NewEndpoints(s Service) *Endpoints { return &Endpoints{ + IndexRoot: NewIndexRootEndpoint(s), IndexEndpoint: NewIndexEndpointEndpoint(s), HealthCheck: NewHealthCheckEndpoint(s), } @@ -30,10 +32,19 @@ func NewEndpoints(s Service) *Endpoints { // Use applies the given middleware to all the "templates" service endpoints. func (e *Endpoints) Use(m func(goa.Endpoint) goa.Endpoint) { + e.IndexRoot = m(e.IndexRoot) e.IndexEndpoint = m(e.IndexEndpoint) e.HealthCheck = m(e.HealthCheck) } +// NewIndexRootEndpoint returns an endpoint function that calls the method +// "index-root" of service "templates". +func NewIndexRootEndpoint(s Service) goa.Endpoint { + return func(ctx context.Context, req interface{}) (interface{}, error) { + return nil, s.IndexRoot(ctx) + } +} + // NewIndexEndpointEndpoint returns an endpoint function that calls the method // "index" of service "templates". func NewIndexEndpointEndpoint(s Service) goa.Endpoint { diff --git a/internal/pkg/template/api/gen/templates/service.go b/internal/pkg/template/api/gen/templates/service.go index 4a9255fc8c..80ab957fbd 100644 --- a/internal/pkg/template/api/gen/templates/service.go +++ b/internal/pkg/template/api/gen/templates/service.go @@ -3,7 +3,7 @@ // templates service // // Command: -// $ goa gen github.com/keboola/keboola-as-code/design --output +// $ goa gen github.com/keboola/keboola-as-code/api/templates --output // ./internal/pkg/template/api package templates @@ -16,6 +16,8 @@ import ( // Service for applying templates to Keboola projects type Service interface { + // IndexRoot implements index-root. + IndexRoot(context.Context) (err error) // Index implements index. IndexEndpoint(context.Context) (res *Index, err error) // HealthCheck implements health-check. @@ -30,12 +32,14 @@ const ServiceName = "templates" // MethodNames lists the service method names as defined in the design. These // are the same values that are set in the endpoint request contexts under the // MethodKey key. -var MethodNames = [2]string{"index", "health-check"} +var MethodNames = [3]string{"index-root", "index", "health-check"} // Index is the result type of the templates service index method. type Index struct { - API *string - Documentation *string + // Name of the API + API string + // Url of the API documentation + Documentation string } // NewIndex initializes result type Index from viewed result type Index. @@ -52,9 +56,12 @@ func NewViewedIndex(res *Index, view string) *templatesviews.Index { // newIndex converts projected type Index to service type Index. func newIndex(vres *templatesviews.IndexView) *Index { - res := &Index{ - API: vres.API, - Documentation: vres.Documentation, + res := &Index{} + if vres.API != nil { + res.API = *vres.API + } + if vres.Documentation != nil { + res.Documentation = *vres.Documentation } return res } @@ -63,8 +70,8 @@ func newIndex(vres *templatesviews.IndexView) *Index { // the "default" view. func newIndexView(res *Index) *templatesviews.IndexView { vres := &templatesviews.IndexView{ - API: res.API, - Documentation: res.Documentation, + API: &res.API, + Documentation: &res.Documentation, } return vres } diff --git a/internal/pkg/template/api/gen/templates/views/view.go b/internal/pkg/template/api/gen/templates/views/view.go index 0a0a2bcd84..758724047d 100644 --- a/internal/pkg/template/api/gen/templates/views/view.go +++ b/internal/pkg/template/api/gen/templates/views/view.go @@ -3,7 +3,7 @@ // templates views // // Command: -// $ goa gen github.com/keboola/keboola-as-code/design --output +// $ goa gen github.com/keboola/keboola-as-code/api/templates --output // ./internal/pkg/template/api package views @@ -22,7 +22,9 @@ type Index struct { // IndexView is a type that runs validations on a projected type. type IndexView struct { - API *string + // Name of the API + API *string + // Url of the API documentation Documentation *string } @@ -50,6 +52,11 @@ func ValidateIndex(result *Index) (err error) { // ValidateIndexView runs the validations defined on IndexView using the // "default" view. func ValidateIndexView(result *IndexView) (err error) { - + if result.API == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("api", "result")) + } + if result.Documentation == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("documentation", "result")) + } return } diff --git a/internal/pkg/template/api/templates.go b/internal/pkg/template/api/templates.go index e1609bd216..342d8ab24a 100644 --- a/internal/pkg/template/api/templates.go +++ b/internal/pkg/template/api/templates.go @@ -15,18 +15,19 @@ func NewTemplates(logger *log.Logger) templates.Service { return &TemplatesService{logger} } +func (s *TemplatesService) IndexRoot(context.Context) (err error) { + // Redirect / -> /v1 + return nil +} + func (s *TemplatesService) IndexEndpoint(_ context.Context) (res *templates.Index, err error) { - apiName := "templates" - documentationUrl := "https://templates.keboola.com/documentation" res = &templates.Index{ - API: &apiName, - Documentation: &documentationUrl, + API: "templates", + Documentation: "https://templates.keboola.com/v1/documentation", } - s.logger.Print("templates.index") return res, nil } func (s *TemplatesService) HealthCheck(_ context.Context) (err error) { - s.logger.Print("templates.health-check") return } diff --git a/scripts/generate-api.sh b/scripts/generate-api.sh new file mode 100644 index 0000000000..1c52935065 --- /dev/null +++ b/scripts/generate-api.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -o errexit # Exit on most errors (see the manual) +set -o errtrace # Make sure any error trap is inherited +set -o nounset # Disallow expansion of unset variables +set -o pipefail # Use last non-zero exit code in a pipeline +#set -o xtrace # Trace the execution of the script (debug) + +# Change directory to the project root +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +cd "$SCRIPT_DIR/.." +pwd + +goa gen github.com/keboola/keboola-as-code/api/templates --output ./internal/pkg/template/api + rm -rf ./internal/pkg/template/api/gen/http/cli + rm -rf ./internal/pkg/template/api/gen/http/templates/client + mv ./internal/pkg/template/api/gen/http/openapi* ./api/templates/gen diff --git a/scripts/tools.sh b/scripts/tools.sh index d5189b3cc4..21dceea0e1 100755 --- a/scripts/tools.sh +++ b/scripts/tools.sh @@ -12,3 +12,4 @@ cd "$SCRIPT_DIR" ./install-gotestsum.sh -b $(go env GOPATH)/bin ./install-goreleaser.sh -b $(go env GOPATH)/bin v0.182.1 curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.42.1 +go install goa.design/goa/v3/cmd/goa@v3