Argo:   JSON Schema Adventures
1 Installation
2 Running Argo
2.1 validate
2.2 schema
2.3 pp
2.4 oneline
2.5 point
2.6 equal
3 Library interface
parse-json?
json-schema?
adheres-to-schema?
check-json/  schema
json-equal?
json-pretty-print
json-in-one-line
json-pointer-value
4 Technical information
4.1 Semantic validation
4.2 JSON Schema versions
5 Shortcomings and sorely missing features
5.1 Hypermedia keywords unsupported
5.2 Error reporting
5.3 Only version 6 of the JSON Schema specification is supported
6 Further reading
6.12

Argo: JSON Schema Adventures

Jesse Alama <[email protected]>

 (require argo) package: argo

Argo is a JSON Schema validator. Work with your JSON data knowing that it adheres to some sensible constraints. If you have to work with JSON, even if only occasionally, you may want to consider validating it (that is, checking that is satisfies the constraints specified by the schema).

1 Installation

To install Argo from the command line, use the raco pkg install command, like so:

raco pkg install argo

After Argo has been installed, you can keep it up-to-date using raco pkg update:

raco pkg update argo

2 Running Argo

Argo can be executed as a command-line tool using raco. This section discusses the five available commands: validate, schema, pp, point, and equal.

2.1 validate

The validate command takes a JSON Schema file and a JSON file as input and checks that the data adheres to the schema.

Run it like this:

raco argo validate schema.json data.json

You will see either Validation succeeded or Validation failed.

In case of validation success, seeing “Validation succeeded” is probably enough. In case of failure, “Validation failed” is, admittedly, not the most informative thing you’ve seen today. See also Error reporting.

Exit code

The validate command exits cleanly (with code 0) provided:

If any of these conditions fails, the exit code will be 1.

Options

validate accepts only one option, quiet, which, if set, will cause all output to be suppressed. By default, this option is unset. In such a case, the exit code will be your only indication about the validity of your data. Here’s how you can use this option:

raco argo validate --quiet schema.json data.json

As discussed in the above concerning exit codes, there are seven conditions that need to be met for validate to exit cleanly. Looking at that list there, another way to think of it is that there are six preconditions that need to be met for validation to even make sense. Even if the quiet flag is set, you will see error output if any of these preconditions is not met. Thus

raco argo validate --quiet schema.json

will cause an error message to be printed, despite the quiet, because this isn’t even a well-formed invocation of validate (notice that the second argument is missing).

2.2 schema

The schema command takes a JSON file as input and checks that it is a schema. (Recall that “schema” for Argo is “draft 06 schema”.)

Run it like this:

raco argo schema schema.json

The output will tell you whether schema.json really is a JSON Schema.

Exit code

schema exits cleanly (with code 0) provided:

(Though see below for a way in which the exit code may be non-zero even if all these conditions are met.)

Options

schema accepts only one option, quiet, which, if set, will cause all output to be suppressed. By default, this option is unset. In such a case, the exit code will be your only indication about whether your JSON really is a schema.

2.3 pp

The pp command takes a JSON file as input and pretty prints it to the console.

Run it like this:

raco argo pp data.json

Exit code

pp exits cleanly (with code 0) provided:

If any of these conditions fails, the exit code will be 1.

Options

The command accepts no options.

2.4 oneline

The oneline command takes a JSON file as input and renders it in a single line. It doesn’t get more compressed than this.

Exit code

The oneline command exits cleanly (with code 0) provided:

If any of these conditions fails, the exit code will be 1.

Options

oneline accepts no options.

2.5 point

The point command takes a JSON file and a JSON Pointer expression as input and outputs the part of the JSON file to which the expression refers.

Run it like this:

raco argo point data.json expression

Exit code

point exits cleanly (with code 0) provided:

If any of these conditions fails, the exit code will be 1.

Options

point accepts no options.

2.6 equal

The equal command takes a two JSON files as input and checks that they represent identical JSON content.

Run it like this:

raco argo equal json-1.json json-2.json

Depending on whether the contents of json-1.json and json-2.json are the same content, you will see either JSON files are equal or JSON files are not equal.

See the documentation for json-equal? to see the definition of what it means for two JSON documents to be equal.

Exit code

equal with arguments exits cleanly (with code 0) provided:

If any of these conditions fails, the exit code will be 1.

If the quiet flag is used, the exit code will be 1 if the two inputs are represent different JSON documents. If the quiet flag is not used, the exit code will always be 0 (provided, of course, that all of the above conditions are met).

Options

equal accepts only one option, quiet, which, if set, will cause all output to be suppressed. By default, this option is unset. In such a case, the exit code will be your only indication about the equality of your data.

3 Library interface

procedure

(parse-json? jsonish)  
jsexpr? boolean?
  jsonish : (or path? bytes? string? input-port? url?)
Parse something that might be JSON (a path to a file, a byte string, a string, an input port, or a URL).

Returns two values. The first a jsexpr? representing the parsed content of jsonish. The second indicates whether the result could be parsed as JSON at all. #f means that the argument represents invalid JSON; in that case, it doesn’t matter what the first return value is.

procedure

(json-schema? schema)  boolean?

  schema : any
Return #t if schema is a jsexpr? value that counts as a JSON Schema.

“JSON Schema” for Argo means “draft 6 JSON Schema”, which was the current version of the JSON Schema specification when Argo was conceived. If you’ve worked with JSON Schema over the years, chances are good you’ve become accustomed to draft 4 schemas. They’re largely the same, and for many users, they may be indistinguishable; but they’re not identical. This means that what passed for a schema in the halcyon days of 2016 may not be a schema in Argo’s eyes. (And vice versa: Argo may accept as a schema something that would be rejected according to the draft 4 rules.)

The meatiest function of Argo is adheres-to-schema?.

procedure

(adheres-to-schema? data schema)  boolean?

  data : jsexpr?
  schema : jsexpr?
Return #t if schema is a (draft 6) JSON Schema and data adheres to schema, otherwise #f.

procedure

(check-json/schema data schema)  void

  data : any
  schema : any
Returns void if (1) data is a jsexpr? value, (2) schema is a JSON Schema, and (3) data adheres to schema. Otherwise, an exception is thrown. If cases (1) or (2) fail, the exception is an exn:fail:contract?; if case (3) fails, the exception is an exn:fail? value.

procedure

(json-equal? data-1 data-2)  boolean

  data-1 : jsexpr?
  data-2 : jsexpr?
Returns #t if data-1 and data-2 represent equal JSON objects.

Equality of two JSON documents doc-1 and doc-2 is defined as follows: doc-1 and doc-2 have the same type (both are JSON objects, both are JSON strings, etc.) and adhere to the type-specific rules for equality, which are:

procedure

(json-pretty-print data)  string?

  data : jsexpr?
Returns a string representation of data that is, well, pretty.

procedure

(json-in-one-line data)  string?

  data : jsexpr?
Returns a string representation of data that has a single line. (It’s kind of the opposite of json-pretty-print.)

procedure

(json-pointer-value data expr)  jsexpr?

  data : jsexpr?
  expr : string?
Returns the part of expr that the JSON Pointer expression expr refers to.

If expr is a malformed JSON Pointer expression, or refers to nothing in data, an exception will be raised.

4 Technical information

4.1 Semantic validation

Argo supports all the semantic validation keywords:

4.2 JSON Schema versions

JSON Schema is a moving target. Thankfully, the target moves slowly. But it does move. What does that mean for you? To put it bluntly: a JSON document that’s valid today may not be valid tomorrow.

Argo implements JSON Schema version 6 (codename “draft-wright-json-schema-validation-01”). The official homepage for specification that Argo follows is here. That version was released on April 21, 2017. If you’ve been working with JSON Schema for a few years, chances are good that you’ve worked with version 4. The two versions are largely the same, but there are some minor differences. Unfortunately, what counts as a “minor difference” is in the eyes of the beholder. While testing Argo I found several schemas on the web, written in the heyday of version 4—including some on the JSON Schema homepage—that no longer produced the expected results when interpreted as version 6 schemas. They had to be updated. It may very well be possible that you’ll need to update your JSON Schemas, too.

5 Shortcomings and sorely missing features

Argo suffers from some known deficiencies.

5.1 Hypermedia keywords unsupported

JSON Schema defines Hypermedia keywords (base, links, and media) are currently not supported. When these properties are encountered on a JSON schema, they are silently ignored. If you work with JSON schema that rely on these features, it will almost certainly not work with Argo. (Meanining: validation will produce many false negatives and maybe even some false positives.)

5.2 Error reporting

Error reporting is largely (or should I say, entirely) missing. Thus, if a JSON document is not valid according to a JSON schema, you just get #f. You don’t get a description of why the document fails validation.

5.3 Only version 6 of the JSON Schema specification is supported

Only verson 6 of the JSON Schema specification is supported. Schema that declare themselves to be, say, a v4 JSON Schema may not be treated correctly (that is, according to the v4 rules).

If you can, either leave out the $schema keyword or use the value http://json-schema.org/draft-06/schema# for $schema.

6 Further reading

To learn more about JSON Schema, go to the source: http://json-schema.org. The specificiations that Argo aims to follow are in two documents:

(The third part of the JSON Schema specification that is currently not implemented by Argo is JSON Hyper-Schema.)

Finally, you’re welcome to visit the Argo homepage to read about updates and other JSON Schema goodies.