Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ucon-ajn33
Search
Masahiro Wakame
June 08, 2016
Technology
1.5k
3
Share
ucon-ajn33
いかにCloudEndpointsをやめSwaggerを愛するようになったか ajn #33
http://gcpja.connpass.com/event/30761/
Masahiro Wakame
June 08, 2016
More Decks by Masahiro Wakame
See All by Masahiro Wakame
社内フレームワークとその依存性解決 / in-house framework and its dependency management
vvakame
1
750
DatastoreからSpannerに 移行したいぞ途中編 / migrate Datastore to Spanner in progress
vvakame
0
1.3k
Google Cloud Next 2019 わくわく報告会 / Google Cloud Next 2019 WakuWaku Report
vvakame
1
450
メルカリ社員100人に聞いたGoLandの使い方 / JetBrains Night Tokyo 2018
vvakame
27
13k
OSS入門 世界に参加する最初のひと押し / OSS first step
vvakame
7
770
GCP Compute 概要と選定 / DevFest Tokyo 2018
vvakame
13
1.7k
GoでGraphQLサーバを立てるぞ! / Building GraphQL server by go
vvakame
15
4.9k
『Re:VIEW+CSS組版やっていき』を やった話とWebエンジニアが期待する未来 / CSS Publishinng for Web Developers
vvakame
3
9.2k
go.mercari.io/datastore はいいぞ! / go.mercari.io/datastore is pretty good!
vvakame
4
1.2k
Other Decks in Technology
See All in Technology
APIテストとは?
nagix
0
130
Harnessing the Power of Mocks and Stubs in PHPUnit / #laravellivejp
asumikam
0
730
20260528_生成AIを専属DSに_Howの次にすべきことを考える
doradora09
PRO
0
240
Copilot CLI・IDE・Web・スマホで途切れない開発フローを目指して / One Copilot flow - CLI IDE Web Mobile
aeonpeople
1
1.1k
組織の中で自分を経営する技術
shoota
0
200
Fabric-cicd によるAzure DevOps デプロイ
ryomaru0825
0
110
Typiaで配信JSONの安全性を構造的に担保する(TSKaigi2026)
righttouch
PRO
1
190
コードレビューを制するチームがソフトウェアデリバリーのフローを制す / Beyond Code Review: Distributing Its Responsibilities Across the SDLC
mtx2s
1
190
さきさん文庫の書籍ができるまで
sakiengineer
0
290
Datadog 認定試験の概要と対策
uechishingo
0
150
ビジュアルプログラミングIoTLT vol.23
1ftseabass
PRO
0
150
freee-mcpを Local→Remote で出してわかった MCP認可実装のリアル
terara
3
910
Featured
See All Featured
RailsConf 2023
tenderlove
30
1.4k
The Curse of the Amulet
leimatthew05
1
12k
GitHub's CSS Performance
jonrohan
1033
470k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
The Cult of Friendly URLs
andyhume
79
6.9k
Embracing the Ebb and Flow
colly
88
5.1k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
[SF Ruby Conf 2025] Rails X
palkan
2
1.1k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
400
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
240
Code Reviewing Like a Champion
maltzj
528
40k
Transcript
͍͔ʹCloudEndpointsΛΊ SwaggerΛѪ͢ΔΑ͏ʹͳ͔ͬͨ Θ͔Ί ·͞ͻΖ
Θ͔Ί ·͞ͻΖ @v vakame TypeScript Masahiro Wakame DefinitelyTyped appengine/go photo
from golang.org/doc/gopher/
Google API Discovery Service ୭͔ͬͯΔʁ
APIs Explorer is ਆ https://developers.google.com/apis-explorer/
APIs Explorer • ୭Ͱ؆୯ʹ͑Δ • ࣮ࡍͷAPI͕ୟ͔ΕΔ • ݁ՌΛڞ༗͍͢͠ • ίʔυ͔ΒUI͕ੜ͞Ε͍ͯΔ
• ίʔυ == CloudEndpoints CloudEndpoints→APIs Explorer
but…
GoogleͷҋͷྖҬ Ϣʔβ GAE ҋ path mapping request format VersionସޙreqΛͳ͔ͬͨࣄʹ custom
domainෆՄ go-endpoints͕ͨ·ʹͭΒ͍
Swagger ͦ͜ͰSwaggerͰ͢Α
✨swagger✨ • Swagger͕Ұ൪ྑͦ͞͏ʂ • RAML, JSON Schema etc… • Open
API Initiativeൃ • Swagger༷Λbaseʹ • ͍ͷʹר͔Ε͍ͨ • Qiitaʹൺֱ·ͱΊ goo.gl/BLS3uH
ucon࡞Δ طଘ࣮ௐ͚ͨͲ ࣗͰ࡞Δ͜ͱʹͨ͠ https://github.com/favclip/ucon
લఏ • appengineറΓʹ͠ͳ͍ • ͱ͍͑appengineͰ͑ͳ͍ͱࠔΔ • net/httpʹ͍ۙAPI • ॊೈੑ •
go-endpointsͱͷޓੑ • swaggeropt-in ͍ͬͯ͘
໊͚ a2c͞Μ uconͱ ໊͚Α͏ʂ
ܾΊͨޙ a2c͞Μ ←ΏΔ͞ͳ͍
ಈ͘σϞ ؒʹ߹Θͳ͍͔ͱࢥͬͨΒ ͍ͭͷؒʹ͔ͬͯ͋ͬͨ
TODO • github.com/vvakame/ucon-todo • ucon-todo.appspot.com/ • ucon-todo.appspot.com/swagger-ui/ • ࣭ૉ ಈ͘ʂ
ར༻ࣄྫ
ར༻αΠτ • favclip • ٕज़ॻయ • TopgateࣾͰࠓޙ͍ͬͯͣ͘…
༷հ
ucon Features • net/http ͱͷྨࣅੑ • Routing • Method, Path
Matching • Middleware • Bubble • Dependency Injection • Plugin
API likes net/http ucon.HandleFunc("GET", "/", func(w http.ResponseWriter, r *http.Request) {})
API likes net/http ucon.HandleFunc("GET", "/", func(w http.ResponseWriter, r *http.Request) {})
Routing ucon.HandleFunc(“*", “/“, … ucon.HandleFunc(“OPTIONS", “/“, … ucon.HandleFunc(“GET", “/“, …
ucon.HandleFunc(“POST", “/“, … ucon.HandleFunc(“GET", “/api/user“, … ucon.HandleFunc(“GET", “/api/user/me“, … ucon.HandleFunc(“GET", “/api/user/{id}“, …
Routing rule • METHOD͕Ұக͢Δ • * ࢦఆՄ ݫີҰக༏ઌ • Request
Path͕Ұக͢Δ • ෳީิ͋Δ߹ΑΓ͍અҰக • Request GET /api/user/123 • GET /api/user/{id} • ❌ GET /api/user • ઌొ༏ઌ
Middleware • 1 requestຖͷॲཧʹհೖ • JavaͰ͍͏ServletFilter • ASP.NET MVCͰ͍͏Filter •
Logging, DI, CORS༻Header, error→JSONม etc, etc…
Middleware Middleware Middleware Middleware Handler ServeHTTP DI Cache-Control Cookie appengine.Context
etc, etc… CORS Header Path, Query, Body → JSON *http.Request http.ResponseWriter
Middleware type MiddlewareFunc func(b *Bubble) error type Bubble struct {
R *http.Request W http.ResponseWriter Context context.Context RequestHandler interface{} ArgumentTypes []reflect.Type Arguments []reflect.Value Returns []reflect.Value } func (b *Bubble) Next() error { … } func (b *Bubble) do() error { hv := reflect.ValueOf(b.handler()) … b.Returns = hv.Call(b.Arguments) return nil } var httpReqType = reflect.TypeOf((*http.Request)( var httpRespType = reflect.TypeOf((*http.Response func HTTPRWDI() MiddlewareFunc { return func(b *Bubble) error { for idx, argT := range b.ArgumentTypes { if argT == httpReqType { b.Arguments[idx] = reflect.ValueOf(b.R) continue } if argT == httpRespType { b.Arguments[idx] = reflect.ValueOf(b.W) continue } } return b.Next() } }
built-in middleware • HTTPRWDI • *http.Request, http.ResponseWriterͷDI • NetContextDI •
net/contextͷContextΛDI
built-in middleware • RequestObjectMapper • path parameter, query paramter, post
bodyΛObjectʹม͠DI • ResponseMapper • Handler͕returnͨ͠ObjecterrorΛ JSONʹม
Plugin • ϓϩηεىಈ࣌1ճ͚ͩಈ࡞ • શHandlerͷࠪ • Handler→Pluginؒͷͷୡػߏ • swaggerplugin •
શHandlerͷใ͔Βॲཧ • swagger.jsonग़ྗ༻HandlerͷՃ
Plugin type pluginContainer struct { base interface{} } type
HandlersScannerPlugin interface { HandlersScannerProcess(m *ServeMux, rds []*RouteDefinition) error } type RouteDefinition struct { Method string PathTemplate *PathTemplate HandlerContainer HandlerContainer } func (m *ServeMux) Prepare() { for _, plugin := range m.plugins { used := false if sc := plugin.HandlersScanner(); sc != nil { err := sc.HandlersScannerProcess(m, m.router.handlers) if err != nil { panic(err) } used = true } if !used { panic(fmt.Sprintf("unused plugin: %#v", plugin)) } } }
Plugin type pluginContainer struct { base interface{} } type
HandlersScannerPlugin interface { HandlersScannerProcess(m *ServeMux, rds []*RouteDefinition) error } type RouteDefinition struct { Method string PathTemplate *PathTemplate HandlerContainer HandlerContainer } func (m *ServeMux) Prepare() { for _, plugin := range m.plugins { used := false if sc := plugin.HandlersScanner(); sc != nil { err := sc.HandlersScannerProcess(m, m.router.handlers) if err != nil { panic(err) } used = true } if !used { panic(fmt.Sprintf("unused plugin: %#v", plugin)) } } }
swagger plugin usage swPlugin := swagger.NewPlugin(…) ucon.Plugin(swPlugin) s := &fooService{}
tag := swPlugin.AddTag(&swagger.Tag{Name: "Foo", Description: ""}) var info *swagger.HandlerInfo info = swagger.NewHandlerInfo(s.List) ucon.Handle("GET", "/api/foo/{id}", info) info.Description, info.Tags = "FooΛ1݅औಘ͢Δ", []string{tag.Name} … type IntIDRequest struct { ID int64 `json:"id,string"` } func (s *fooService) Get(r *http.Request, req *IntIDRequest) (*FooJSON, error) { … }
swagger plugin usage swPlugin := swagger.NewPlugin(…) ucon.Plugin(swPlugin) s := &fooService{}
tag := swPlugin.AddTag(&swagger.Tag{Name: "Foo", Description: ""}) var info *swagger.HandlerInfo info = swagger.NewHandlerInfo(s.List) ucon.Handle("GET", "/api/foo/{id}", info) info.Description, info.Tags = "FooΛ1݅औಘ͢Δ", []string{tag.Name} … type IntIDRequest struct { ID int64 `json:"id,string"` } func (s *fooService) Get(r *http.Request, req *IntIDRequest) (*FooJSON, error) { … } go-endpointsͱͷޓੑ!
ίʔυنͷ • ຊମ 1339ߦ • ls | grep .go |
grep -v _test.go | xargs wc -l • swaggerϓϥάΠϯ 1138ߦ • find ./swagger -type f | grep .go | grep -v sample | grep -v _test.go | xargs wc -l
એ
6/25 () 11:00ʙ17:00 ळ༿ݪ ௨ӡձؗ ٕज़ॻΦϯϦʔଈചձ ݸਓ੍࡞ͷٕज़ॻ✕56ஂମ techbookfest.org
ࣗલϥΠϒϥϦհ ͬͯΈͯͶʂ
GAE༻ϥΠϒϥϦ࡞ͬͯ·͢ • testerator github.com/favclip/testrator • UnitTestߴԽ • qbg github.com/favclip/qbg •
Datastore༻TypeSafeΫΤϦϏϧμ • smg github.com/favclip/smg • Search API༻TypeSafeϥού productionͰར༻தʂ
ͦͷଞϥΠϒϥϦ࡞ͬͯ·͢ • jwg github.com/favclip/jwg • JSON༻ͷTagͱ͔ࣗಈͰΔͭଞ • golidator github.com/favclip/golidator •
Validator ศར