Slide 1

Slide 1 text

HPBJOUSP

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

ల๬΋ͬͯ։ൃ͍͖͍ͯͨ͠ w "1*ͷ࢓༷มߋʹ͢͹΍͘ରԠ͍ͨ͠ w ϏδωεϩδοΫʹूத͍ͨ͠ w ಉ͡Α͏ͳίʔυԿ౓΋ॻ͘ͷͭΒ͍ w ࢓༷ॻͭΒ͍

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

HPB w ϚΠΫϩαʔϏε։ൃ༻ͷϑϨʔϜϫʔΫ w "1*σβΠϯΛ%4-Ͱهड़ ʙHP w σβΠϯ͔Β8FCΞϓϦͷͻͳܗΛੜ੒ HPBHFO w ΫϥΠΞϯτ΍υΩϡϝϯτ΋ੜ੒ʂ w W͕ϦϦʔε͞Ε·ͨ͠

Slide 7

Slide 7 text

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") }) })

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

TXBHHFS KTPOcZBNM ΋ੜ੒͠·͢

Slide 10

Slide 10 text

%FTJHOpSTU5IFOXJO

Slide 11

Slide 11 text

Կ͔Β͸͡ΊΔ͔ʁ (FUUJOH4UBSUFEXJUIHPB
 IUUQHPBEFTJHOMFBSOHVJEF ʹͷͬͯΔͪͬͪΌͳσβΠϯͰࢼ͢ͷ͕͓͢͢Ί HJUIVCDPNHPBEFTJHOHPBDFMMBSͷࠎࢠ෦෼

Slide 12

Slide 12 text

wαϯϓϧΛ͋ͨΔ
 IUUQTHJUIVCDPNHPBEFTJHOFYBNQMFT
 IUUQTHJUIVCDPNHPBEFTJHOHPBDFMMBS w"1*%4-ͷϦϑΝϨϯεΛ͋ͨΔ
 IUUQHPBEFTJHOSFGFSFODFHPBEFTJHOBQJETM wTMBDL
 IUUQTHPQIFSTTMBDLDPNNFTTBHFTHPB ࠔͬͨͱ͖͸

Slide 13

Slide 13 text

w ΠϯετʔϧHPBHFOͷ࢖͍ํ w σβΠϯͷͭͷཁૉ w ύϥϝʔλͱόϦσʔγϣϯʹ͍ͭͯ w ฤू͕ඞཁͳίʔυʹ͍ͭͯɿNBJO DPOUSPMMFS w #BTJDೝূͷαϯϓϧ w ςετ "HFOEB

Slide 14

Slide 14 text

JOTUBMM HPHFUVHJUIVCDPNHPBEFTJHOHPB HPBHFOͱ͍͏όΠφϦ͕ग़དྷΔ͕ɼ͜Ε͸ HPBEFTJHOHPBHPBHFOHFO@ ͱ͍͏ϑΥϧμʹґଘ͍ͯ͠ΔͷͰ஫ҙ

Slide 15

Slide 15 text

WFOEPSJOH͢Δ৔߹ DEWFOEPSHJUIVCDPNHPBEFTJHOHPBHPBHFO HPCVJME DE CVJME WFOEPSHJUIVCDPNHPBEFTJHOHPBHPBHFOHPBHFOBQQEEFTJHO QBDLBHF WFOEPSϑΥϧμͷHPBHFOΛ͔ͭ͏͜ͱ

Slide 16

Slide 16 text

HPBHFO ॳճ HPBHFOEDFMMBSEFTJHOCPPUTUSBQ σβΠϯͷύοέʔδύε͸(01"5)TSD͕ج४ wNBJOHPʜΞϓϦέʔγϣϯͷϝΠϯ wCPUUMFHPʜ"1*ίϯτϩʔϥ lϦιʔε໊zHPʹͳΔ ŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠŠ wBQQʜੜ੒͞Εͨ8FC"1*ͷίʔυ wTXBHHFSʜTXBHHFS࢓༷ॻ wUPPMʜΫϥΠΞϯτπʔϧ wDMJFOUʜΫϥΠΞϯτ༻ͷίʔυ ੜ੒͞ΕΔ΋ͷ

Slide 17

Slide 17 text

HPBHFO "WBJMBCMF$PNNBOET BQQ(FOFSBUFBQQMJDBUJPODPEF DMJFOU(FOFSBUFDMJFOUQBDLBHFBOEUPPM HFO3VOUIJSEQBSUZHFOFSBUPS KT(FOFSBUF+BWB4DSJQUDMJFOU NBJO(FOFSBUFBQQMJDBUJPOTDB⒎PMEJOH TDIFNB(FOFSBUF+40/4DIFNB TXBHHFS(FOFSBUF4XBHHFS CPPUTUSBQ͸ BQQNBJOTXBHHFSDMJFOU Λ࣮ߦͯͨ͠ɽ͜ͷ͋ͨΓΛΑ͘࢖͏ͷͰ .BLFpMFΛ༻ҙ͓ͯ͘͠ͱ͍͍ ˡฤू͢Δͷ͸͜ΕͰੜ੒͞ΕΔ΋ͷ͚ͩ

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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*

Slide 20

Slide 20 text

"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") })

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

.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") }) } )

Slide 25

Slide 25 text

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ʹ௥Ճ͢Δ͚ͩ

Slide 26

Slide 26 text

ύϥϝʔλͷࢦఆํ๏ Param("bottleID", Integer, "Bottle ID", func() { Minimum(0) Maximum(127)
 Default(1)
 Example(3) }) ύϥϝʔλ໊ ܕ આ໌ WBMJEBUJPO σϑΥϧτ஋ͷࢦఆ ࢖༻ྫ লུͯ͠୹͘΋͔͚Δ͚Ͳɼجຊ͸͜ͷܗ &YBNQMF ͸ࢦఆ͠ͳͯ͘΋ܕʹ߹Θͤͯద౰ʹ࡞ͬͯ͘ΕΔ
 ෆཁͳΒ/P&YBNQMF Λࢦఆ͢Δ ༨ஊ "UUSJCVUF1BSBN.FNCFS͸࣮͸ಉ͡΋ͷ

Slide 27

Slide 27 text

ύϥϝʔλʹࢦఆͰ͖Δܕ جຊܕ 4USJOH*OUFHFS#PPMFBO/VNCFS%BUF5JNF66*% ҎԼ΋ܕͱͯ͠ࢦఆͰ͖Δ 5ZQF ʜ Ͱఆٛ͞Εͨ΋ͷ "UUSJCVUFΛ·ͱΊͯߏ଄ମʹͨ͠΋ͷ .FEJB5ZQF ʜ Ͱఆٛ͞Εͨ΋ͷ ϝσΟΞλΠϓͱͯ͠ఆٛͨ͠΋ͷ "SSBZ0G ʜ Ͱఆٛ͞Εͨ഑ྻ ྫ"SSBZ0G *OUFHFS "SSBZ0G #PUUMF )BTI0G ʜ Ͱఆٛ͞Εͨ ϋογϡϚοϓ ྫ)BTI0G 4USJOH #PUUMF

Slide 28

Slide 28 text

ύϥϝʔλʹࢦఆͰ͖Δ7BMJEBUJPO ࠷େ࠷খ .BYJNVN .JOJNVN ࠷େ௕࠷খ௕ .BY-FOHUI .JO-FOHUI ύλʔϯ 1BUUFSO ?GPP ྻڍ &OVN &NVN NBMF GFNBMF ఆܕ 'PSNBU EBUFUJNF 'PSNBU FNBJM 'PSNBU JQW 'PSNBU NBD

Slide 29

Slide 29 text

ฤू͕ඞཁͳίʔυ HPBHFONBJOͰੜ੒͞ΕΔίʔυ͸ฤू͕ඞཁ
 ͱ͍͏͔ɼฤू͕ඞཁͳͷ͸͜Ε͔͠ͳ͍ʂʣ w NBJO w DPOUSPMMFS طʹੜ੒͞Ε͍ͯΔϑΝΠϧ͕͋Ε͹্ॻ͖͞Εͳ͍

Slide 30

Slide 30 text

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) } } ࣌ʑ৽͍͠ίϯτϩʔϥ௥Ճ͢Δͷ๨ΕΔ

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

#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) }) })

Slide 33

Slide 33 text

#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͕ੜ੒͢Δίʔυ͕ద੾ʹ੾Γସ͑ͯ͘ΕΔ ೝূ͋Γͳ͠ΤϯυϙΠϯτʹରԠ͢Δͷίϯτϩʔϥʔ

Slide 34

Slide 34 text

Ͳ͏΍ͬͯ࢖͏͔ 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 SFRIUUQ3FRVFTU 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ͱҰॹʹஔ͍͓ͯ͘

Slide 35

Slide 35 text

ೝূ͍Ζ͍Ζ w #BTJD"VUIʜ#BTJD"VUI4FDVSJUZ w "1*,FZʜ"1*,FZ4FDVSJUZ w +85ʜ+854FDVSJUZ w 0"VUIʜ0"VUI4FDVSJUZ 
 IUUQTHJUIVCDPNHPBEFTJHOFYBNQMFTUSFFNBTUFSTFDVSJUZ

Slide 36

Slide 36 text

ςετ 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Ληοτ͢Ε͹͍͍

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

*NBHF$SFEJUT w (PB IUUQTHPBEFTJHO w 5IF(PHPQIFSXBTEFTJHOFECZ3FOFF 'SFODI IUUQSFOFFGSFODICMPHTQPUDPN w IUUQTNFNFHFOFSBUPSOFU9"MM5IF5IJOHT