Upgrade to Pro — share decks privately, control downloads, hide ads and more …

goa intro.

ikawaha
September 05, 2016
6.5k

goa intro.

golang : goa 勉強会の資料です

ikawaha

September 05, 2016
Tweet

Transcript

  1. package design // The convention consists of naming the design

    // package "design" import ( . "github.com/goadesign/goa/design" // Use . imports to enable the DSL . "github.com/goadesign/goa/design/apidsl" ) var _ = API("cellar", func() { // API defines the microservice endpoint and Title("The virtual wine cellar") // other global properties. There should be one Description("A simple goa service") // and exactly one API definition appearing in Scheme("http") // the design. Host("localhost:8080") }) var _ = Resource("bottle", func() { // Resources group related API endpoints BasePath("/bottles") // together. They map to REST resources for REST DefaultMedia(BottleMedia) // services. Action("show", func() { // Actions define a single API endpoint together Description("Get bottle by id") // with its path, parameters (both path Routing(GET("/:bottleID")) // parameters and querystring values) and payload Params(func() { // (shape of the request body). Param("bottleID", Integer, "Bottle ID") }) Response(OK) // Responses define the shape and status code Response(NotFound) // of HTTP responses. }) }) // BottleMedia defines the media type used to render bottles. var BottleMedia = MediaType("application/vnd.goa.example.bottle+json", func() { Description("A bottle of wine") Attributes(func() { // Attributes define the media type shape. Attribute("id", Integer, "Unique bottle ID") Attribute("href", String, "API href for making requests on the bottle") Attribute("name", String, "Name of wine") Required("id", "href", "name") }) View("default", func() { // View defines a rendering of the media type. Attribute("id") // Media types may have multiple views and must Attribute("href") // have a "default" view. Attribute("name") }) })
  2. package design // The convention consists of naming the design

    // package "design" import ( . "github.com/goadesign/goa/design" // Use . imports to enable the DSL . "github.com/goadesign/goa/design/apidsl" ) var _ = API("cellar", func() { // API defines the microservice endpoint and Title("The virtual wine cellar") // other global properties. There should be one Description("A simple goa service") // and exactly one API definition appearing in Scheme("http") // the design. Host("localhost:8080") }) var _ = Resource("bottle", func() { // Resources group related API endpoints BasePath("/bottles") // together. They map to REST resources for REST DefaultMedia(BottleMedia) // services. Action("show", func() { // Actions define a single API endpoint together Description("Get bottle by id") // with its path, parameters (both path Routing(GET("/:bottleID")) // parameters and querystring values) and payload Params(func() { // (shape of the request body). Param("bottleID", Integer, "Bottle ID") }) Response(OK) // Responses define the shape and status code Response(NotFound) // of HTTP responses. }) }) // BottleMedia defines the media type used to render bottles. var BottleMedia = MediaType("application/vnd.goa.example.bottle+json", func() { Description("A bottle of wine") Attributes(func() { // Attributes define the media type shape. Attribute("id", Integer, "Unique bottle ID") Attribute("href", String, "API href for making requests on the bottle") Attribute("name", String, "Name of wine") Required("id", "href", "name") }) View("default", func() { // View defines a rendering of the media type. Attribute("id") // Media types may have multiple views and must Attribute("href") // have a "default" view. Attribute("name") }) }) "1*
  3. "1* package design import ( . "github.com/goadesign/goa/design" . "github.com/goadesign/goa/design/apidsl" )

    var _ = API("cellar", func() { Title("The virtual wine cellar") Version("") Description("A simple goa service") Scheme("http") Host("localhost:8080") })
  4. package design // The convention consists of naming the design

    // package "design" import ( . "github.com/goadesign/goa/design" // Use . imports to enable the DSL . "github.com/goadesign/goa/design/apidsl" ) var _ = API("cellar", func() { // API defines the microservice endpoint and Title("The virtual wine cellar") // other global properties. There should be one Description("A simple goa service") // and exactly one API definition appearing in Scheme("http") // the design. Host("localhost:8080") }) var _ = Resource("bottle", func() { // Resources group related API endpoints BasePath("/bottles") // together. They map to REST resources for REST DefaultMedia(BottleMedia) // services. Action("show", func() { // Actions define a single API endpoint together Description("Get bottle by id") // with its path, parameters (both path Routing(GET("/:bottleID")) // parameters and querystring values) and payload Params(func() { // (shape of the request body). Param("bottleID", Integer, "Bottle ID") }) Response(OK) // Responses define the shape and status code Response(NotFound) // of HTTP responses. }) }) // BottleMedia defines the media type used to render bottles. var BottleMedia = MediaType("application/vnd.goa.example.bottle+json", func() { Description("A bottle of wine") Attributes(func() { // Attributes define the media type shape. Attribute("id", Integer, "Unique bottle ID") Attribute("href", String, "API href for making requests on the bottle") Attribute("name", String, "Name of wine") Required("id", "href", "name") }) View("default", func() { // View defines a rendering of the media type. Attribute("id") // Media types may have multiple views and must Attribute("href") // have a "default" view. Attribute("name") }) }) 3FTPVSDF
  5. 3FTPVSDF var _ = Resource("bottle", func() { BasePath("/bottles") DefaultMedia(BottleMedia) Action("show",

    func() { Description("Get bottle by id") Routing(GET("/:bottleID")) Params(func() { Param("bottleID", Integer, "Bottle ID", func() { Minimum(0) Maximum(127) }) }) Response(OK) Response(NotFound) }) }) (&5CPUUMFT
  6. package design // The convention consists of naming the design

    // package "design" import ( . "github.com/goadesign/goa/design" // Use . imports to enable the DSL . "github.com/goadesign/goa/design/apidsl" ) var _ = API("cellar", func() { // API defines the microservice endpoint and Title("The virtual wine cellar") // other global properties. There should be one Description("A simple goa service") // and exactly one API definition appearing in Scheme("http") // the design. Host("localhost:8080") }) var _ = Resource("bottle", func() { // Resources group related API endpoints BasePath("/bottles") // together. They map to REST resources for REST DefaultMedia(BottleMedia) // services. Action("show", func() { // Actions define a single API endpoint together Description("Get bottle by id") // with its path, parameters (both path Routing(GET("/:bottleID")) // parameters and querystring values) and payload Params(func() { // (shape of the request body). Param("bottleID", Integer, "Bottle ID") }) Response(OK) // Responses define the shape and status code Response(NotFound) // of HTTP responses. }) }) // BottleMedia defines the media type used to render bottles. var BottleMedia = MediaType("application/vnd.goa.example.bottle+json", func() { Description("A bottle of wine") Attributes(func() { // Attributes define the media type shape. Attribute("id", Integer, "Unique bottle ID") Attribute("href", String, "API href for making requests on the bottle") Attribute("name", String, "Name of wine") Required("id", "href", "name") }) View("default", func() { // View defines a rendering of the media type. Attribute("id") // Media types may have multiple views and must Attribute("href") // have a "default" view. Attribute("name") }) }) .FEJB5ZQF
  7. .FEJB5ZQF var BottleMedia = MediaType("application/vnd.goa.example.bottle+json", func() { Description("A bottle of

    wine") Attributes(func() { Attribute("id", Integer, "Unique bottle ID") Attribute("name", String, "Name of wine") Required("id", "name") }) View("default", func() { Attribute("id") Attribute("name") }) } )
  8. 1BZMPBE // [1, 2, 3, 4] ʹରԠ͢Δ Payload ͷྫ var

    BottlesPayload = Type("BottlesPayload", func() { Member("bottles", ArrayOf(Integer), “Bottle IDs”, func(){ MinLength(1) }) Required("bottles") }) var _ = Resource("bottle", func() { BasePath("/bottles") DefaultMedia(BottleMedia) Action("show", func() { Routing(POST("") Payload(BottlesPayload) Response(OK) Response(NotFound) }) }) "DUJPOʹ௥Ճ͢Δ͚ͩ
  9. ύϥϝʔλͷࢦఆํ๏ Param("bottleID", Integer, "Bottle ID", func() { Minimum(0) Maximum(127)
 Default(1)


    Example(3) }) ύϥϝʔλ໊ ܕ આ໌ WBMJEBUJPO σϑΥϧτ஋ͷࢦఆ ࢖༻ྫ লུͯ͠୹͘΋͔͚Δ͚Ͳɼجຊ͸͜ͷܗ &YBNQMF ͸ࢦఆ͠ͳͯ͘΋ܕʹ߹Θͤͯద౰ʹ࡞ͬͯ͘ΕΔ
 ෆཁͳΒ/P&YBNQMF Λࢦఆ͢Δ ༨ஊ "UUSJCVUF1BSBN.FNCFS͸࣮͸ಉ͡΋ͷ
  10. ύϥϝʔλʹࢦఆͰ͖Δܕ جຊܕ 4USJOH*OUFHFS#PPMFBO/VNCFS%BUF5JNF66*% ҎԼ΋ܕͱͯ͠ࢦఆͰ͖Δ 5ZQF ʜ Ͱఆٛ͞Εͨ΋ͷ "UUSJCVUFΛ·ͱΊͯߏ଄ମʹͨ͠΋ͷ .FEJB5ZQF ʜ

    Ͱఆٛ͞Εͨ΋ͷ ϝσΟΞλΠϓͱͯ͠ఆٛͨ͠΋ͷ "SSBZ0G ʜ Ͱఆٛ͞Εͨ഑ྻ ྫ"SSBZ0G *OUFHFS "SSBZ0G #PUUMF )BTI0G ʜ Ͱఆٛ͞Εͨ ϋογϡϚοϓ ྫ)BTI0G 4USJOH #PUUMF
  11. ύϥϝʔλʹࢦఆͰ͖Δ7BMJEBUJPO ࠷େ࠷খ .BYJNVN  .JOJNVN  ࠷େ௕࠷খ௕ .BY-FOHUI  .JO-FOHUI

     ύλʔϯ 1BUUFSO ?GPP ྻڍ &OVN    &NVN NBMF GFNBMF ఆܕ 'PSNBU EBUFUJNF 'PSNBU FNBJM  'PSNBU JQW 'PSNBU NBD
  12. NBJO func main() { // Create service service := goa.New("cellar")

    // Mount middleware service.Use(middleware.RequestID()) service.Use(middleware.LogRequest(true)) service.Use(middleware.ErrorHandler(service, true)) service.Use(middleware.Recover()) // Mount "bottle" controller c := NewBottleController(service) app.MountBottleController(service, c) // Start service if err := service.ListenAndServe(":8080"); err != nil { service.LogError("startup", "err", err) } } ࣌ʑ৽͍͠ίϯτϩʔϥ௥Ճ͢Δͷ๨ΕΔ
  13. DPOUSPMMFS // Show runs the show action. func (c *BottleController)

    Show(ctx *app.ShowBottleContext) error { // BottleController_Show: start_implement // Put your logic here // BottleController_Show: end_implement res := &app.GoaExampleBottle{} return ctx.OK(res) } (app) type ShowBottleContext struct { context.Context *goa.ResponseData *goa.RequestData BottleID int } (&5CPUUMFT
  14. #BTJDೝূ var BasicAuth = BasicAuthSecurity("my_basic_auth") var _ = Resource("foo", func()

    { Security(BasicAuth) // ͜ͷϦιʔεͷΞΫγϣϯʹ͸͢΂ͯೝূ͕ඞཁʹͳΔ Action("secure", func() { Description("BasicAuth͋Γ") Routing(GET("/")) Response(OK) Response(Unauthorized) }) Action("unsecure", func() { Description("BasicAuthͳ͠") Routing(GET("/unsecure")) NoSecurity() // ඞཁͳ͍ͳΒ໌ࣔతʹࢦఆ͢Δ Response(OK) }) })
  15. #BTJDೝূ // Secure runs the secure action. func (c *FooController)

    Secure(ctx *app.SecureFooContext) error { // Put your logic here return nil } // Unsecure runs the unsecure action. func (c *FooController) Unsecure(ctx *app.UnsecureFooContext) error { // Put your logic here return nil } ೝূ͋Γͳ͠͸ίϯτϩʔϥʔͰҙࣝ͠ͳ͍͍ͯ͘ HPBHFO͕ੜ੒͢Δίʔυ͕ద੾ʹ੾Γସ͑ͯ͘ΕΔ ೝূ͋Γͳ͠ΤϯυϙΠϯτʹରԠ͢Δͷίϯτϩʔϥʔ
  16. Ͳ͏΍ͬͯ࢖͏͔ app.UseMyBasicAuthMiddleware(service, NewMyBasicAuthMiddleware()) NBJOHPʹBQQTFDVSJUZHPͰఆٛ͞Ε͍ͯΔ.PVOUFSΛ௥Ճ #BTJDೝূ༻ͷ.JEEMFXBSFΛࣗ෼Ͱ༻ҙͯ͠ηοτ GVOD/FX#BTJD"VUI.JEEMFXBSF HPB.JEEMFXBSF\  SFUVSOGVOD IHPB)BOEMFS

    HPB)BOEMFS\   SFUVSOGVOD DUYDPOUFYU$POUFYU SXIUUQ3FTQPOTF8SJUFS SFR IUUQ3FRVFTU FSSPS\    VTFS QBTT PLSFR#BTJD"VUI     JGPL\     HPB-PH*OGP DUY GBJMFECBTJDBVUI      SFUVSO&SS6OBVUIPSJ[FE NJTTJOHBVUI     ^    HPB-PH*OGP DUY CBTJD VTFS VTFS QBTT QBTT     SFUVSOI DUY SX SFR    ^  ^ ^ ೝূ෦෼Λ࣮૷ͯ͠DPOUSPMMFSͱҰॹʹஔ͍͓ͯ͘
  17. ೝূ͍Ζ͍Ζ w #BTJD"VUIʜ#BTJD"VUI4FDVSJUZ  w "1*,FZʜ"1*,FZ4FDVSJUZ  w +85ʜ+854FDVSJUZ 

    w 0"VUIʜ0"VUI4FDVSJUZ 
 IUUQTHJUIVCDPNHPBEFTJHOFYBNQMFTUSFFNBTUFSTFDVSJUZ
  18. ςετ func ShowBottleOK(t goatest.TInterface, ctx context.Context, service *goa.Service, ctrl app.BottleController,

    bottleID int, payload *app.BottlesPayload) (http.ResponseWriter, *app.GoaExampleBottle) BQQUFTUͷ഑Լʹࣗಈతʹੜ੒͞ΕΔ ΤϯυϙΠϯτͱظ଴͞ΕΔฦ஋͝ͱʹ
 ϝιου͕࡞ΒΕΔͷͰ ͦΕʹ͋ΘͤͯςετΛॻ͍͓͚ͯΔ func ShowBottleNotFound(t goatest.TInterface, ctx context.Context, service *goa.Service, ctrl app.BottleController, bottleID int, payload *app.BottlesPayload) http.ResponseWriter HPBUFTU5*OUFSGBDF͸ UFTUJOH5Ληοτ͢Ε͹͍͍