Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Python用のマイクロサービスフレームワークを探す旅 / A journey to fin...

yukinagae
September 29, 2019

Python用のマイクロサービスフレームワークを探す旅 / A journey to find a microservices framework for Python

golangのGoa (https://goa.design/) のようなマイクロフレームワークに似たようなのをPythonでもほしいので、Nameko (https://www.nameko.io/) の拡張を作ってみました(`・ω・´)
repository: https://github.com/yukinagae/nameko-design

yukinagae

September 29, 2019
Tweet

More Decks by yukinagae

Other Decks in Technology

Transcript

  1. Goaとは? Goa is a Go framework for writing microservices that

    promotesbest practice by providing a single source of truth from which server code, client code, and documentation is derived. マイクロサービス用のフレームワーク コードからサーバサイドのスケルトンやドキュメント(swagger) を生成できる 4
  2. こんな感じのAPIデザインをgoで記述する var _ = Service("calc", func() { Method("add", func() {

    Payload(func() { Field(1, "a", Int, "Left operand") Field(2, "b", Int, "Right operand") Required("a", "b") }) Result(Int) HTTP(func() { GET("/add/{a}/{b}") }) GRPC(func() { }) }) }) 5
  3. 省略しているがいろいろ生成してくれる gen ├── calc │ └── *.go ├── grpc │

    ├── calc │ │ ├── client │ │ │ └── *.go │ │ ├── pb │ │ │ ├── calc.pb.go │ │ │ └── calc.proto # <- protobuffer │ │ └── server │ │ └── *.go │ └── cli │ └── calc │ └── cli.go └── http ├── calc ├── cli ├── openapi.json # <- swagger ファイル └── openapi.yaml # <- swagger ファイル 7
  4. 11

  5. Nameko(なめこ)の由来 Nameko takes its name from the Japanese mushroom, which

    grows in clusters. クラスタ(?)に成長する日本のキノコである "なめこ" が由来 13
  6. HTTPの場合 アノテーションで @http を指定 import json from nameko.web.handlers import http

    class HttpService: name = "http_service" @http('GET', '/get/<int:value>') def get_method(self, request, value): return json.dumps({'value': value}) 14
  7. gRPCの場合 アノテーションで @grpc を指定 grpc = Grpc.implementing(exampleStub) class GrpcService: name

    = "grpc_service" @grpc def stream_unary(self, request, context): messages = [] for req in request: message = req.value * (req.multiplier or 1) messages.append(message) return ExampleReply(message=",".join(messages)) ※ namekoのコアにはgRPCが入っていないが nameko‑grpc という拡張を 使用可能 15
  8. 使い方 HTTPサービスを起動 nameko run http_service curlで叩いてみる(`・ω・´) $ curl localhost:8000/get/123 {'value':

    123} ためしにサンプルプロジェクト作成した。 ただDBからselectするだけ(/・ω・)/ yukinagae/nameko‑api‑template 16
  9. 端的に地獄......( ˘ω˘)スヤァ service = Service('http_service') \ .Title('This is a http

    service') \ .Method('liveness') \ .Description('liveness probe') \ .Result(str) \ .HTTP(GET, '/liveness') service.generate() # コード生成 25
  10. Pythonicに書けるようにしたつもり このPythonファイルをスキーマとする with Service('http_service'): Title('This is a http service') with

    Method('liveness'): Description('liveness probe') Result(str) HTTP(GET, '/liveness') with Method('readiness'): Description('readiness probe') Result(str) HTTP(GET, '/readiness') 26
  11. これを生成(`・ω・´) from nameko.web.handlers import http class HttpService: name = 'http

    service' @http('GET', '/liveness') def liveness(self, request) -> str: pass @http('GET', '/readiness') def readiness(self, request) -> str: pass 28
  12. まだTODOたくさんあるけれど Configure http url and port Add URL parameter and

    type Add payload (name, type, description, position etc) Add validation Add gRPC server Generate proto files Generate swagger json 29
  13. こんな感じでできたらよさそう(´∀` ) with Service('example_service'): Title('This is an example service') with

    Method('liveness'): Description('liveness probe') Result(str) HTTP(GET, '/liveness') with Method('add'): Description('a + b') with Payload(): Field(1, "a", int, "left operand") Field(2, "b", int, "right operand") Required("a", "b") Result(int) HTTP(GET, '/add/{a}/{b}') GRPC() 30