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.5k
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
670
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
730
GCP Compute 概要と選定 / DevFest Tokyo 2018
vvakame
12
1.7k
GoでGraphQLサーバを立てるぞ! / Building GraphQL server by go
vvakame
15
4.8k
『Re:VIEW+CSS組版やっていき』を やった話とWebエンジニアが期待する未来 / CSS Publishinng for Web Developers
vvakame
3
9k
go.mercari.io/datastore はいいぞ! / go.mercari.io/datastore is pretty good!
vvakame
4
1.1k
Other Decks in Technology
See All in Technology
戦えるAIエージェントの作り方
iwiwi
22
11k
進化する大規模言語モデル評価: Swallowプロジェクトにおける実践と知見
chokkan
PRO
3
470
re:Invent 2025の見どころと便利アイテムをご紹介 / Highlights and Useful Items for re:Invent 2025
yuj1osm
0
690
文字列操作の達人になる ~ Kotlinの文字列の便利な世界 ~ - Kotlin fest 2025
tomorrowkey
2
490
AI-ready"のための"データ基盤 〜 LLMOpsで事業貢献するための基盤づくり
ismk
0
110
AIがコードを書いてくれるなら、新米エンジニアは何をする? / komekaigi2025
nkzn
25
17k
Giving Tuesday Auctria Set-Up 2025
auctria
PRO
0
100
[re:Inent2025事前勉強会(有志で開催)] re:Inventで見つけた人生をちょっと変えるコツ
sh_fk2
1
1.3k
SOTA競争から人間を超える画像認識へ
shinya7y
0
690
Amazon Q Developer CLIをClaude Codeから使うためのベストプラクティスを考えてみた
dar_kuma_san
0
340
Digitization部 紹介資料
sansan33
PRO
1
5.8k
DMMの検索システムをSolrからElasticCloudに移行した話
hmaa_ryo
0
370
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
97
6.3k
Mobile First: as difficult as doing things right
swwweet
225
10k
Docker and Python
trallard
46
3.6k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
Faster Mobile Websites
deanohume
310
31k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
253
22k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
36
6.1k
Making the Leap to Tech Lead
cromwellryan
135
9.6k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
10
910
The World Runs on Bad Software
bkeepers
PRO
72
11k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
Why You Should Never Use an ORM
jnunemaker
PRO
60
9.6k
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 ศར