query-mapper
is an alternate solution to graphql
. define your request in a json format.
It use joi like validator to validate request.
Install with npm:
npm i query-mapper --save
Install with yarn:
yarn add query-mapper
Here is a basic setup.
const express = require("express");
const bodyParser = require("body-parser");
const { Query } = require("query-mapper");
const map = require("./map");
const app = express();
app.use(bodyParser.json());
app.post("/v1/api", (request, response) => {
Query.mapper(map, request.body.request)
.then(result => {
res.status(200).json(result);
})
.catch(error => {
res.status(500).json(error);
});
});
app.listen(3000);
let { Users, Blogs } = require("../model/models");
let map = {
User: {
resolver: (args, parent) => {
return parent
? await Blogs.find({id:parent.data.id})
: await Blogs.find({})
}
},
Blog: {
resolver: (args, parent) => {
return parent
? await Blogs.find({id:parent.data.id})
: await Blogs.find({})
}
}
};
module.exports = map;
request object to get just user Id and First Name
{
"type": "User",
"attributes": ["Id", "firstName"]
}
request object to get just user Id , First Name and Blogs title posted by user (shows relation with users and blogs collection)
{
"type": "User",
"attributes": ["Id", "firstName"],
"relationships": {
"type": "Blog",
"attributes": ["title"]
}
}
In a case of user having multiple relation like get details about blogs and product relationships would be an array
{
"type": "User",
"attributes": ["Id", "firstName"],
"relationships": [
{
"type": "Blog",
"attributes": ["title"]
},
{
"type": "Product",
"attributes": ["Id"]
}
]
}
data could be pass with query and will be receive in args in User resolver
{
"type": "User",
"attributes": ["Id", "firstName"],
"query": { "data": 1 }
}
let { Query, Schema } = require("query-mapper");
let userScehema = {
Id: Schema.isNumber(),
firstName: Schema.isAlpha().isOptional(),
blogIds: Schema.isArray([Schema.isNumber()]),
blogDetails: Schema.isObject({
Id: Schema.isNumber(),
title: Schema.isString()
})
};
validation success
let user = Query.validate(userScehema, {
Id: 4,
blogIds: [23, 45, 67],
blogDetails: { Id: 4, title: "title of blog" }
});
console.log(user);
{
"Id": 4,
"blogIds": [23, 45, 67],
"blogDetails": {
"Id": 4,
"title": "title of blog"
}
}
validation error
let user = Query.validate(userScehema, {
Id: "four",
blogIds: [23, 45, 67],
blogDetails: { Id: 4, title: "title of blog" }
});
console.log(user);
{
"errors": [
{
"key": "Id",
"error": "Invalid Type"
}
],
"blogIds": [23, 45, 67],
"blogDetails": {
"Id": 4,
"title": "title of blog"
}
}
let { Users, Blogs } = require("../model/models");
let map = {
User: {
before: (request, args, parent) {
let userScehema = {
Id: Schema.isNumber(),
firstName: Schema.isAlpha().isOptional(),
};
let validate = Query.validate(userScehema, request.query);
return validate.errors
? { type: false, errors: validate.errors }
: { type: true };
},
resolver: (args, parent) => {
return parent
? await Blogs.find({id:parent.data.id})
: await Blogs.find({})
}
},
};
module.exports = map;