// RequireHeader requires a request header to match a value pattern. If the // header is missing or does not match then the failureStatus is the response // (e.g. http.StatusUnauthorized). If pathPattern is nil then any path is // included. If requiredHeaderValue is nil then any value is accepted so long as // the header is non-empty. func RequireHeader( service *goa.Service, pathPattern *regexp.Regexp, requiredHeaderName string, requiredHeaderValue *regexp.Regexp, failureStatus int) goa.Middleware { return func(h goa.Handler) goa.Handler { return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) (err error) { if pathPattern == nil || pathPattern.MatchString(req.URL.Path) { matched := false headerValue := req.Header.Get(requiredHeaderName) if len(headerValue) > 0 { if requiredHeaderValue == nil { matched = true } else { matched = requiredHeaderValue.MatchString(headerValue) } } if matched { err = h(ctx, rw, req) } else { err = service.Send(ctx, failureStatus, http.StatusText(failureStatus)) } } else { err = h(ctx, rw, req) } return } } }
// MountAeController "mounts" a Ae resource controller on the given service. func MountAeController(service *goa.Service, ctrl AeController) { initService(service) var h goa.Handler h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { // Check if there was an error loading the request if err := goa.ContextError(ctx); err != nil { return err } // Build the context rctx, err := NewHealthAeContext(ctx, service) if err != nil { return err } return ctrl.Health(rctx) } service.Mux.Handle("GET", "/_ah/health", ctrl.MuxHandler("Health", h, nil)) service.LogInfo("mount", "ctrl", "Ae", "action", "Health", "route", "GET /_ah/health") h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { // Check if there was an error loading the request if err := goa.ContextError(ctx); err != nil { return err } // Build the context rctx, err := NewStartAeContext(ctx, service) if err != nil { return err } return ctrl.Start(rctx) } service.Mux.Handle("GET", "/_ah/start", ctrl.MuxHandler("Start", h, nil)) service.LogInfo("mount", "ctrl", "Ae", "action", "Start", "route", "GET /_ah/start") }
// ErrorHandler turns a Go error into an HTTP response. It should be placed in the middleware chain // below the logger middleware so the logger properly logs the HTTP response. ErrorHandler // understands instances of goa.Error and returns the status and response body embodied in them, // it turns other Go error types into a 500 internal error response. // If verbose is false the details of internal errors is not included in HTTP responses. func ErrorHandler(service *goa.Service, verbose bool) goa.Middleware { return func(h goa.Handler) goa.Handler { return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { e := h(ctx, rw, req) if e == nil { return nil } status := http.StatusInternalServerError var respBody interface{} if err, ok := e.(*goa.Error); ok { status = err.Status respBody = err goa.ContextResponse(ctx).ErrorCode = err.Code rw.Header().Set("Content-Type", goa.ErrorMediaIdentifier) } else { respBody = e.Error() rw.Header().Set("Content-Type", "text/plain") } if status >= 500 && status < 600 { reqID := ctx.Value(reqIDKey) if reqID == nil { reqID = shortID() ctx = context.WithValue(ctx, reqIDKey, reqID) } goa.LogError(ctx, "uncaught error", "id", reqID, "msg", respBody) if !verbose { rw.Header().Set("Content-Type", goa.ErrorMediaIdentifier) respBody = goa.ErrInternal("internal error [%s]", reqID) } } return service.Send(ctx, status, respBody) } } }
// NewWorkItemLinkController creates a work-item-link controller. func NewWorkItemLinkController(service *goa.Service, db application.DB) *WorkItemLinkController { if db == nil { panic("db must not be nil") } return &WorkItemLinkController{ Controller: service.NewController("WorkItemLinkController"), db: db, } }
// unmarshalCreateBottlePayload unmarshals the request body into the context request data Payload field. func unmarshalCreateBottlePayload(ctx context.Context, service *goa.Service, req *http.Request) error { payload := &createBottlePayload{} if err := service.DecodeRequest(req, payload); err != nil { return err } if err := payload.Validate(); err != nil { return err } goa.ContextRequest(ctx).Payload = payload.Publicize() return nil }
// StartAeOK runs the method Start of the given controller with the given parameters. // It returns the response writer so it's possible to inspect the response headers. // If ctx is nil then context.Background() is used. // If service is nil then a default service is created. func StartAeOK(t goatest.TInterface, ctx context.Context, service *goa.Service, ctrl app.AeController) http.ResponseWriter { // Setup service var ( logBuf bytes.Buffer resp interface{} respSetter goatest.ResponseSetterFunc = func(r interface{}) { resp = r } ) if service == nil { service = goatest.Service(&logBuf, respSetter) } else { logger := log.New(&logBuf, "", log.Ltime) service.WithLogger(goa.NewLogger(logger)) newEncoder := func(io.Writer) goa.Encoder { return respSetter } service.Encoder = goa.NewHTTPEncoder() // Make sure the code ends up using this decoder service.Encoder.Register(newEncoder, "*/*") } // Setup request context rw := httptest.NewRecorder() u := &url.URL{ Path: fmt.Sprintf("/_ah/start"), } req, err := http.NewRequest("GET", u.String(), nil) if err != nil { panic("invalid test " + err.Error()) // bug } prms := url.Values{} if ctx == nil { ctx = context.Background() } goaCtx := goa.NewContext(goa.WithAction(ctx, "AeTest"), rw, req, prms) startCtx, err := app.NewStartAeContext(goaCtx, service) if err != nil { panic("invalid test data " + err.Error()) // bug } // Perform action err = ctrl.Start(startCtx) // Validate response if err != nil { t.Fatalf("controller returned %s, logs:\n%s", err, logBuf.String()) } if rw.Code != 200 { t.Errorf("invalid response status code: got %+v, expected 200", rw.Code) } // Return results return rw }
// ErrorHandler turns a Go error into an JSONAPI HTTP response. It should be placed in the middleware chain // below the logger middleware so the logger properly logs the HTTP response. ErrorHandler // understands instances of goa.ServiceError and returns the status and response body embodied in // them, it turns other Go error types into a 500 internal error response. // If verbose is false the details of internal errors is not included in HTTP responses. // If you use github.com/pkg/errors then wrapping the error will allow a trace to be printed to the logs func ErrorHandler(service *goa.Service, verbose bool) goa.Middleware { return func(h goa.Handler) goa.Handler { return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { e := h(ctx, rw, req) if e == nil { return nil } cause := errs.Cause(e) status := http.StatusInternalServerError var respBody interface{} respBody, status = ErrorToJSONAPIErrors(e) rw.Header().Set("Content-Type", ErrorMediaIdentifier) if err, ok := cause.(goa.ServiceError); ok { status = err.ResponseStatus() //respBody = err goa.ContextResponse(ctx).ErrorCode = err.Token() //rw.Header().Set("Content-Type", ErrorMediaIdentifier) } else { //respBody = e.Error() //rw.Header().Set("Content-Type", "text/plain") } if status >= 500 && status < 600 { //reqID := ctx.Value(reqIDKey) reqID := ctx.Value(1) // TODO remove this hack if reqID == nil { reqID = shortID() //ctx = context.WithValue(ctx, reqIDKey, reqID) ctx = context.WithValue(ctx, 1, reqID) // TODO remove this hack } log.Error(ctx, map[string]interface{}{ "msg": respBody, "err": fmt.Sprintf("%+v", e), }, "uncaught error detected in ErrorHandler") if !verbose { rw.Header().Set("Content-Type", goa.ErrorMediaIdentifier) msg := errors.NewInternalError(fmt.Sprintf("%s [%s]", http.StatusText(http.StatusInternalServerError), reqID)) //respBody = goa.ErrInternal(msg) respBody, status = ErrorToJSONAPIErrors(msg) // Preserve the ID of the original error as that's what gets logged, the client // received error ID must match the original // TODO for JSONAPI this won't work I guess. if origErrID := goa.ContextResponse(ctx).ErrorCode; origErrID != "" { respBody.(*goa.ErrorResponse).ID = origErrID } } } return service.Send(ctx, status, respBody) } } }
// ErrorHandler turns a Go error into an HTTP response. It should be placed in the middleware chain // below the logger middleware so the logger properly logs the HTTP response. ErrorHandler // understands instances of goa.ServiceError and returns the status and response body embodied in // them, it turns other Go error types into a 500 internal error response. // If verbose is false the details of internal errors is not included in HTTP responses. // If you use github.com/pkg/errors then wrapping the error will allow a trace to be printed to the logs func ErrorHandler(service *goa.Service, verbose bool) goa.Middleware { return func(h goa.Handler) goa.Handler { return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { e := h(ctx, rw, req) if e == nil { return nil } cause := errors.Cause(e) status := http.StatusInternalServerError var respBody interface{} if err, ok := cause.(goa.ServiceError); ok { status = err.ResponseStatus() respBody = err goa.ContextResponse(ctx).ErrorCode = err.Token() rw.Header().Set("Content-Type", goa.ErrorMediaIdentifier) } else { respBody = e.Error() rw.Header().Set("Content-Type", "text/plain") } if status >= 500 && status < 600 { reqID := ctx.Value(reqIDKey) if reqID == nil { reqID = shortID() ctx = context.WithValue(ctx, reqIDKey, reqID) } goa.LogError(ctx, "uncaught error", "err", fmt.Sprintf("%+v", e), "id", reqID, "msg", respBody) if !verbose { rw.Header().Set("Content-Type", goa.ErrorMediaIdentifier) msg := fmt.Sprintf("%s [%s]", http.StatusText(http.StatusInternalServerError), reqID) respBody = goa.ErrInternal(msg) // Preserve the ID of the original error as that's what gets logged, the client // received error ID must match the original if origErrID := goa.ContextResponse(ctx).ErrorCode; origErrID != "" { respBody.(*goa.ErrorResponse).ID = origErrID } } } return service.Send(ctx, status, respBody) } } }
// MountSpecController "mounts" a Spec resource controller on the given service. func MountSpecController(service *goa.Service, ctrl SpecController) { initService(service) var h goa.Handler service.Mux.Handle("OPTIONS", "/swagger/spec", ctrl.MuxHandler("preflight", handleSpecOrigin(cors.HandlePreflight()), nil)) h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { // Check if there was an error loading the request if err := goa.ContextError(ctx); err != nil { return err } // Build the context rctx, err := NewShowSpecContext(ctx, service) if err != nil { return err } return ctrl.Show(rctx) } h = handleSpecOrigin(h) service.Mux.Handle("GET", "/swagger/spec", ctrl.MuxHandler("Show", h, nil)) service.LogInfo("mount", "ctrl", "Spec", "action", "Show", "route", "GET /swagger/spec") }
// MountBottleController "mounts" a Bottle resource controller on the given service. func MountBottleController(service *goa.Service, ctrl BottleController) { initService(service) var h goa.Handler h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { // Check if there was an error loading the request if err := goa.ContextError(ctx); err != nil { return err } // Build the context rctx, err := NewCreateBottleContext(ctx, service) if err != nil { return err } // Build the payload if rawPayload := goa.ContextRequest(ctx).Payload; rawPayload != nil { rctx.Payload = rawPayload.(*CreateBottlePayload) } else { return goa.MissingPayloadError() } return ctrl.Create(rctx) } service.Mux.Handle("POST", "/bottles", ctrl.MuxHandler("Create", h, unmarshalCreateBottlePayload)) service.LogInfo("mount", "ctrl", "Bottle", "action", "Create", "route", "POST /bottles") h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { // Check if there was an error loading the request if err := goa.ContextError(ctx); err != nil { return err } // Build the context rctx, err := NewShowBottleContext(ctx, service) if err != nil { return err } return ctrl.Show(rctx) } service.Mux.Handle("GET", "/bottles/:id", ctrl.MuxHandler("Show", h, nil)) service.LogInfo("mount", "ctrl", "Bottle", "action", "Show", "route", "GET /bottles/:id") }
// MountSwaggerController "mounts" a Swagger resource controller on the given service. func MountSwaggerController(service *goa.Service, ctrl SwaggerController) { initService(service) var h goa.Handler h = ctrl.FileHandler("/swagger-ui/*filepath", "swagger-ui/") service.Mux.Handle("GET", "/swagger-ui/*filepath", ctrl.MuxHandler("serve", h, nil)) service.LogInfo("mount", "ctrl", "Swagger", "files", "swagger-ui/", "route", "GET /swagger-ui/*filepath") h = ctrl.FileHandler("/swagger.json", "swagger/swagger.json") service.Mux.Handle("GET", "/swagger.json", ctrl.MuxHandler("serve", h, nil)) service.LogInfo("mount", "ctrl", "Swagger", "files", "swagger/swagger.json", "route", "GET /swagger.json") h = ctrl.FileHandler("/swagger-ui/", "swagger-ui/index.html") service.Mux.Handle("GET", "/swagger-ui/", ctrl.MuxHandler("serve", h, nil)) service.LogInfo("mount", "ctrl", "Swagger", "files", "swagger-ui/index.html", "route", "GET /swagger-ui/") }
// MountPreflightController mounts the handlers for the CORS preflight requests onto service. func MountPreflightController(service goa.Service, spec Specification) { for _, res := range spec { path := res.Path if res.IsPathPrefix { if strings.HasSuffix(path, "/") { path += "*cors" } else { path += "/*cors" } } handle := service.ServeMux().Lookup("OPTIONS", path) if handle == nil { h := func(ctx *goa.Context) error { return ctx.Respond(200, nil) } ctrl := service.NewController("cors") service.ServeMux().Handle("OPTIONS", path, ctrl.HandleFunc("preflight", h, nil)) } } }
// NewWorkItemCommentsController creates a work-item-relationships-comments controller. func NewWorkItemCommentsController(service *goa.Service, db application.DB) *WorkItemCommentsController { return &WorkItemCommentsController{Controller: service.NewController("WorkItemRelationshipsCommentsController"), db: db} }
// NewUsersController creates a users controller. func NewUsersController(service *goa.Service, db application.DB) *UsersController { return &UsersController{Controller: service.NewController("UsersController"), db: db} }
// NewTrackerqueryController creates a trackerquery controller. func NewTrackerqueryController(service *goa.Service, db application.DB, scheduler *remoteworkitem.Scheduler) *TrackerqueryController { return &TrackerqueryController{Controller: service.NewController("TrackerqueryController"), db: db, scheduler: scheduler} }
Describe("GetMany", func() { It("returns nil if not initialized", func() { Ω(ctx.GetMany("foo")).Should(BeNil()) }) }) Describe("RawPayload", func() { It("returns nil if not initialized", func() { Ω(ctx.RawPayload()).Should(BeNil()) }) }) Context("with a request response", func() { const appName = "foo" var app goa.Service const resName = "res" const actName = "act" var handler, unmarshaler goa.Handler const reqBody = `"body"` const respStatus = 200 var respContent = []byte("response") var handleFunc goa.HandleFunc var rw http.ResponseWriter var request *http.Request var params url.Values BeforeEach(func() { app = goa.New(appName) handler = func(c *goa.Context) error { ctx = c
// MountAccountController "mounts" a Account resource controller on the given service. func MountAccountController(service goa.Service, ctrl AccountController) { // Setup encoders and decoders. This is idempotent and is done by each MountXXX function. tmp15 := goa.GobEncoderFactory() service.SetEncoder(tmp15, false, "application/gob", "application/x-gob") tmp16 := goa.JSONEncoderFactory() service.SetEncoder(tmp16, true, "application/json") tmp17 := goa.XMLEncoderFactory() service.SetEncoder(tmp17, false, "application/xml", "text/xml") tmp18 := goa.GobDecoderFactory() service.SetDecoder(tmp18, false, "application/gob", "application/x-gob") tmp19 := goa.JSONDecoderFactory() service.SetDecoder(tmp19, true, "application/json") tmp20 := goa.XMLDecoderFactory() service.SetDecoder(tmp20, false, "application/xml", "text/xml") // Setup endpoint handler var h goa.Handler mux := service.ServeMux() h = func(c *goa.Context) error { ctx, err := NewCreateAccountContext(c) ctx.Payload = ctx.RawPayload().(*CreateAccountPayload) if err != nil { return goa.NewBadRequestError(err) } return ctrl.Create(ctx) } mux.Handle("POST", "/cellar/accounts", ctrl.HandleFunc("Create", h, unmarshalCreateAccountPayload)) service.Info("mount", "ctrl", "Account", "action", "Create", "route", "POST /cellar/accounts") h = func(c *goa.Context) error { ctx, err := NewDeleteAccountContext(c) if err != nil { return goa.NewBadRequestError(err) } return ctrl.Delete(ctx) } mux.Handle("DELETE", "/cellar/accounts/:accountID", ctrl.HandleFunc("Delete", h, nil)) service.Info("mount", "ctrl", "Account", "action", "Delete", "route", "DELETE /cellar/accounts/:accountID") h = func(c *goa.Context) error { ctx, err := NewShowAccountContext(c) if err != nil { return goa.NewBadRequestError(err) } return ctrl.Show(ctx) } mux.Handle("GET", "/cellar/accounts/:accountID", ctrl.HandleFunc("Show", h, nil)) service.Info("mount", "ctrl", "Account", "action", "Show", "route", "GET /cellar/accounts/:accountID") h = func(c *goa.Context) error { ctx, err := NewUpdateAccountContext(c) ctx.Payload = ctx.RawPayload().(*UpdateAccountPayload) if err != nil { return goa.NewBadRequestError(err) } return ctrl.Update(ctx) } mux.Handle("PUT", "/cellar/accounts/:accountID", ctrl.HandleFunc("Update", h, unmarshalUpdateAccountPayload)) service.Info("mount", "ctrl", "Account", "action", "Update", "route", "PUT /cellar/accounts/:accountID") }
It("wraps it in a middleware", func() { Ω(mErr).ShouldNot(HaveOccurred()) h := func(ctx *goa.Context) error { return nil } Ω(middleware(h)(ctx)).ShouldNot(HaveOccurred()) Ω(ctx.ResponseStatus()).Should(Equal(200)) }) }) }) }) var _ = Describe("LogRequest", func() { var handler *testHandler var ctx *goa.Context var service goa.Service params := url.Values{"param": []string{"value"}} payload := map[string]interface{}{"payload": 42} BeforeEach(func() { service = goa.New("test") service.SetEncoder(goa.JSONEncoderFactory(), true, "*/*") req, err := http.NewRequest("POST", "/goo", strings.NewReader(`{"payload":42}`)) Ω(err).ShouldNot(HaveOccurred()) rw := new(testResponseWriter) ctx = goa.NewContext(nil, service, req, rw, params) ctx.SetPayload(payload) handler = new(testHandler) logger := log15.New("test", "test") logger.SetHandler(handler) ctx.Logger = logger
// MountController mounts the JavaScript example controller under "/js". func MountController(service *goa.Service) { // Serve static files under js service.ServeFiles("/js/*filepath", "/Users/nii236/Go/src/github.com/nii236/go-react-webpack/js") goa.Info(goa.RootContext, "mount", goa.KV{"ctrl", "JS"}, goa.KV{"action", "ServeFiles"}, goa.KV{"route", "GET /js/*"}) }
// initService sets up the service encoders, decoders and mux. func initService(service *goa.Service) { if inited { return } inited = true // Setup encoders and decoders service.Encoder(goa.NewJSONEncoder, "application/json") service.Decoder(goa.NewJSONDecoder, "application/json") service.Decoder(goa.NewGobDecoder, "application/gob", "application/x-gob") service.Decoder(goa.NewXMLDecoder, "application/xml") // Setup default encoder and decoder service.Encoder(goa.NewJSONEncoder, "*/*") service.Decoder(goa.NewJSONDecoder, "*/*") }
// NewOperandsController creates a operands controller. func NewOperandsController(service *goa.Service) *OperandsController { return &OperandsController{Controller: service.NewController("operands")} }
"golang.org/x/net/context" "github.com/goadesign/goa" "github.com/goadesign/goa/middleware" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("RequestID", func() { const reqID = "request id" var ctx context.Context var rw http.ResponseWriter var req *http.Request var params url.Values var service *goa.Service BeforeEach(func() { service = newService(nil) var err error req, err = http.NewRequest("GET", "/goo", nil) Ω(err).ShouldNot(HaveOccurred()) req.Header.Set(middleware.RequestIDHeader, reqID) rw = new(testResponseWriter) params = url.Values{"query": []string{"value"}} service.Encoder.Register(goa.NewJSONEncoder, "*/*") ctx = newContext(service, rw, req, params) }) It("sets the request ID in the context", func() {
// ShowBottleOK Show runs the method Show of the given controller with the given parameters. // It returns the response writer so it's possible to inspect the response headers and the media type struct written to the response. // If ctx is nil then context.Background() is used. // If service is nil then a default service is created. func ShowBottleOK(t *testing.T, ctx context.Context, service *goa.Service, ctrl app.BottleController, id int) (http.ResponseWriter, *app.Bottle) { // Setup service var ( logBuf bytes.Buffer resp interface{} respSetter goatest.ResponseSetterFunc = func(r interface{}) { resp = r } ) if service == nil { service = goatest.Service(&logBuf, respSetter) } else { logger := log.New(&logBuf, "", log.Ltime) service.WithLogger(goa.NewLogger(logger)) newEncoder := func(io.Writer) goa.Encoder { return respSetter } service.Encoder = goa.NewHTTPEncoder() // Make sure the code ends up using this decoder service.Encoder.Register(newEncoder, "*/*") } // Setup request context rw := httptest.NewRecorder() u := &url.URL{ Path: fmt.Sprintf("/bottles/%v", id), } req, err := http.NewRequest("GET", u.String(), nil) if err != nil { panic("invalid test " + err.Error()) // bug } prms := url.Values{} prms["id"] = []string{fmt.Sprintf("%v", id)} if ctx == nil { ctx = context.Background() } goaCtx := goa.NewContext(goa.WithAction(ctx, "BottleTest"), rw, req, prms) showCtx, err := app.NewShowBottleContext(goaCtx, service) if err != nil { panic("invalid test data " + err.Error()) // bug } // Perform action err = ctrl.Show(showCtx) // Validate response if err != nil { t.Fatalf("controller returned %s, logs:\n%s", err, logBuf.String()) } if rw.Code != 200 { t.Errorf("invalid response status code: got %+v, expected 200", rw.Code) } var mt *app.Bottle if resp != nil { var ok bool mt, ok = resp.(*app.Bottle) if !ok { t.Errorf("invalid response media: got %+v, expected instance of app.Bottle", resp) } err = mt.Validate() if err != nil { t.Errorf("invalid response media type: %s", err) } } // Return results return rw, mt }
// CreateBottleCreated Create runs the method Create of the given controller with the given parameters and payload. // It returns the response writer so it's possible to inspect the response headers. // If ctx is nil then context.Background() is used. // If service is nil then a default service is created. func CreateBottleCreated(t *testing.T, ctx context.Context, service *goa.Service, ctrl app.BottleController, payload *app.CreateBottlePayload) http.ResponseWriter { // Setup service var ( logBuf bytes.Buffer resp interface{} respSetter goatest.ResponseSetterFunc = func(r interface{}) { resp = r } ) if service == nil { service = goatest.Service(&logBuf, respSetter) } else { logger := log.New(&logBuf, "", log.Ltime) service.WithLogger(goa.NewLogger(logger)) newEncoder := func(io.Writer) goa.Encoder { return respSetter } service.Encoder = goa.NewHTTPEncoder() // Make sure the code ends up using this decoder service.Encoder.Register(newEncoder, "*/*") } // Validate payload err := payload.Validate() if err != nil { e, ok := err.(*goa.Error) if !ok { panic(err) // bug } if e.Status != 201 { t.Errorf("unexpected payload validation error: %+v", e) } return nil } // Setup request context rw := httptest.NewRecorder() u := &url.URL{ Path: fmt.Sprintf("/bottles"), } req, err := http.NewRequest("POST", u.String(), nil) if err != nil { panic("invalid test " + err.Error()) // bug } prms := url.Values{} if ctx == nil { ctx = context.Background() } goaCtx := goa.NewContext(goa.WithAction(ctx, "BottleTest"), rw, req, prms) createCtx, err := app.NewCreateBottleContext(goaCtx, service) if err != nil { panic("invalid test data " + err.Error()) // bug } createCtx.Payload = payload // Perform action err = ctrl.Create(createCtx) // Validate response if err != nil { t.Fatalf("controller returned %s, logs:\n%s", err, logBuf.String()) } if rw.Code != 201 { t.Errorf("invalid response status code: got %+v, expected 201", rw.Code) } // Return results return rw }
// MountController mounts the swagger spec controller under "/swagger.json". func MountController(service goa.Service) { service.ServeFiles("/swagger.json", "swagger/swagger.json") }
import ( "bytes" "fmt" "io/ioutil" "net/http" "net/url" "github.com/goadesign/goa" "github.com/goadesign/middleware" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Application", func() { const appName = "foo" var s goa.Service BeforeEach(func() { s = goa.New(appName) s.SetDecoder(goa.JSONDecoderFactory(), true, "*/*") s.SetEncoder(goa.JSONEncoderFactory(), true, "*/*") }) Describe("New", func() { It("creates an application", func() { Ω(s).ShouldNot(BeNil()) }) It("initializes the application fields", func() { Ω(s.Name()).Should(Equal(appName)) Ω(s).Should(BeAssignableToTypeOf(&goa.Application{}))
// NewWorkitemtypeController creates a workitemtype controller. func NewWorkitemtypeController(service *goa.Service, db application.DB) *WorkitemtypeController { return &WorkitemtypeController{ Controller: service.NewController("WorkitemtypeController"), db: db, } }
// NewAreaController creates a area controller. func NewAreaController(service *goa.Service, db application.DB) *AreaController { return &AreaController{Controller: service.NewController("AreaController"), db: db} }
"regexp" "strings" "golang.org/x/net/context" "github.com/goadesign/goa" "github.com/goadesign/goa/middleware" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("RequireHeader", func() { var ctx context.Context var req *http.Request var rw http.ResponseWriter var service *goa.Service headerName := "Some-Header" BeforeEach(func() { var err error service = newService(nil) req, err = http.NewRequest("POST", "/foo/bar", strings.NewReader(`{"payload":42}`)) Ω(err).ShouldNot(HaveOccurred()) rw = new(testResponseWriter) ctx = newContext(service, rw, req, nil) }) It("matches a header value", func() { req.Header.Set(headerName, "some value") var newCtx context.Context h := func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
// MountBottleController "mounts" a Bottle resource controller on the given service. func MountBottleController(service goa.Service, ctrl BottleController) { // Setup encoders and decoders. This is idempotent and is done by each MountXXX function. tmp21 := goa.GobEncoderFactory() service.SetEncoder(tmp21, false, "application/gob", "application/x-gob") tmp22 := goa.JSONEncoderFactory() service.SetEncoder(tmp22, true, "application/json") tmp23 := goa.XMLEncoderFactory() service.SetEncoder(tmp23, false, "application/xml", "text/xml") tmp24 := goa.GobDecoderFactory() service.SetDecoder(tmp24, false, "application/gob", "application/x-gob") tmp25 := goa.JSONDecoderFactory() service.SetDecoder(tmp25, true, "application/json") tmp26 := goa.XMLDecoderFactory() service.SetDecoder(tmp26, false, "application/xml", "text/xml") // Setup endpoint handler var h goa.Handler mux := service.ServeMux() h = func(c *goa.Context) error { ctx, err := NewCreateBottleContext(c) ctx.Payload = ctx.RawPayload().(*CreateBottlePayload) if err != nil { return goa.NewBadRequestError(err) } return ctrl.Create(ctx) } mux.Handle("POST", "/cellar/accounts/:accountID/bottles", ctrl.HandleFunc("Create", h, unmarshalCreateBottlePayload)) service.Info("mount", "ctrl", "Bottle", "action", "Create", "route", "POST /cellar/accounts/:accountID/bottles") h = func(c *goa.Context) error { ctx, err := NewDeleteBottleContext(c) if err != nil { return goa.NewBadRequestError(err) } return ctrl.Delete(ctx) } mux.Handle("DELETE", "/cellar/accounts/:accountID/bottles/:bottleID", ctrl.HandleFunc("Delete", h, nil)) service.Info("mount", "ctrl", "Bottle", "action", "Delete", "route", "DELETE /cellar/accounts/:accountID/bottles/:bottleID") h = func(c *goa.Context) error { ctx, err := NewListBottleContext(c) if err != nil { return goa.NewBadRequestError(err) } return ctrl.List(ctx) } mux.Handle("GET", "/cellar/accounts/:accountID/bottles", ctrl.HandleFunc("List", h, nil)) service.Info("mount", "ctrl", "Bottle", "action", "List", "route", "GET /cellar/accounts/:accountID/bottles") h = func(c *goa.Context) error { ctx, err := NewRateBottleContext(c) ctx.Payload = ctx.RawPayload().(*RateBottlePayload) if err != nil { return goa.NewBadRequestError(err) } return ctrl.Rate(ctx) } mux.Handle("PUT", "/cellar/accounts/:accountID/bottles/:bottleID/actions/rate", ctrl.HandleFunc("Rate", h, unmarshalRateBottlePayload)) service.Info("mount", "ctrl", "Bottle", "action", "Rate", "route", "PUT /cellar/accounts/:accountID/bottles/:bottleID/actions/rate") h = func(c *goa.Context) error { ctx, err := NewShowBottleContext(c) if err != nil { return goa.NewBadRequestError(err) } return ctrl.Show(ctx) } mux.Handle("GET", "/cellar/accounts/:accountID/bottles/:bottleID", ctrl.HandleFunc("Show", h, nil)) service.Info("mount", "ctrl", "Bottle", "action", "Show", "route", "GET /cellar/accounts/:accountID/bottles/:bottleID") h = func(c *goa.Context) error { ctx, err := NewUpdateBottleContext(c) ctx.Payload = ctx.RawPayload().(*UpdateBottlePayload) if err != nil { return goa.NewBadRequestError(err) } return ctrl.Update(ctx) } mux.Handle("PATCH", "/cellar/accounts/:accountID/bottles/:bottleID", ctrl.HandleFunc("Update", h, unmarshalUpdateBottlePayload)) service.Info("mount", "ctrl", "Bottle", "action", "Update", "route", "PATCH /cellar/accounts/:accountID/bottles/:bottleID") }