goa勉強会 in 六本木一丁目

goa勉強会 in 六本木一丁目

E9f19057a827b90932d66f174e31fa90?s=128

ikawaha

June 12, 2017
Tweet

Transcript

  1. %FTJHOpSTU5IFOXJO

  2. 8FC"1*ΛϥΠϑαΠΫϧʹ Ԋͬͯ։ൃ͠Α͏ ίʔυυΩϡϝϯτੜ੒ "1*σβΠϯΛॻ͘ ίϯτϩʔϥ෦ ϏδωεϩδοΫ ͷ࣮૷

  3. 8FC"1*ॻ͍ͨ͜ͱ͋Γ·͔͢ʁ w 3PVUJOHͲ͏͢Δʁ w όϦσʔγϣϯͲ͏͢Δʁ w ͳΜͳΒOFUIUUQͰ͍͚Δ ҙ֎ͱ؆୯ͳΜ͡Όͳ͍ʁ

  4. ࣮ࡍ։ൃͯ͠ΈΔͱɾɾɾ w "1*ͷ࢓༷มߋ͕ ͨͼͨͼʁ ඞཁͩͬͨΓ w όϦσʔγϣϯ͕࢓༷มߋʹԊͬͯͳ͔ͬͨΓ w Τϥʔ࣌ͷฦ஋ͷߟྀ·Ͱߦ͖ಧ͍ͯͳ͔ͬͨΓ w

    ࢓༷ॻ͚ͩݹ͔ͬͨΓɾɾɾ ΍ͨΒͱಉ͡ࣄΛ܁Γฦ͢͜ͱଟ͍
  5. શͯੜ੒͠Ζʂ

  6. "1*σβΠϯͷϥΠϑαΠΫϧ ίʔυυΩϡϝϯτੜ੒ "1*σβΠϯΛॻ͘ ίϯτϩʔϥ෦ ϏδωεϩδοΫ ͷ࣮૷

  7. 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") }) })
  8. "1*σβΠϯͷϥΠϑαΠΫϧ ίʔυυΩϡϝϯτੜ੒ "1*σβΠϯΛॻ͘ ίϯτϩʔϥ෦ ϏδωεϩδοΫ ͷ࣮૷

  9. None
  10. w "1*σβΠϯͷͭͷཁૉ  w ύϥϝʔλͱόϦσʔγϣϯʹ͍ͭͯ w ϛυϧ΢ΤΞ "HFOEB

  11. EFTJHOͷͭͷཁૉ  w "1*ʜ"1*αʔόͷఆٛ w 3FTPVSDFʜΞΫηεํ๏ΤϯυϙΠϯτͳͲ w .FEJB5ZQFʜϨεϙϯεσʔλͷܗࣜ w 1BZMPBEʜϦΫΤετσʔλͷܗࣜ

  12. 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*
  13. "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") })
  14. 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
  15. 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
  16. 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
  17. .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") }) } )
  18. 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ʹ௥Ճ͢Δ͚ͩ
  19. ฤू͕ඞཁͳίʔυ ੜ੒͞ΕΔίʔυͰฤू͕ඞཁͳͷ͸͜Ε͚ͩʂ w NBJOˠNBJOHPͱ͍͏ϑΝΠϧ w DPOUSPMMFSˠϦιʔε໊HPͱ͍͏ϑΝΠϧ

  20. 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) } } ίϯτϩʔϥ ϛυϧ΢ΤΞ αʔόىಈ
  21. 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
  22. ϛυϧ΢ΤΞ w ೝূ #BTJD +85 "1*,FZ 0"VUIʜ  w -PH3FRVFTUʜϦΫΤετͱϨεϙϯεͷͷϩά

    w -PH3FTQPOTFʜ%&#6(ϨϕϧͰϨεϙϯεϘσΟΛه࿥ w 3FDPWFSʜQBOJD࣌ͷϦΧόʔɼόοΫτϨʔεͷه࿥ w 3FRVJSF)FBEFSʜඞཁͳϦΫΤετϔομ͕͋Δ͔νΣοΫ w ͦͷଞɼαʔυύʔςΟྲྀ༻͢Δͷ͸؆୯
  23. ϛυϧ΢ΤΞ 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ͱҰॹʹஔ͍͓ͯ͘
  24. None
  25. wαϯϓϧΛ͋ͨΔ
 IUUQTHJUIVCDPNHPBEFTJHOFYBNQMFT
 IUUQTHJUIVCDPNHPBEFTJHOHPBDFMMBS w"1*%4-ͷϦϑΝϨϯεΛ͋ͨΔ
 IUUQHPBEFTJHOSFGFSFODFHPBEFTJHOBQJETM wTMBDL
 IUUQTHPQIFSTTMBDLDPNNFTTBHFTHPB
 IUUQTHPQIFSTTMBDLDPNNFTTBHFTHPBKQ ࠔͬͨͱ͖͸

  26. w LBHPNFͷதͷਓ w ύγϑΟοΫɾϙʔλʔͱ͍͏ձࣾͰHPMBOHॻ͍ͯ·͢ w ڵຯ͸ɼݕࡧ/-1ΦʔτϚτϯܗࣜݴޠͱ͔

  27. *NBHF$SFEJUT w (PB IUUQTHPBEFTJHO  w 5IF(PHPQIFSXBTEFTJHOFECZ3FOFF 'SFODI IUUQSFOFFGSFODICMPHTQPUDPN 

    w IUUQTNFNFHFOFSBUPSOFU9"MM5IF5IJOHT