Part2: Open API 를 사용하여 REST API 를 Mesh Gateway 에 연결

송톰톰·2023년 1월 23일
0
post-thumbnail

프로젝트 설정

프로젝트 디렉토리를 만들고 Go 모듈로 초기화 합니다.

$ mkdir rest_api
$ cd rest_api

OpenAPI Generator

GraphQL Mesh REST API 스키마를 통합하기 위해서는 OpenAPI 정의 파일이 필요합니다.

OpenAPI Genrator 를 설치 합니다.

$ brew install openapi-generator

GraphQL Mesh 예제에서 openapi3-definition.json 파일을 가져옵니다.

  • openapi3-definition.json
    • GET /books
    • GET /books/:id
    • GET /categories
{
  "openapi": "3.0.0",
  "paths": {
    "/books": {
      "get": {
        "operationId": "AppController_listBooks",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Book"
                  }
                }
              }
            }
          }
        },
        "tags": [
          "books"
        ]
      }
    },
    "/categories": {
      "get": {
        "operationId": "AppController_listBookCategories",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Category"
                  }
                }
              }
            }
          }
        },
        "tags": [
          "books"
        ]
      }
    },
    "/books/{id}": {
      "get": {
        "operationId": "AppController_findOne",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Book"
                }
              }
            }
          },
          "404": {
            "description": ""
          }
        },
        "tags": [
          "books"
        ]
      }
    }
  },
  "info": {
    "title": "Books service example",
    "description": "Everything about books",
    "version": "1.0",
    "contact": {}
  },
  "tags": [
    {
      "name": "books",
      "description": ""
    }
  ],
  "servers": [],
  "components": {
    "schemas": {
      "Book": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "1"
          },
          "authorId": {
            "type": "string",
            "example": "1"
          },
          "categorieId": {
            "type": "string",
            "example": "1"
          },
          "title": {
            "type": "string",
            "example": "Dune"
          }
        },
        "required": [
          "id",
          "authorId",
          "categorieId",
          "title"
        ]
      },
      "Category": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "1"
          },
          "name": {
            "type": "string",
            "example": "Fiction"
          }
        },
        "required": [
          "id",
          "name"
        ]
      }
    }
  }
}

OpenAPI Genrator 를 통해 파일을 생성합니다.

$ openapi-generator generate -i openapi3-definition.json -g go-gin-server

파일이 성공 적으로 생성된 경우:

.
├── Dockerfile
├── api
│   └── openapi.yaml
├── go
│   ├── README.md
│   ├── api_books.go
│   ├── model_book.go
│   ├── model_category.go
│   └── routers.go
├── go.mod
├── go.sum
├── main.go
└── openapi3-definition.json

OpenAPI Generator 가 생성한 main.gosw "./go" 코드에 에러가 발생합니다.

  • main.go
/*
 * Books service example
 *
 * Everything about books
 *
 * API version: 1.0
 * Generated by: OpenAPI Generator (https://openapi-generator.tech)
 */

package main

import (
	"log"

	// WARNING!
	// Change this to a fully-qualified import path
	// once you place this file into your project.
	// For example,
	//
	//sw "github.com/GIT_USER_ID/GIT_REPO_ID/go"
	//
	sw "./go" // Error
)

func main() {
	log.Printf("Server started")

	router := sw.NewRouter()

	log.Fatal(router.Run(":8080"))
}

go.mod 파일에 정의한 모듈 주소에 따라 수정합니다.

  • go.mod
module github.com/songtomtom/graphql-mesh-gateway/rest_api

또한 .meshrc.ymal 에서 정의한 포트 3002 로 수정합니다.

/*
 * Books service example
 *
 * Everything about books
 *
 * API version: 1.0
 * Generated by: OpenAPI Generator (https://openapi-generator.tech)
 */

package main

import (
	openapi "github.com/songtomtom/graphql-mesh-gateway/rest_api/go"
	"log"
)

func main() {
	log.Printf("Server started")
	router := openapi.NewRouter()
	log.Fatal(router.Run(":3002"))
}

REST API 서버가 정상적으로 동작하는지 확인합니다.

$ go run main.go
Server started
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /                         --> github.com/songtomtom/graphql-mesh-gateway/rest-api/go.Index (3 handlers)
[GIN-debug] GET    /books/:id                --> github.com/songtomtom/graphql-mesh-gateway/rest-api/go.AppControllerFindOne (3 handlers)
[GIN-debug] GET    /categories               --> github.com/songtomtom/graphql-mesh-gateway/rest-api/go.AppControllerListBookCategories (3 handlers)
[GIN-debug] GET    /books                    --> github.com/songtomtom/graphql-mesh-gateway/rest-api/go.AppControllerListBooks (3 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :3002

REST API 스키마 통합

REST API 서버 스키마를 통합 하려면 /mesh-gateway 프로젝트로 이동하여 @graphql-mesh/openapi 종속성을 추가하고 .meshrc.ymal 를 수정합니다.

$ yarn add @graphql-mesh/openapi
  • package.json
{
  "dependencies": {
    "@graphql-mesh/cli": "^0.82.11",
    "@graphql-mesh/openapi": "^0.35.7",
    "graphql": "^16.6.0"
  },
  "scripts": {
    "start": "mesh start",
    "build": "mesh build"
  }
}
  • .meshrc.yaml
sources:
  - name: Books
    handler:
      openapi:
        endpoint: http://localhost:3002/
        source: ../rest_api/openapi3-definition.json
#  - name: Authors
#    handler:
#      grpc:
#        endpoint: http://localhost:3003/
#  - name: Stores
#    handler:
#      graphql:
#        endpoint: http://localhost:3004/
serve:
  hostname: 0.0.0.0
  port: 80
  endpoint: /
  browser: false
  playground: true

mesh build 를 실행하여 REST API 스키마를 통합하고 mesh start 로 Mesh Gateway 를 실행합니다.

$ yarn start
yarn run v1.22.18
warning package.json: No license field
$ mesh start
💡 🕸️  Mesh - Server Starting GraphQL Mesh...
💡 🕸️  Mesh - Books Processing annotations for the execution layer
💡 🕸️  Mesh - Server Serving GraphQL Mesh: http://0.0.0.0:80

Books REST API를 GraphQL 스키마로 변환 한 것을 확인 할 수 있습니다.

  • GET /api/helloWorld -> helloWorld(): String!
  • POST /api/sayHelloAll -> sayHelloAll(input: [SayHelloAllInput]): String

Reference

Github

0개의 댓글