A resposta de Joe (append
{"name":"ratio" , value:data.active/data.total}
para o resultado uma vez que o resultado é buscado no banco de dados) faria isso sem fazer nenhuma alteração no esquema. Como método alternativo ou como uma maneira mais elegante de fazer isso no GraphQL, os nomes dos campos podem ser especificados no próprio tipo em vez de passá-los como argumentos. E calcule a
ratio
escrevendo um resolvedor. Assim, o esquema GraphQL seria:
Item {
total: Int,
active: Int,
ratio: Float
}
type Query {
items: [Item]
}
O cliente especifica os campos:
{
items {
total
active
ratio
}
}
E
ratio
pode ser calculado dentro do resolver. Aqui está o código:
const express = require('express');
const graphqlHTTP = require('express-graphql');
const { graphql } = require('graphql');
const { makeExecutableSchema } = require('graphql-tools');
const getFieldNames = require('graphql-list-fields');
const typeDefs = `
type Item {
total: Int,
active: Int,
ratio: Float
}
type Query {
items: [Item]
}
`;
const resolvers = {
Query: {
items(obj, args, context, info) {
const fields = getFieldNames(info) // get the array of field names specified by the client
return context.db.getItems(fields)
}
},
Item: {
ratio: (obj) => obj.active / obj.total // resolver for finding ratio
}
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
const db = {
getItems: (fields) => // table.select(fields)
[{total: 10, active: 5},{total: 5, active: 5},{total: 15, active: 5}] // dummy data
}
graphql(
schema,
`query{
items{
total,
active,
ratio
}
}`,
{}, // rootValue
{ db } // context
).then(data => console.log(JSON.stringify(data)))