graphql-rest-proxy
Convert your REST server to GraphQL server.
Install
npm -g install graphql-rest-proxy
Or if you use Yarn:
yarn global add graphql-rest-proxy
Why
We all know GraphQL is great, so you want to move from REST API to GraphQL.
However, it requires a lot of effort to replace your current REST API with a brand new GraphQL server.
graphql-rest-proxy comes in to address this issue. It proxies GraphQL to REST API according to the defined schema.
Getting Started
STEP 1. Define your schema.
schema.graphql
type User { id: Int name: String isActive: Boolean } type Query { getUser: User @proxy(get: "https://my-rest-api.com/user") }
STEP 2. Run your proxy server.
graphql-rest-proxy schema.graphql
# => graphql-rest-proxy is running on http://localhost:5252STEP 3. Request!
curl -XPOST -H 'Content-Type: application/json' \ -d '{ "query": "{ getUser { id name isActive } }" }' \ http://localhost:5252/graphql
It will return like this:
{
"data": {
"getUser": {
"id": 1,
"name": "Tom",
"isActive": false
}
}
}Examples
Basic Query Proxy
type User { id: Int name: String } type Query { getUser: User @proxy(get: "https://my-rest-api.com/user") getUsers: [User] @proxy(get: "https://my-rest-api.com/users") }
Query with Parameters
You can refer the id of query args by ^id.
type User { id: Int name: String } type Query { getUserById(id: Int!): User @proxy(get: "https://my-rest-api.com/users/^id") }
Mutation with Input Parameters
Mutation forward variables to the REST API.
input UserInput { name: String! } type User { id: Int name: String } type Mutation { createUser(user: UserInput!): User @proxy(post: "https://my-rest-api.com/users") updateUser(id: Int!, user: UserInput!): User @proxy(patch: "https://my-rest-api.com/users/^id") }
Request example:
fetch('http://localhost:5252/graphql', { method: 'patch', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ query: gql` mutation UpdateUser($id: Int!, $user: UserInput!) { updateUser(id: $id, user: $user) { id name } } `, variables: { id: 1, user: { name: 'acro5piano', }, }, }), })
Nested Objects
You can refer the id of parent object by ^id.
type Post { id: Int title: String } type User { id: Int name: String posts: [Post] @proxy(get: "https://my-rest-api.com/users/^id/posts") } type Query { getUser: User @proxy(get: "https://my-rest-api.com/user") }
Specify base url
You can set base url to reduce verbosity:
graphql-rest-proxy --baseUrl https://my-rest-api.com schema.graphql
type Query { getUser: User @proxy(get: "/user") }
Configuration
CLI options are:
Usage: graphql-rest-proxy <command> [options]
Commands:
graphql-rest-proxy <file> Start graphql-rest-proxy server. [default]
graphql-rest-proxy print <file> Print GraphQL schema
Options:
--version Show version number [boolean]
-c, --config Specify config file
-p, --port Specify port
-b, --baseUrl Specify proxy base url
-h, --help Show help [boolean]
You can also set a config file.
proxy.config.js
module.exports = { baseUrl: 'https://myapi.com', port: 3000, }
And run with the configuration:
graphql-rest-proxy --config proxy.config.js schema.graphql
Notes
Request as less as possible
graphql-rest-proxy does not request if proxy response includes child object. This means you can reduce API call if you includes child object.
For example, if the schema is like this:
type Post { id: Int title: String } type User { id: Int name: String posts: [Post] @proxy(get: "https://my-rest-api.com/users/^id/posts") } type Query { getUser: User @proxy(get: "https://my-rest-api.com/user") }
And REST API returns like this:
curl https://my-rest-api.com/user
{
"id": 1,
"name": "acro5piano",
"posts": {
"id": 1,
"title": "graphql-rest-proxy"
}
}In this case, posts is embbed in response, so graphql-rest-proxy doesn't request to https://my-rest-api.com/users/1/posts.
Development Status
Still in Beta. If you have any suggestions or feature requests, feel free to open new issues or Pull Requests!
TODO:
- More type support
- Fragment
- Scalar
- Refactoring
- Logging

