Introduction
In this blog, I introduce the idea of using ASN.1 as a schema language for JSON. I'll give a quick overview of what ASN.1 is and then I'll proceed to explaining why it is a good schema language for JSON.
What is ASN.1?
ASN.1 is a schema notation used to define data types. There are primitive types (INTEGER, UTF8String, REAL, ...) and types you construct from other types (SEQUENCE, CHOICE, SEQUENCE OF). ASN.1 is complemented by encoding rules which determine how the values of types should be represented in bytes. This means you can select the encoding rules that best fit your application. Standardized encoding rules include PER (packed encoding rules), BER (basic encoding rules) and XER (XML encoding rules). These encoding rules produce more (PER) or less (BER) compact binary encodings and text-based encodings (XER).
ASN.1 has been around since the 1980's, but it isn't going away anytime soon; technologies that you use everyday use ASN.1. Check out the breadth of application for ASN.1, or the Wikipedia entry.
ASN.1 also has some nice tool support. For example, given an ASN.1 specification, tools can generate code with data structures that represent the ASN.1 types you have defined and methods that handle encoding/decoding that data in the various encoding rules.
How to Use ASN.1 with JSON?
As I noted above, ASN.1 describes data types. By applying one set of encoding rules to your types, you can produce a compact-binary representation and by applying a different set of encoding rules, you can produce XML. All we need is to define a set of encoding rules that produces JSON. Conveniently, we have defined just such a set of encoding rules. These encoding rules are fairly straightforward and our code-generation tool, asn1c, supports them - which means you can generate C, C++, Java, and C# code that will encode your data to JSON.
A Brief Aside
For those who are familiar with X.693, XML Encoding Rules, and think it is overly complicated, we might ask whether JSON encoding rules will be the same. In short, no.
We need to distinguish here between the basic XML encoding rules (XER) and the extended XML encoding rules (EXTENDED-XER or EXER). XER provides a simple, straightforward XML representation for ASN.1 types, and the JSON encoding rules we have defined are quite similar. EXER, on the other hand, is more complicated, but there is a reason for that. EXER aims at generating XML that is valid with respect to an XML Schema. Given an XML Schema, EXER works in combination with X.694, Mapping W3C XML schema definitions into ASN.1, to produce XML that can be validated against the original XML Schema. Unlike XER, where the goal is simply to specify an XML representation for ASN.1 values, EXER's goal is to allow specification of any XML representation that can be described using XML Schema. In our JSON encoding rules, we aimed for a simple, straightforward JSON representation. We did not try to specify rules that would allow someone to produce all JSON that can be described using JSON Schema.
Why Use ASN.1 Instead of JSON Schema?
There is an IETF draft recommendation for JSON Schema, so why use ASN.1?
- ASN.1 is a mature standard. As I already mentioned, it has been around since the 1980's. Though stable, it is not stagnant; the most recent revision occurred in 2008.
- ASN.1 has tool support. There are both commercial and open source tools that will generate code from your ASN.1 specification.
- Using ASN.1, you'll focus on your data, not on the JSON itself. Using JSON Schema, you would be focused on the JSON itself, and on constraining it. Using ASN.1 with JSON encoding rules, you focus on describing your data in the abstract, and the encoding rules define the JSON that will be produced.
- Using ASN.1 gives you options: you can pick a binary encoding, XML encoding, or JSON encoding - whatever your tool supports. You are not locked-in to JSON.
Conclusion
The conclusion should be pretty clear. A proven schema language, ASN.1 can be combined with simple, straightforward rules for encoding to JSON. With tool support, this approach gives you options, allowing you to encode your data in JSON, in XML, or even in a very compact binary encoding.