でのマイクロサービスの構築:REST API



どのようなswaggerですか?OpenAPI ?
Swagger/OpenAPIを使用すると、ドキュメントを作成し、ユーザーと協力することができます、具体的には、リソース、パラメータ、種類、フィールド、および我々が構築しているAPIを記述するすべてを定義することができます.SwaggerとOpenAPIは2つの異なるものですthe original blog post , しかし、この考えは基本的にこうです.

  • OpenAPI :仕様

  • Swagger:仕様を実装するためのツール
  • Disclaimer: This post includes Amazon affiliate links. If you click on one of them and you make a purchase I'll earn a commission. Please notice your final price is not affected at all by using those links.

    The code used for this post is available on Github.



    OpenAPI 3の実装
    のようなパッケージによってサポートされるのはよく知られているswaggergithub.com/go-swagger/go-swagger and github.com/swaggo/swag しかし、OpenAPI 3のような最新のものを使おうとすると、もっと複雑になります.

  • github.com/getkin/kin-openapi/openapi3 : OpenAPI 3.0ドキュメントを生成するには

  • github.com/deepmap/oapi-codegen : OpenAPI 3仕様からGoクライアントとサーバーBoilerPlateを生成します.
  • OpenAPI 3.0ドキュメントを生成するには、getkin/kin-openapi/openapi3 パッケージの例を示しますa function that does that for us .
    この機能は長いです、そして、それは多くの人々のためにターンオフすることができました、しかし、私はそれが私が私が必要とする値を明示的に示すのを許すので、それが方法であるのが好きですgo-swagger or swagger/swag たとえば、それはあなたがそれを見る方法に応じてプロ/コンンだ.すべてがよりマニュアルだから.
    最後に、APIを表現するために必要なコードは、その構造を構築するために書かれたコードと等価です.たとえば、基本的なOpenAPIの詳細を見ると、次のようになります.
    // NewOpenAPI3 instantiates the OpenAPI specification for this service.
    func NewOpenAPI3() openapi3.Swagger {
        swagger := openapi3.Swagger{
            OpenAPI: "3.0.0",
            Info: &openapi3.Info{
                Title:       "ToDo API",
                Description: "REST APIs used for interacting with the ToDo Service",
                Version:     "0.0.0",
                License: &openapi3.License{
                    Name: "MIT",
                    URL:  "https://opensource.org/licenses/MIT",
                },
                Contact: &openapi3.Contact{
                    URL: "https://github.com/MarioCarrion/todo-api-microservice-example",
                },
            },
            Servers: openapi3.Servers{
                &openapi3.Server{
                    Description: "Local development",
                    URL:         "http://0.0.0.0:9234",
                },
            },
        }
    
        // ... more code ...
    
    を指定すると、helper binary コール go generate YAMLとJSONファイルをビルドするには、APIを記述する必要があります.
    実際、そのコードはcmd/openapi-gen/main.go 基本的にこのように見えます.
    func main() {
        swagger := rest.NewOpenAPI3()
    
        // openapi3.json
        data, _ := json.Marshal(&swagger)
    
        _ = os.WriteFile(path.Join(output, "openapi3.json"), data, 0644) // XXX: explicitly ignoring errors
    
        // openapi3.yaml
        data, _ = yaml.Marshal(&swagger)
    
        _ = os.WriteFile(path.Join(output, "openapi3.yaml"), data, 0644) // XXX: explicitly ignoring errors
    }
    
    最後に、それらを作ることですfiles available :
    func RegisterOpenAPI(r *mux.Router) {
        swagger := NewOpenAPI3()
    
        r.HandleFunc("/openapi3.json", func(w http.ResponseWriter, r *http.Request) {
            // ... code here ...
        }).Methods(http.MethodGet)
    
        r.HandleFunc("/openapi3.yaml", func(w http.ResponseWriter, r *http.Request) {
            // ... code here ...
        }).Methods(http.MethodGet)
    }
    

    swagger UIの実装
    我々はOpenAPI 3ファイルを構築しました.そして、現在我々のHTTPハンドラーの一部として我々がユーザーと対話するのを許すつもりですSwagger UI APIを起動するには、これは何かをするか、または生産する必要はありませんが、私は個人的にのみ、内部環境をテストする目的のために、このUIをサポートできるようになります.
    swagger UIをサポートするために、我々のすべてのAPIをダウンロードする必要があります dist files オリジナルのリポジトリから、新しいハンドラとしてAPIの一部として埋め込む cmd/rest-server/static/swagger-ui , を使って、embed 次のようにしてgo 1.16に含まれています.
    //go:embed static
    var content embed.FS
    
    
    func main() {
        // ... other code ...
    
        r := mux.NewRouter()
    
        fsys, _ := fs.Sub(content, "static")
        r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.FS(fsys))))
    
        srv := &http.Server{
            Handler: r,
            // ... other code ...
        }
    
        log.Fatal(srv.ListenAndServe())
    }
    
    そのコードで、我々は要求することができますhttp://address:port/static/swagger-ui そして、以前に生成されたOpenAPI 3ファイルを使用してAPIをロードします.変更するには本当に重要なことがあります index.html file 地域を参照するopenapi3.json ファイルと環境に応じてファイルを生成したい場合は、常に正しいHTTP URLを指します.

    クライアントの生成とOpenAPI 3からのコードの提供
    OpenAPI 3ドキュメントを生成した後にできる別の興味深いことは、元のAPIに合ったGo型を表すBoilerPlateを生成することです.github.com/deepmap/oapi-codegen . これは次のようになります.
    発電機をインストールします.
    go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.5.1
    
    その後go generate 生成時our types :
    //go:generate oapi-codegen -package openapi3 -generate types  -o ../../pkg/openapi3/task_types.gen.go openapi3.yaml
    //go:generate oapi-codegen -package openapi3 -generate client -o ../../pkg/openapi3/client.gen.go     openapi3.yaml
    
    この例では、pkg パッケージは、プログラムのようにいくつかのコードを構築するために使用することができますAPIとの対話のようなfollowing example :
    func main() {
        client, _ := openapi3.NewClientWithResponses("http://0.0.0.0:9234") // XXX: explicitly ignoring errors
    
        priority := openapi3.Priority_low
    
        respC, _ := client.CreateTaskWithResponse(context.Background(), // XXX: explicitly ignoring errors
            openapi3.CreateTaskJSONRequestBody{
                Dates: &openapi3.Dates{
                    Start: newPtrTime(time.Now()),
                    Due:   newPtrTime(time.Now().Add(time.Hour * 24)),
                },
                Description: newPtrStr("Sleep early"),
                Priority:    &priority,
            })
    
        // ... other code ...
    

    別れの言葉
    Swagger 2.0を使用したGoの残りのAPIを比較するのは比較的よくサポートされていて、簡単に行うことができますが、いくつかの異なる選択肢がありますが、あなたが持っているかもしれないのは、OpenAPI 3のような最新の選択肢を探索したいなら、すでに古くなっている技術に依存しているということです.これは長期的な解決策を探している人々のための公正な懸念です.
    それでは、最善のアプローチは何ですか?私はそれを参照してください場合は、リソースを投資していない場合は、新しい最先端のツールを試してswaggerしかし、OpenAPI 3を探索しているコミュニティに貢献する気があるならば、オプションはよりよいです.

    推奨読書
    あなたがあなたの歯をより多くの休みとウェブプログラミングに沈めるのを見ているならば、私は以下の本を推薦します:
  • The Design of Web APIs (2019)
  • Irresistible APIs (2016)
  • Go Web Programming (2016)
  • REST in Practice (2010)