Unleash the power of lodash inside your GraphQL queries
GraphQL allows to ask for what you need and get exactly that. But what about the shape?GraphQL Lodash gives you the power of lodash
right inside your GraphQL Query using @_
directive.
Note: This is an experimental project created to explore the concept of Query and transformation collocation.
We encourage you to try it inside our demo or check detailed walkthrough.
Here are a few query examples you can run against StartWars API:
npm install --save graphql-lodash
or
yarn add graphql-lodash
graphqlLodash(query, [operationName])
{
query: string|object,
transform: Function
}
@_
directivesresponse.data
as a single argument and returnsthe same data in the intended shape.The simplest way to integrate graphql-lodash
is to write wrapper function for graphql client of you choice:
import { graphqlLodash } from 'graphql-lodash';
function lodashQuery(queryWithLodash) {
let { query, transform } = graphqlLodash(queryWithLodash);
// Make a GraphQL call using 'query' variable as a query
// And place result in 'result' variable
...
result.data = transform(result.data);
return result;
}
An example of a simple client based on fetch API:
function executeGraphQLQuery(url, query) {
return fetch(url, {
method: 'POST',
headers: new Headers({"content-type": 'application/json'}),
body: JSON.stringify({ query: query })
}).then(response => {
if (response.ok)
return response.json();
return response.text().then(body => {
throw Error(response.status + ' ' + response.statusText + '\n' + body);
});
});
}
function lodashQuery(url, queryWithLodash) {
let { query, transform } = window.GQLLodash.graphqlLodash(queryWithLodash);
return executeGraphQLQuery(url, query).then(result => {
result.data = transform(result.data);
return result;
});
}
// then use as bellow
lodashQuery('https://swapi.apis.guru', `{
planetWithMaxPopulation: allPlanets @_(get: "planets") {
planets @_(maxBy: "population") {
name
population
}
}
}`).then(result => console.log(result.data));
For caching clients like Relay and Apollo we recommend to apply the transformation after the caching layer.Here is proposed solution for Relay:
We are still figuring out how to do this and any feedback is welcome.
When using with Apollo you can use props
option to apply transformations:
const rawQuery = gql`
# query with @_ directives
`;
const {query, transform} = graphqlLodash(rawQuery);
export default graphql(query, {
props: (props) => ({...props, rawData: props.data, data: transform(props.data)})
})(Component);
You can write a simple wrapper for simplicity:
import { graphql } from 'react-apollo';
import { graphqlLodash } from 'graphql-lodash';
export function gqlLodash(rawQuery, config) {
const {query, transform} = graphqlLodash(rawQuery);
let origProps = (config && config.props) || ((props) => props);
return (comp) => graphql(query, {...config,
props: (props) => origProps({
...props,
rawData: props.data,
data: transform(props.data)
})
})(comp);
}
// then use as bellow
export default gqlLodash(query)(Component);
Just replace graphql
with gqlLodash
and you are ready to use lodash in your queries.Check out the react-apollo-lodash-demo repo.
You can also do the transformation inside an ApolloLink by rewriting theparsed GraphQL Document
:
new ApolloLink((operation, forward) => {
const { query, transform } = graphqlLodash(operation.query);
operation.query = query;
return forward(operation)
.map(response => ({
...response,
data: transform(response.data),
}));
});
Chaining this link with the other links passed to your ApolloClient
will apply the transformation to every query thatApollo runs, such as those from the <Query />
component orsubscriptions.
If your application uses introspection queries (like GraphiQL does toget documentation and autocomplete information), you will also need toextend the introspection query result with the directives fromgraphql-lodash. One way you could do this is:
import {
buildClientSchema,
extendSchema,
graphqlSync,
introspectionQuery,
} from 'graphql';
// inside the above ApolloLink function
if (response.data && response.data.__schema) {
const schema = extendSchema(
buildClientSchema(response.data),
lodashDirectiveAST,
);
return graphqlSync(schema, introspectionQuery);
}
See the demo/
source in this repo for another example of modifyingthe introspection query result.
In theory, this tool can be used on the server. But this will break the contract and, most likely,will break all the GraphQL tooling you use. Use it on server-side only if you know what you do.
使用场景 在 js 中经常会出现嵌套调用这种情况,如 a.b.c.d.e,但是这么写很容易抛出异常。你需要这么写 a && a.b && a.b.c && a.b.c.d && a.b.c.d.e,但是显得有些啰嗦与冗长了。特别是在 graphql 中,这种嵌套调用更是难以避免。 这时就需要一个 get 函数,使用 get(a, 'b.c.d.e') 简单清晰,并且容错性提高了很多
lodash 基本上成为了写 javascript 工具库的标配,它广泛应用在各种服务端以及前端应用中,但是它的包体积略大了一些。对于服务端来说,包的体积并不是十分的重要,或者换句话说,不像前端那样对包的体积特别敏感,一分一毫都会影响页面打开的性能,从而影响用户体验。 正因为前端包体积对于用户体验的重要性,因此有各种各样减小包体积的方法。针对 lodash 来说,你完全不必要引入 lodash 的
快速开始 GraphQL 是一种用于 API 的查询语言。这是 GraphQL 和 REST 之间一个很好的比较 (译者注: GraphQL 替代 REST 是必然趋势)。在这组文章中, 我们不会解释什幺是 GraphQL, 而是演示如何使用 @nestjs/GraphQL 模块。 GraphQLModule 只不过是 Apollo 服务器的包装器。我们没有造轮子, 而是提供一个现成的模块, 这让
GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。 向你的 API 发出一个 GraphQL 请求就能准确获得你想要的数据,不多不少。 GraphQL 查询总是返回可预测
Graphql editor 是一款 Graphql 的可视化编辑器和 IDE,帮助用户更容易理解 GraphQL 模式,通过使用可视化块系统创建模式。GraphQL Editor 将把它们转化为代码。通过 GraphQL Editor,用户可以在不写任何代码的情况下创建可视化的图表,或者以一种很好的方式呈现其模式。 GraphQL View Code Editor View Hierarchy View
GraphQL CLI Help us to improve new GraphQL CLI. Check out the new structure and commands below!Feel free to contact us in Discord channel. We would love to hear your feedback. Features Helpful command
Fullstack GraphQL Simple Demo Application API built with Node + Express + GraphQL + Sequelize (supports MySQL, Postgres, Sqlite and MSSQL). WebApp built with React + Redux. Written in ES6 using Babel
Hasura GraphQL Engine Hasura is an open source product that accelerates API development by 10x by giving you GraphQL or REST APIs with built in authorization on your data, instantly. Read more at hasu