1. Introduction

This library provides a JSON schema draft 4 validator for OpenResty and Lua 5.2+.

It has been designed to validate incoming data for HTTP APIs so it is decently fast: it works by transforming the given schema into a pure Lua function on-the-fly.

This is an updated version of ljsonschema by @jdesgats.

1.1 Differences with JSONSchema

Due to the nature of the Lua language, the full JSON schema support is difficult to reach. Some of the limitations can be solved using customizing the behaviour, but some features are not supported (correctly) at this time:

  • Pattern matching/regex

1.2 Handling JSON

When decoding JSON into a Lua table there are several things that require some extra attention. The default is to use lua-cjson and its implementation of the values below.

The prefered setup:

local cjson = require("cjson.safe").new() -- use 'new' to not pollute the global instance
cjson.decode_array_with_array_mt(true) -- force decoded arrays to be marked with array_mt

1.2.1 Null values

Lua doesn't have an explicit null value. In JSON null essentially means, this key exists, but it has no value. Whereas the Lua equivalent nil cannot distinguish between the key non existing and the key having no value.

As such a sentinel value must be defined that is unique and can be used to represent the JSON-null value.

1.2.2 Array vs Object

Lua tables are more versatile than the JSON Array and JSON Object types, and hence a table is used to represent both JSON types. This can however create ambiguity when validating. When decoding JSON, both an empty array and an empty object will be decoded to an empty Lua table. So it cannot be properly validated as being either one.

For this purpose a meta-table (array_mt) is defined and should be attached to arrays.

1.3 UTF-8 encoding

Lua has functionality to handle UTF-8 from Lua version 5.3 onwards. This library only needs a string length function, and it has a pure Lua implementation that is used when the Lua native utf8.len() function is unavailable.

Especially on platforms where performance matters it might be worthwhile investigating to replace the function by specifying your own when calling generate_validator.

The behaviour is that the function returns the length of the string in characters (not bytes) or if that fails (in case of binary string for example) falls back to byte-count.

1.4 Customizing behaviour

Some advanced features of JSON Schema are not possible to implement using the standard library and require third party libraries to work.

In order to not force one particular library, and not bloat this library for the simple schemas, extension points are provided. For details see the generate_validator method and its options.

1.5 Automatic coercion

When validating properties that are not json, the input usually always is a string value. For example a query string or header value.

For these cases there is an option coercion. If you set this flag then a string value targetting a type of boolean, number, or integer will be attempted coerced to the proper type. After which the validation will occur.

1.6 Installation

It is aimed at use with lua-cjson. Since it uses the cjson semantics for arrays (array_mt)

The preferred way to install this library is to use Luarocks:

luarocks install lua-resty-ljsonschema

To install it from the repo use the Makefile:

make install

1.7 Development

Running the tests requires the Busted test framework. The test suite is based of a standard test suite for JSONschema and is included as a Git submodule.

To set up the repo for testing use the Makefile. To list the available targets do:

make
generated by LDoc 1.5.0 Last updated 2024-10-24 09:22:08