Slide 1

Slide 1 text

goaΛ࢖ͬͨAPI։ൃ Go Conference 2017 Spring / @decafe09

Slide 2

Slide 2 text

ࣗݾ঺հ খ໺ࣉ ढ़໵ (@decafe09) • γφδʔϚʔέςΟϯάגࣜձࣾ • Goྺ 2೥

Slide 3

Slide 3 text

ࠓ೔࿩͢͜ͱ goaΛ࢖ͬͨAPI։ൃͰࠔͬͨ͜ͱͱղܾࡦ

Slide 4

Slide 4 text

goa https://github.com/goadesign/goa • ϚΠΫϩαʔϏε޲͚ϑϨʔϜϫʔΫ • DSLͰॻ͍ͨAPIσβΠϯ͔Βίʔυ΍ SwaggerΛੜ੒Ͱ͖Δ

Slide 5

Slide 5 text

։ൃͷྲྀΕ

Slide 6

Slide 6 text

design DSL DSLͰAPIσβΠϯΛॻ͘

Slide 7

Slide 7 text

var _ = Resource("account", func() { DefaultMedia(Account) BasePath("/accounts") Action("show", func() { Routing( GET("/:accountID"), ) Description("Retrieve account with given id.") Params(func() { Param("accountID", Integer, "Account ID", func() { Minimum(1) }) }) Response(OK) Response(NotFound) Response(BadRequest, ErrorMedia) }) } DSLͰͷσβΠϯ

Slide 8

Slide 8 text

goagen ίϚϯυͰίʔυੜ੒ Swagger΋ੜ੒Ͱ͖Δ design API DSL goagen

Slide 9

Slide 9 text

ίʔυੜ੒ goagen ίϚϯυͰίʔυੜ੒ ެࣜαϯϓϧ https://github.co/goadesign/goa-cellar goagen main -d github.com/goadesign/goa-cellar/design ੜ੒ର৅ σβΠϯ

Slide 10

Slide 10 text

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 "account" controller c := NewAccountController(service) app.MountAccountController(service, c) // Start service if err := service.ListenAndServe(":8081"); err != nil { service.LogError("startup", "err", err) } } ੜ੒͞Εͨίʔυ

Slide 11

Slide 11 text

ੜ੒͞ΕͨίʔυΛϕʔεʹ࣮૷ design API ࣮૷

Slide 12

Slide 12 text

func main() { // Create service service := goa.New("cellar") // Mount middleware service.Use(myMiddleware.RestrictIP()) service.Use(middleware.RequestID()) service.Use(middleware.LogRequest(true)) service.Use(middleware.ErrorHandler(service, true)) service.Use(middleware.Recover()) // Mount "account" controller c := NewAccountController(service) app.MountAccountController(service, c) // Start service if err := service.ListenAndServe(":8081"); err != nil { service.LogError("startup", "err", err) } } service.Use(myMiddleware.RestrictIP()) ϛυϧ΢ΣΞΛ௥Ճ

Slide 13

Slide 13 text

ಥવͷAPI࢓༷มߋʂ ʢ͋Δ͋Δʣ

Slide 14

Slide 14 text

DSLΛमਖ਼ͯ͠goagenͰίʔυ࠶ੜ੒ design API goagen ࠶ੜ੒ मਖ਼

Slide 15

Slide 15 text

ੜ·ΕΔࠩ෼ design API ࠶ੜ੒ API ࣮૷

Slide 16

Slide 16 text

खಈͰͷࠩ෼Ϛʔδ design API ࠶ੜ੒ API ࣮૷

Slide 17

Slide 17 text

΍ͬͯΒΕΔ͔ͬʂ

Slide 18

Slide 18 text

։ൃΛ࢝ΊΔͱࠔΔͱ͜Ζ σβΠϯͷมߋͰίʔυΛ࠶ੜ੒͢Δࡍɺɹɹ ࠩ෼Λݟͳ͕ΒखಈϚʔδ͠ͳ͍ͱ͍͚ͳ͍ɻ

Slide 19

Slide 19 text

։ൃΛ࢝ΊΔͱࠔΔͱ͜Ζ σβΠϯͷมߋͰίʔυΛ࠶ੜ੒͢Δࡍɺɹɹ ࠩ෼Λݟͳ͕ΒखಈϚʔδ͠ͳ͍ͱ͍͚ͳ͍ɻ ɹɹɹɹɹσβΠϯʹґଘ͠ͳ͍෦෼͕ ɹɹɹɹɹੜ੒͞ΕΔίʔυʹؚ·Ε͍ͯΔ

Slide 20

Slide 20 text

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 "account" controller c := NewAccountController(service) app.MountAccountController(service, c) // Start service if err := service.ListenAndServe(":8081"); err != nil { service.LogError("startup", "err", err) } } σβΠϯʹґଘ͠ͳ͍

Slide 21

Slide 21 text

σβΠϯ͔Βࣗ෼ͷ࢖͍΍͍͢Α͏ʹίʔυੜ੒͍ͨ͠

Slide 22

Slide 22 text

ͦΕpluginͰͰ͖ΔΑ

Slide 23

Slide 23 text

goa Plugin Generators https://goa.design/extend/generators/ goagenͷpluginͰDSL͔Βࣗ༝ʹίʔυੜ੒ goagen gen -d github.com/goadesign/goa-cellar/design \ —pkg-path=/go/path/to/genresnames goagen gen plugin

Slide 24

Slide 24 text

goagen main templateमਖ਼͢Δ͚ͩͰ͍͚Δʂ https://github.com/goadesign/goa/blob/v1.1.0/goagen/gen_main/ generator.go

Slide 25

Slide 25 text

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 "account" controller c := NewAccountController(service) app.MountAccountController(service, c) // Start service if err := service.ListenAndServe(":8081"); err != nil { service.LogError("startup", "err", err) } } ͜ΕΛ

Slide 26

Slide 26 text

func main() { // Create service service := goa.New("cellar") // Mount middleware mountMiddleware(service) // Mount "account" controller c := NewAccountController(service) app.MountAccountController(service, c) // Start service if err := service.ListenAndServe(":8081"); err != nil { service.LogError("startup", "err", err) } } ͜͏ʂ

Slide 27

Slide 27 text

ϑΝΠϧΛ෼͚Δ // middleware.go func mountMiddleware(service *goa.Service) { // Put Your Code service.Use(middleware.RequestID()) service.Use(middleware.LogRequest(true)) service.Use(middleware.ErrorHandler(service, true)) service.Use(middleware.Recover()) } main.go͔Β੾Γग़ͯ͠ɺผϑΝΠϧʹ͢Δɻ ϛυϧ΢ΣΞ͕૿͑ͯ΋ίʔυੜ੒ͷӨڹΛड͚ͳ͍

Slide 28

Slide 28 text

࢓༷มߋʹ଱͑ΒΕΔʂ

Slide 29

Slide 29 text

΄͔ʹ΋΍Γํ͸͋Δͱࢥ͍·͕͢

Slide 30

Slide 30 text

goagenͰࠔͬͨΒ plugin࡞ͬͯΈ·͠ΐ͏

Slide 31

Slide 31 text

͓·͚

Slide 32

Slide 32 text

swrt https://github.com/decafe09/swrt swagger.jsonͷϧʔςΟϯάΛCLIͰ֬ೝɻ $ swrt -f swagger/swagger.json http://localhost:8081 GET /cellar/_ah/health GET /cellar/accounts POST /cellar/accounts GET /cellar/accounts/{accountID} PUT /cellar/accounts/{accountID} DELETE /cellar/accounts/{accountID} GET /cellar/accounts/{accountID}/bottles

Slide 33

Slide 33 text

ΈΜGoಡΜͰ࡞Γ·ͨ͠

Slide 34

Slide 34 text

goaͷࢀߟαΠτ • ެࣜαΠτ https://goa.design/ja/ ೔ຊޠ൛͋Γ͕ͱ͏͍͟͝·͢ m(_ _)m • goaΛ࢝ΊΑ͏ @ikawaha ͞Μ http://ikawaha.hateblo.jp/entry/ 2016/09/11/095129 ͱͯ΋Θ͔Γ΍͍͢Ͱ͢ m(_ _)m

Slide 35

Slide 35 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠