A cli tool to transform RESTful API to GraphQL with one js config file.
Global install:
npm i -g rest2graphql
Local install:
npm i -D rest2graphql
Write your RESTful API server, or you already have got one.
Write the GraphQL Schema file, each rest api maps to one Query/Mutation field.
Choosing between
Query/Mutationisn't important, just semantic difference. Or maybe some idempotence difference on other community tools.
Write the config file, maps those field resolver to rest api queries sent by axios.
Copy the config file in the example is smart. 😉
Run it: rest2graphql config.js or shorter r2g config.js.
/** @type {import('../src/index').Config} */
// if you install `rest2graphql` locally, you can take advantage of its type with the first line
module.exports = {
debug: true, // defaults to `process.env.NODE_ENV !== 'production'`, and maybe future logging operations
port: 3000,
// serve static files
// it's `koa-send` options plus `path`(defaults to '') and `historyApiFallback`(defaults to true if index is set)
// or just a string act as root
// and we can serve multiple directories with an array
serve: {
root: 'demo',
index: 'index.html',
},
// `http-middleware-proxy` parameters array
proxy: [
[
"/api",
{
target: "http://127.0.0.1:4000",
pathRewrite: { '^/api': '' }
}
]
],
axios: {
// `axios-logger` global config: https://github.com/hg-pyun/axios-logger
logger: {},
// `config.axios.interceptors` is just:
// `Record<string, (axios:AxiosInstance, ctx:Koa.Context) => any>`
// you can do things to them and give it a name in the key.
// see `config.graphql.axiosPresets[presetName].interceptors`
interceptors: {
// transmit cookie in both directions
cookie: (axios, ctx) => {
axios.interceptors.request.use(config => {
if (ctx.req.headers.cookie) {
config.headers = { ...config.headers, cookie: ctx.req.headers.cookie };
}
return config;
});
axios.interceptors.response.use(res => {
if (res.headers["set-cookie"]) {
ctx.set({ "set-cookie": res.headers["set-cookie"] });
}
return res;
});
},
},
},
// `apollo-server-koa Config`, but you can not control the `context`
graphql: {
// schema content or scheme file name like 'schema.gql'
// you can offer an array, so you can split the schema and resolvers to multiple file
typeDefs: `
type User {
id: ID!
name: String!
age: Int!
}
type Query {
user(id: ID!): User!
}
`,
// axios presets used in `axios.create(preset)`
// each preset has a name
axiosPresets: {
default: {
baseURL: "http://127.0.0.1:3000/api",
interceptors: ["cookie"], // use interceptors declared in `config.axios.interceptors`
},
},
// `apollo-server-koa` `ApolloServer.applyMiddleware` options
serverRegistration: {
path: '/graphql',
cors: true,
},
// you can split the resolvers to multiple files and require and spread them in this main config if the schema is too big
resolvers: {
Query: {
// axios request config
// all strings in this axios request config will be evaluated in js(startsWith 'js:') or rendered by ejs with `{source, args, ctx, info}`
user: {
// preset: "default", // defaults to 'default' or set to false to not use a preset
url: "/get_user_by_id",
method: 'post',
params: { id: "js:args.id", a: 'abc<%= args.id %>defg' },
data: { id: "js:args.id", a: 'abc<%= args.id %>defg' },
// data selector from axios response
// strings will be evaluated with `{res, data:res.data}`
// you can do data select in preset or even interceptors
res: { // defaults to this value
data: "js:res.data.data",
// if (error) throw error
error: "js:res.data.error"
}
},
},
},
},
};