프로젝트 디렉토리를 만들고 Go 모듈로 초기화 합니다.
$ mkdir rest_api
$ cd rest_api
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.go
는 sw "./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 서버 스키마를 통합 하려면 /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