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
3
1.4k
ucon-ajn33
いかにCloudEndpointsをやめSwaggerを愛するようになったか ajn #33
http://gcpja.connpass.com/event/30761/
Masahiro Wakame
June 08, 2016
Tweet
Share
More Decks by Masahiro Wakame
See All by Masahiro Wakame
社内フレームワークとその依存性解決 / in-house framework and its dependency management
vvakame
1
630
DatastoreからSpannerに 移行したいぞ途中編 / migrate Datastore to Spanner in progress
vvakame
0
1.1k
Google Cloud Next 2019 わくわく報告会 / Google Cloud Next 2019 WakuWaku Report
vvakame
1
430
メルカリ社員100人に聞いたGoLandの使い方 / JetBrains Night Tokyo 2018
vvakame
27
13k
OSS入門 世界に参加する最初のひと押し / OSS first step
vvakame
7
720
GCP Compute 概要と選定 / DevFest Tokyo 2018
vvakame
12
1.6k
GoでGraphQLサーバを立てるぞ! / Building GraphQL server by go
vvakame
15
4.7k
『Re:VIEW+CSS組版やっていき』を やった話とWebエンジニアが期待する未来 / CSS Publishinng for Web Developers
vvakame
3
8.9k
go.mercari.io/datastore はいいぞ! / go.mercari.io/datastore is pretty good!
vvakame
4
1.1k
Other Decks in Technology
See All in Technology
CSS、JSをHTMLテンプレートにまとめるフロントエンド戦略
d120145
0
210
菸酒生在 LINE Taiwan 的後端雙刀流
line_developers_tw
PRO
0
1.1k
Clineを含めたAIエージェントを 大規模組織に導入し、投資対効果を考える / Introducing AI agents into your organization
i35_267
4
1.4k
Oracle Audit Vault and Database Firewall 20 概要
oracle4engineer
PRO
2
1.6k
LinkX_GitHubを基点にした_AI時代のプロジェクトマネジメント.pdf
iotcomjpadmin
0
160
Snowflake Summit 2025全体振り返り / Snowflake Summit 2025 Overall Review
mtpooh
2
200
A2Aのクライアントを自作する
rynsuke
1
150
Definition of Done
kawaguti
PRO
6
460
原則から考える保守しやすいComposable関数設計
moriatsushi
3
500
Абьюзим random_bytes(). Фёдор Кулаков, разработчик Lamoda Tech
lamodatech
0
270
2025/6/21 日本学術会議公開シンポジウム発表資料
keisuke198619
2
470
ローカルLLMでファインチューニング
knishioka
0
120
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.4k
Navigating Team Friction
lara
187
15k
The Invisible Side of Design
smashingmag
299
51k
Optimizing for Happiness
mojombo
379
70k
The Cult of Friendly URLs
andyhume
79
6.4k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
Speed Design
sergeychernyshev
31
1k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
660
Six Lessons from altMBA
skipperchong
28
3.8k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.2k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
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 ศར