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
How to Quickly Call American Airlines®️ U.S. Customer Care : Full Guide
flyaahelpguide
0
240
ゼロから始めるSREの事業貢献 - 生成AI時代のSRE成長戦略と実践 / Starting SRE from Day One
shinyorke
PRO
0
110
「Chatwork」のEKS環境を支えるhelmfileを使用したマニフェスト管理術
hanayo04
1
400
振り返りTransit Gateway ~VPCをいい感じでつなげるために~
masakiokuda
3
210
大量配信システムにおけるSLOの実践:「見えない」信頼性をSLOで可視化
plaidtech
PRO
0
390
衛星運用をソフトウェアエンジニアに依頼したときにできあがるもの
sankichi92
1
1k
対話型音声AIアプリケーションの信頼性向上の取り組み
ivry_presentationmaterials
3
1k
TLSから見るSREの未来
atpons
2
310
Talk to Someone At Delta Airlines™️ USA Contact Numbers
travelcarecenter
0
160
VS CodeとGitHub Copilotで爆速開発!アップデートの波に乗るおさらい会 / Rapid Development with VS Code and GitHub Copilot: Catch the Latest Wave
yamachu
3
460
shake-upを科学する
rsakata
7
1k
ABEMAの本番環境負荷試験への挑戦
mk2taiga
5
1.3k
Featured
See All Featured
YesSQL, Process and Tooling at Scale
rocio
173
14k
A Tale of Four Properties
chriscoyier
160
23k
Agile that works and the tools we love
rasmusluckow
329
21k
The Straight Up "How To Draw Better" Workshop
denniskardys
235
140k
Writing Fast Ruby
sferik
628
62k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
22k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
A Modern Web Designer's Workflow
chriscoyier
695
190k
Java REST API Framework Comparison - PWX 2021
mraible
31
8.7k
Optimising Largest Contentful Paint
csswizardry
37
3.3k
Thoughts on Productivity
jonyablonski
69
4.7k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
520
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 ศར