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
Go-Swagger в продуктиве
Search
Ilya Kaznacheev
May 30, 2020
Programming
510
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Go-Swagger в продуктиве
Ilya Kaznacheev
May 30, 2020
More Decks by Ilya Kaznacheev
See All by Ilya Kaznacheev
Road to four nines
dreamworm
0
28
Many Layers of Availability
dreamworm
0
100
Stateful Solutions: A Hands-On Guide to FSM in Golang
dreamworm
0
210
CQRS
dreamworm
0
180
Building a Cloud-Native PaaS
dreamworm
0
160
Distributed System State Management: When Transactions Are Long and SLA Is High
dreamworm
0
150
How To Create Saga-Free Distributed Transactions
dreamworm
0
79
Architectural decisions in building distributed systems
dreamworm
0
42
Распределенные транзакции без саг
dreamworm
0
210
Other Decks in Programming
See All in Programming
AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策
tnagao7
0
110
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
270
「エンジニアインターン、どうやって取った?」準備のリアルを語るLT会 Progate BAR
akiomatic
0
140
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
350
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
160
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
11
5.8k
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
120
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
560
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
130
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
150
JavaDoc 再入門
nagise
1
370
DynamoDBには集計系のクエリがないけどなんとかしたい
musan
1
180
Featured
See All Featured
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.4k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Tell your own story through comics
letsgokoyo
1
960
The Invisible Side of Design
smashingmag
302
52k
Marketing to machines
jonoalderson
1
5.5k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
340
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
440
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
410
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
1.1k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Designing for humans not robots
tammielis
254
26k
Transcript
Go-Swagger в продуктиве взлеты и падения
Илья Казначеев Remote Backend SWE Основатель Golang Voronezh Ведущий подкаста
Z-Namespace Организатор конференций и митапов Любитель кофе
Golang Voronezh - ~30 активных участников - митапы - мероприятия
для новичков - открыто и дружелюбно t.me/golang_vrn meetup.com/Golang-Voronezh
что такое swagger?
None
SOAP JSON-PRC GraphQL gRPC OData REST
Representational state transfer (REST) is a software architectural style that
defines a set of constraints to be used for creating Web services Wikipedia
None
swagger: "2.0" info: title: Pet API version: "1.0.0" basePath: /api
schemes: - http paths: /pets: get: summary: List all pets parameters: - name: limit in: query description: "How many items to return at one time" required: true type: integer responses: 200: description: an paged array of pets 400: description: unexpected error
None
None
почему мы используем swagger?
команда синхронизирует изменения в API...
None
библиотеки go-swagger/go-swagger ✭ 5.2 K swaggo/swag ✭ 2.7 K deepmap/oapi-codegen
✭ 440 … grpc-ecosystem/grpc-gateway ✭ 8.5 K
go-swagger
генерация кода swagger generate server -t internal/api --exclude-main
структура сгенерированных файлов internal/api ├ models │ └ ... └
restapi ├ operations │ └ ... ├ configure_<your_service_name>.go ├ doc.go ├ embedded_spec.go └ server.go
как мы генерируем код rm -rf internal/api && mkdir -p
internal/api swagger generate server -t internal/api --exclude-main go mod tidy
? вроде все просто
НЕТ
есть некоторые проблемы - go-swagger - это фреймворк, а не
библиотека - куча сгенерированных типов на каждый чих - несовместим с популярными http библиотеками
давайте фиксить!
net/http хендлеры type CustomResponder func(http.ResponseWriter, runtime.Producer) func (c CustomResponder) WriteResponse(w
http.ResponseWriter, p runtime.Producer) { c(w, p) } func MetricsHandler(p instruments.GetMetricsParams) middleware.Responder { return CustomResponder(func(w http.ResponseWriter, _ runtime.Producer) { promhttp.Handler().ServeHTTP(w, p.HTTPRequest) }) }
простые middleware api := operations.NewSwaggerPetstoreAPI(swaggerSpec) api.InstrumentsGetMetricsHandler = instruments.GetMetricsHandlerFunc(MetricsHandler) api.AddMiddlewareFor("GET", "/metrics",
SomeMiddleware) srv := restapi.NewServer(api) srv.Serve()
middleware с кастомным хендлером h := api.Serve(nil) r := chi.NewRouter()
r.Use( middleware.Recoverer, ) r.With(AuthMiddleware).Group(func(r chi.Router) { r.Handle("/user/*", h) }) r.Mount("/", h) srv.ConfigureAPI() srv.SetHandler(r) srv.Serve()
настройки вне configure_<your_service_name>.go api.Logger = log.Printf api.HTMLProducer = runtime.TextProducer() srv
:= restapi.NewServer(api) srv.EnabledListeners = []string{"http"} srv.Port = conf.HTTPPort srv.Host = conf.HTTPAddr
кастомные имена методов /store/order/{orderId}/items: get: tags: - store summary: Find
purchase order items parameters: - name: orderId in: path required: true type: integer func GetOrderItems( param store.GetStoreOrderOrderIDItemsParams, ) middleware.Responder { items, err := getOrderItems(param.OrderID) if err != nil { return store.NewGetStoreOrderOrderIDItemsNotFound() } res := &models.OrderItems{} // // fill resopnse // return store.NewGetStoreOrderOrderIDItemsOK(). WithPayload(res) }
кастомные имена методов /store/order/{orderId}/items: get: tags: - store summary: Find
purchase order items operationId: getOrderItems parameters: - name: orderId in: path required: true type: integer func GetOrderItems( param store.GetOrderItemsParams, ) middleware.Responder { items, err := getOrderItems(param.OrderID) if err != nil { return store.NewGetOrderItemsNotFound() } res := &models.OrderItems{} // // fill resopnse // return store.NewGetOrderItemsOK(). WithPayload(res) }
встроенная валидация OrderItems: type: object properties: message: type: string maximum:
3 # swg/internal/api/models internal/api/models/order_items.go:45:55: cannot convert m.Message (type string) to type float64
шпаргалка по валидации numbers and integers - multipleOf - maximum
- minimum - exclusiveMaximum - exclusiveMinimum strings - maxLength - minLength - pattern arrays - maxItems - minItems - uniqueItems - maxContains - minContains objects - maxProperties - minProperties - required - dependentRequired any type - type - enum - const
расширения (костыли) x-omitempty x-nullable x-isnullable x-order x-go-custom-tag x-schemes x-go-name x-go-type
x-go-json-string x-go-enum-ci
юнит-тесты func GetOrderByID(param store.GetOrderByIDParams) middleware.Responder { order := models.Order{ ID:
123, PetID: 456, Quantity: 20, Status: "approved", } if param.OrderID != order.ID { return store.NewGetOrderByIDNotFound().WithPayload(&models.ErrorMessage{ Code: http.StatusNotFound, Message: http.StatusText(http.StatusNotFound), }) } return store.NewGetOrderByIDOK().WithPayload(&order) }
юнит-тесты tests := []struct { name string req store.GetOrderByIDParams code
int want string }{ { name: "good test", req: store.GetOrderByIDParams{OrderID: 123}, code: 200, want: `{"id":123,"petId":456,"quantity":20,"status":"approved"}`, }, { name: "bad test", req: store.GetOrderByIDParams{OrderID: 456}, code: 404, want: `{"message":"Not Found", "code":404}`, }, }
юнит-тесты for _, tt := range tests { t.Run(tt.name, func(t
*testing.T) { rr := httptest.NewRecorder() GetOrderByID(tt.req).WriteResponse(rr, runtime.JSONProducer()) assert.JSONEq(t, tt.want, rr.Body.String(), "wrong response body") assert.Equal(t, tt.code, rr.Code, "wrong response code") }) }
None
полезные ссылки json-schema.org/specification.html swagger.io/docs/specification/2-0 goswagger.io bit.ly/go-swagger-in-production
бонус A pluggable go-swagger (in development) github.com/ilyakaznacheev/go-plugger
бонус 2 Insomnia Designer insomnia.rest/products/designer
None
ilyakaznacheev