## [[oapi-codegen]]のインストール ```console go install github.com/deepmap/oapi-codegen/v2/cmd/oapi-codegen@latest ``` ## [[OpenAPI Specification]]の[[YAML]]作成 [[Reqres]]を使う。 <div class="link-card"> <div class="link-card-header"> <span class="link-card-site-name">reqres.in</span> </div> <div class="link-card-body"> <div class="link-card-content"> <div> <p class="link-card-title"> Reqres - A hosted REST-API ready to respond to your AJAX requests </p> </div> <div class="link-card-description"> A hosted REST-API ready to respond to your AJAX requests </div> </div> </div> <a href="https://reqres.in/"></a> </div> サイト内に[[Swagger]]へのリンクもあって素晴らしい! <div class="link-card"> <div class="link-card-header"> <img src="https://reqres.in/api-docs/favicon-32x32.png" class="link-card-site-icon"/> <span class="link-card-site-name">reqres.in</span> </div> <div class="link-card-body"> <div class="link-card-content"> <div> <p class="link-card-title">Swagger UI</p> </div> <div class="link-card-description"> </div> </div> </div> <a href="https://reqres.in/api-docs/"></a> </div> > [!question] どうしてREADMEのエンドポイントを使わないのか? > > READMEにも記載されていた[[OpenAPI Specification]]のリポジトリにあるサンプルはエンドポイントにアクセスできなかった... 今回利用する`/users`の部分だけ抽出して `openapi.yaml`として作成。 ```yaml openapi: 3.0.0 info: title: ReqRes API description: Fake data CRUD API version: "1" servers: - url: https://reqres.in/api components: schemas: User: type: object properties: id: type: integer email: type: string first_name: type: string last_name: type: string avatar: type: string paths: /users: get: summary: Fetches a user list parameters: - in: query name: page schema: type: integer - in: query name: per_page schema: type: integer responses: '200': description: Success content: application/json: schema: type: object properties: page: type: integer per_page: type: integer total: type: integer total_pages: type: integer data: type: array items: $ref: '#/components/schemas/User' ``` ## コードを生成 [[パッケージ (Go)|パッケージ]]は`api`なので、`api`ディレクトリを作成し、配下に配置する。 ```console mkdir api oapi-codegen -package api openapi.yaml > api/openapi.gen.go ``` `api/openapi.gen.go`にはimportエラーが含まれるので ```console go mod tidy ``` ## 自動生成されたコードを使って実装 以下のようなコードになる。 ```go package main import ( "context" "go-study/api" "net/http" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) func main() { e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.GET("/", hello) e.GET("/users", users) e.Logger.Fatal(e.Start(":1323")) } func hello(c echo.Context) error { return c.String(http.StatusOK, "Hello, World!") } // 今回重要なのはココ! func users(c echo.Context) error { client, err := api.NewClientWithResponses("https://reqres.in/api") if err != nil { return err } res, err := client.GetUsersWithResponse(context.TODO(), nil) if err != nil { return err } return c.JSON(http.StatusOK, res.JSON200) } ``` > [!caution] > `NewClient`の方はレスポンスが不要な場合に使うケース。レスポンスが必要な場合は`NewClientWithResponses`を使う必要がある。 ## 動作確認 サーバーを起動する。 ```console go run . ``` http://localhost:1323/users にアクセスして結果が返却されればOK。 ```console $ curl http://localhost:1323/users {"data":[{"avatar":"https://reqres.in/img/faces/1-image.jpg","email":"[email protected]","first_name":"George","id":1,"last_name":"Bluth"},{"avatar":"https://reqres.in/img/faces/2-image.jpg","email":"[email protected]","first_name":"Janet","id":2,"last_name":"Weaver"},{"avatar":"https://reqres.in/img/faces/3-image.jpg","email":"[email protected]","first_name":"Emma","id":3,"last_name":"Wong"},{"avatar":"https://reqres.in/img/faces/4-image.jpg","email":"[email protected]","first_name":"Eve","id":4,"last_name":"Holt"},{"avatar":"https://reqres.in/img/faces/5-image.jpg","email":"[email protected]","first_name":"Charles","id":5,"last_name":"Morris"},{"avatar":"https://reqres.in/img/faces/6-image.jpg","email":"[email protected]","first_name":"Tracey","id":6,"last_name":"Ramos"}],"page":1,"per_page":6,"total":12,"total_pages":2} ```