How to solve jsonLogic, GraphQL Unsupported Query Keys using Lodash

Yannis Kolovos
3 min readJun 21, 2021

When it comes to data structure for storing or transferring a set of rules that should be defined from the client, jsonLogic its a great choice.

Build complex rules, serialize them as JSON, share them between front-end and back-end” is how the home page for JsonLogic starts describing the library.

The client can define rules in Json format that can be used in many systems to perform validations.

The Problem:

When you want to save the jsonLogic rules (as JSON) using GraphQL the jsonLogic’s operators ==, ===, !=, !==, >, >=, <, <=, !!, !, %, +, *, -, and / are not supported from GraphQL as Query Keys

The Solution:

json-logic-js-graphql to rescue!

json-logic-js-graphql it is using json-logic-js as a dependency and adds on top a few useful immutable helpful functions from Lodash without changing the default functionality

Installation:

# Yarn
$ yarn add json-logic-js-graphql
# NPM
$ npm install json-logic-js-graphql --save

Using a GraphQL Mutation:

We will send a mutation from the client (GraphQL playground) to GraphQL server and then save the rule input as json in the database.

The Input:

The rules should be saved as a Json in the db and the GraphQL input type should be an Json input type.

1. Database: If we are using MongoDB and mongoose the Schema should be a “anything goes” Mixed SchemaType and will look like this:

import mongoose from 'mongoose';
const { Schema } = mongoose;
const ruleSchema = new Schema({
title: { type: String, required: true },
condition: { type: Schema.Types.Mixed, required: true },
});

2. GraphQL input: The field it is anJSONObject using graphql-scalars

input RuleInput {
title: String
condition: JSONObject
}

The GraphQL Query:

Use any of _eq, _gt, _gte, _lt, _lte etc from Lodash methods.

The condition it is the actual Json rule, we will use to validate our data,

Replace the === with the _eq method.

mutation {
updateRule(
id: "609ce9dbec9fb60004087784"
condition: { _eq: [{ var: "foo" }, "bar"] }
) {
id
}
}

json-logic-js-graphql supports around 248 Lodash methods

All Lodash methods exposed with the _ namespace to avoid overwriting the default jsonLogic's functionality

Using Javascript:

import { jsonLogic } from 'json-logic-js-graphql'const rules = {
_eq: [{ var: 'foo' }, { var: 'bar' }],
}
const data = { foo: 'bar', bar: 'bar' }
jsonLogic.apply(rules, data)

How it works:

key: You can use the docs https://lodash.com/docs to locate the methods you want to use, add the _ as a prefix and this is the rule key.

value: The value it is the method’s parameters as an array. The order of the array matters because this is how jsonLogic use the order to call the method with the params!

The key its the method and value an array of the params

Example:

For example we want to use the chunk method

The chunk usage is:

_.chunk(array, size)

So the first argument its the array and the second the size

_.chunk(['a', 'b', 'c', 'd'], 2);

In json-logic-js-graphql will be:

{_chunk: [["a","b","c","d"], 2]}

So the results is:

[["a","b"],["c","d"]]

Extras: Date functions using momentJs:

The json-logic-js-graphql also supports a few useful date comparison methods like:

_gteDate, _gtDate, _lteDate, _ltDate, _eqDate, _getDate

Example:

const rules = {
_gteDate: [
[{ var: 'from' }, { var: 'to' }],
[364, 'days'],
],
}
const data = { from: '2020-10-01', to: '2021-10-01' }
jsonLogic.apply(rules, data)

Expect: from..to >= 364 days

Conclusion:

Exposing Lodash methods to jsonLogic we can manipulate data with more flexibility also support GraphQL Query Keys

--

--