SyntaxHighlighter

SyntaxHighlighter

Showing posts with label tip. Show all posts
Showing posts with label tip. Show all posts

Sunday, March 14, 2021

Installing Java 8 on MacOS

If you, like me, need to install Java 8 on your MacOS, then this is the TL;DR:

brew install openjdk@8

You will find more complete instructions in mykong's excellent overview of How to Install Java on Mac OS X

I needed Java8 in order to play with MorganaXProc-III, a Java XProc 3 implementation. At the time of writing, that software only supports Java 8, which set me hunting for how to install Java 8 on my Mac.

Hopefully, this short note will also help you (or future me).

Wednesday, August 30, 2017

Serverless Tip: Use the "artifact" Directive to Deploy Your Pre-Built Lambda Zip File

tl;dr: you can deploy pre-built zip files (e.g. for your Python Lambda) using the "artifact" directive in the serverless framework.

AWS Lambda is Great!

I've been doing a lot of work recently with AWS Lambda. And I'm a fan. The combination of API Gateway + Lambda + Python, together with other AWS services including DynamoDB and S3, not to mention the awesome array of Python open source libraries, means I'm churning out all sorts of microservices with glee.

The serverless paradigm is quite different than the traditional (serverfull?) paradigm. As well as adjusting the architectural style to take advantage of what Lambda offers, deploying the code and all of its dependencies is quite different. After looking at some alternatives, we concluded that the Serverless Framework best fit our requirements.

The Serverless Framework is Great!

Rather than crafting complex CloudFormation configurations to manage my microservices in AWS, I use the Serverless Framework. (The framework also works with Apache OpenWhisk, Microsoft Azure and Google Cloud). Essentially Serverless is a simpler CloudFormation, specific to Lambda-centric deployments. (To be clear, it doesn't just help with deployments of AWS Lambda - Serverless covers a wide and growing range of AWS services).

Mainly by studying (*cough* copy-n-pasting *cough*) the extensive range of examples, and sometimes resorting to actually reading the manual, I've been able to get even quite complex setups to work, with fairly simple YAML configuration files. So, I recommend Serverless. (Although AWS themselves are developing an eerily similar alternative, in SAM, which you may also want to check out).

AWS Lambda has Limits

Sometimes you need to do stuff outside the Serverless Framework, but you still want to use all the other cool stuff it does for you.

For example, AWS Lambda has certain limits. This includes a 50Mbyte deployment limit per Lambda. Now, Serverless does let you control what goes into the Lambda package via the "include" and "exclude" directives, within the "package" directive. But, sometimes, you're sailing very close to the 50Mb limit and the only way to stay underneath is to directly create your zip package yourself. Or, in my case, you have a zip file which has precisely what you need, but you also need to manipulate it to add in a pickled bit of code. (Which you do via the Python zipfile library).


It took me a while to figure out, but you can use the "artifact" directive as the way to deploy a zip you've packaged already.

So, there you have it: Lambda is great, but you should use Serverless (or something like it) to simplify your deployments.  And you can deploy pre-built zip files using the "artifact" directive.

Monday, September 26, 2016

An ast "Hello World": Getting Started with Python's Abstract Syntax Trees


I've been working on a Python library which - for a number of reasons - needs to dynamically alter itself. Essentially, I want it to parse a document and to generate some code based on that parsed file.

ast

It turns out that Python's ast module lets me do exactly what I need. I came across some quite useful supplementary documentation on ast. But, to get started, I needed something simpler that those advanced examples. I therefore wrote a "Hello world!" program using ast. Here it is, in case you were looking for that, too.

Hello world!

Since I've become test infected, I wanted to structure my "Hello world!" ast program using unit tests.

So, to start, I tracked down a suitable "Hello world!" unit test in Python.

Hello world! in ast

Then I rewrote the Greeter.py class to use ast. My version constructs an abstract syntax tree for an Assignment. Specifically, it assigns the string "Hello world!" to the variable "m". The code then fixes the locations, compiles the code and executes it dynamically.

Obviously, the above code is a lot more work than simply assigning the string value to the variable directly. But it meant I now had the world's simplest ast program.

Nothing

Armed with this most basic of unit tests, I was then in a position to work out how to support various other types of code in ast.

For example, here's a snippet of ast code which uses ast to generate an abstract syntax tree to assign an empty type to a variable named "nothing". In other words, equivalent to nothing = ()

Invoking Methods

One of the hardest things for me to figure out was how to invoke a method of a class.

First, I worked out to call a function - one not attached to an instance of a class. But to call a method of a class, I needed to understand a bit more about how Python itself is implemented.

Calling Functions

Here's some Python ast code to call a function _foo() and assign the returned value to a variable called "result", i.e. equivalent to result = foo() And here's a variant where you pass in a value, i.e. equivalent to result = bar("some value")

In Python, Methods are Attributes of Classes

Having figured out how to call functions and pass parameters to them, I reckoned that calling a method on a class would be similar.
And it sort of was - I still needed to use ast.Call to invoke the method. But it took me quite a while to figure out how to tell it which class method to call. For example, if I wanted to call

result = self._baz(theResult)

should I pass in a function name of "self._baz"? (I tried that - it didn't work). Eventually, I worked out that self._baz is an attribute of the instance object referred to as "self". In Python, instance objects have two kinds of valid attribute names, data attributes and methods. Which meant that the code to call one method of an instance from another method looks like this:
I had never thought that profoundly about how Python is really implemented behind the scenes. Although many of the Python design decisions are actually quite well documented.

An ast Short Cut

In the process of working out how to invoke instance object methods, I came up with a general-purpose shortcut. It turns out that - since Python 2.6 - ast has a very handy helper method called "ast.parse()". This - in combination with ast.dump() - will let you very quickly figure out the correct ast pattern to use for a given bit of Python code. For example, here's how to figure out how to invoke an instance object method

005-Syntax by vicdunk
https://flic.kr/p/dUdQkm
Hopefully, that will be enough to get you going on your own Python ast adventures!

Monday, July 20, 2015

Do the Right Thing

"Do the Right Thing" by Laure Wayaffe
https://flic.kr/p/4TsH5c
Da Mayor: Doctor...
Mookie: C'mon, what. What?
Da Mayor: Always do the right thing.
Mookie: That's it?
Da Mayor: That's it.
Mookie: I got it, I'm gone.


Tony Crabbe asserts that time management is just making our busy lives worse - that the emphasis on breaking down tasks into smaller and smaller slices does mean that you cram in more stuff into a given time period but that you're not getting to the big, important things that can't be timesliced.

 Tagged! by jdhancock
https://flic.kr/p/4TsH5c
Maybe. Or maybe the techniques which used to work no longer do, since those techniques are actually changing us?
By coincidence, I've been playing with some ways that are a little different than the make-a-list and tick things off style of time management. Though I'm treating all of them as supplements, to try and help me get to the important-but-not-urgent things.
13/52 : Charte canadienne des droits et libertés by Eric Constantineau
https://flic.kr/p/9ukSAr

Habitrpg - "HabitRPG is a free habit building and productivity app that treats your real life like a game. With in-game rewards and punishments to motivate you and a strong social network to inspire you, HabitRPG can help you achieve your goals to become healthy, hard-working, and happy."

So, in fact, this is pretty close to the traditional make-a-list time management technique, but with added gamification. However, what I use it for is things like chores or habits that I want to cultivate but don't want to clutter up my to-do list. I can pick which days of the week I want dailies to appear and I associate different levels of difficulty. It has nice feedback to tell me how often I'm getting to something (e.g. by changing colours), has a holiday feature (where you check into an Inn) so you don't get penalized for changes in your routine but also let's you declare task bankruptcy by killing your character off altogether and then getting a fresh, re-incarnated one. Fun.
harpseal by gale
https://flic.kr/p/8TVRq
BJ Fogg's "Tiny Habits program can create new behaviors in your life." In some ways, this is the ultimate timeslice technique, in that you break down things into the tiniest possible steps - e.g. rather than "I want to floss my teeth twice a day" - you resolve "I will floss a single tooth". Then you tie that action to a trigger action - something you do routinely - e.g. "after I step out of the shower". The idea is to grow a set of positive new habits to habits you already have. Of course, if you're already flossing one tooth, you may as well floss a second. So, eventually, you find yourself flossing all of them. Although these are microtasks, they are not on your to-do list. Instead - the hope is - they just become automatic habits, that you don't need to think about.
I've been able to develop some good habits (e.g. tidying up my car) but - like everything else - sticking with it is the tricky thing. And not *every* desirable habit is easy to pair with a trigger action.
The Chili Pipeline by Viewminder
https://flic.kr/p/aL62z6
Blog Course - John Somnez (of SimpleProgrammer) offers a "FREE Email Course "How To Build A Blog That Will Boost Your Career" Will Show You How To Do It The RIGHT WAY... FAST!". It is essentially a three week course that takes you step-by-step to setting up a blog, from setting up Wordpress through a marketing strategy. Posting to my blog is something I know I should do - and have been kinda doing for the last few years. Actually having someone email me about it every week, with concrete steps to follow and even personally replying to my emails, makes a big difference with really doing it, though. Basically, John's course isn't a time management technique, but more of a coach - helping me do what it is I know I *ought* to do, but haven't been able to do entirely on my own.
Vulture Peak by Wonderlane
https://flic.kr/p/6B5sD2
Lark - A fitness / nutrition app, Lark lets you "Chat 1-on-1 with your nutritionist in your pocket". On my iPhone 6, it makes use of Apple's iOS 8 HealthKit, to track my daily movements. It can also be configured to help me with nutrition, by letting me log what I eat. What's different about this one is that it simulates someone texting with you. It is like a relentlessly upbeat friend, who is obsessively monitoring how much you walk or run each day, plus always asking about what you've had for breakfast. That might sound annoying, but it is actually pretty encouraging. It has certainly got me eating more fruit and vegetables and nudged me into exercising a little more.
do the right thing by paolobarzman
https://flic.kr/p/b2h2fc
The last two I list above - John's Blog Course and the Lark chatbot - are an interesting development, beyond time management lists. They are essentially coaches who encourage you to do the things you know *should* be doing, but aren't: do the right thing. That's it.

Friday, April 17, 2015

More Concise ODRL and RightsML Expressions in XML using DRY Asset Patterns

DRY

Don't repeat yourself (DRY) is a much-loved principle of software engineering.

Essentially, the DRY principle states that you should strive to express any particular piece of information only once. This simplification typically improves maintainability and understandability. Systems which require you to repeat information are known by DRY-adherents as "WET" systems (for "We Enjoy Typing" or "Write Everything Twice").

DRY ODRL

In ODRL (and hence RightsML) every permission or prohibition refers to a particular asset.

When you have more than one permission or prohibition to express for a particular asset, this means you need to repeatedly refer to the same asset. How do you avoid repeating more than absolutely necessary to identify which asset the permission or prohibition constrains?

XML Linking

One solution for minimizing the amount of XML Markup is to use XML Linking. Here's an example where you identify an asset o:asset/@id=as1 and then use an @idref to refer to it in other permission or prohibition blocks.

<o:Policy xmlns:o="http://www.w3.org/ns/odrl/2/" type="http://www.w3.org/ns/odrl/2/Set" uid="http://example.com/policy:Z1XZ">
  <o:permission>
    <o:asset id="as1" uid="http://example.com/music:1234908" relation="http://www.w3.org/ns/odrl/2/target"/>
    <o:action id="ac1" name="http://www.w3.org/ns/odrl/2/play"/>
    <o:constraint id="c1" name="http://www.w3.org/ns/odrl/2/spatial" operator="http://www.w3.org/ns/odrl/2/eq" rightOperand="http://www.itu.int/tML/tML-ISO-3166:it"/>
    <o:party id="p1" uid="http://example.com/sony:10" function="http://www.w3.org/ns/odrl/2/assigner"/>
    <o:party id= "p2" uid="http://example.com/billie:888" function="http://www.w3.org/ns/odrl/2/assignee"/>
  </o:permission>

  <o:prohibition>
    <o:asset idref="as1"/>
    <o:action idref="ac1"/>
    <o:constraint name="http://www.w3.org/ns/odrl/2/spatial" operator="http://www.w3.org/ns/odrl/2/eq" rightOperand="http://www.itu.int/tML/tML-ISO-3166:fr"/>
    <o:party idref="p1"/>
    <o:party idref="p2"/>
  </o:prohibition>
</o:Policy>


Embed the ODRL inside the Asset Markup

The other thing you can do is to have markup for the asset itself (rnews:Article in the below example) embed the ODRL policy. This means that the ODRL is even more concise, as it only needs to refer to the ID of the asset.

<rnews:Article xml:id="item8HEX">
  <rnews:title>Allies are Split<rnews:title>
  <rnews:description>Rebel fighters take control...<rnews:description>

...

  <o:Policy xmlns:o="http://www.w3.org/ns/odrl/2/" type="http://www.w3.org/ns/odrl/2/Set" uid="http://example.com/policy:ABAABA">
  <o:permission>
    <o:asset uid="#item8HEX"/>
    <o:action name="http://w3.org/ns/odrl/vocab#distribute"/>
    <o:constraint name="http://www.w3.org/ns/odrl/2/dateTime" operator="http://www.w3.org/ns/odrl/2/gteq" rightOperand="2011-11-11"/>
  </o:permission>
</o:policy>

...

</rnews:Article>





Friday, August 22, 2014

JSON Design Principles and Lessons Learnt: JSON Style (Part Three of Three)

Lessons Learnt from JSON Designs I've Worked On

Over the last couple of years, I've worked on a few JSON schema. For example, IPTC's NINJS (for representing news) and W3C GC ODRL's ODRL in JSON (for representing permissions and restrictions). I've also done some work on JSON internal to AP, for various APIs and search systems.

Along the way, I've learnt some lessons about better or worse ways to design the JSON - both about the way to do it and some JSON "style" tips. I've broken this into three posts:

JSON's built in datatypes - number, string, Boolean, array, object and null - are a natural fit for many programming languages (particularly scripting / high level languages such as Javascript, Ruby and Python). A large part of the attraction of JSON over XML, therefore, is that it is often easier to deal with data expressed in JSON in those languages.

However, crucially, it makes a big difference as to how the JSON is structured. The simpler the JSON structures are, the easier it is to write correct code to deal with them. This is part of why it is so important to prototype some code to work with a structure you are considering, as it gives you a much better sense of how easy it is to work with a given JSON structure. This principle (Simpler JSON Means Simpler Code) underlies and/or is counter-balanced by most of the rest of the following principles.

Choose Wisely: Once You Commit to a Structure, You Can't Change It (Easily)

Once you declare a given property as having a particular structure, you can't change it (easily). For example, let's say that you want to represent a date in your JSON. You decide that you will call it "arrivalDate" and that you will make this a number (which means it is easy to do date arithmetic, for example):

"arrivalDate" : 20140515

Later, however, you realize that you need to indicate in which timezone this date occurs. Sadly, you can't just tack on a timezone offset indicator (such as "+0500" or "-03") since that would make arrivalDate a string and any existing JSON documents that conform to your first definition would now be invalid.

It is annoying to have an array if there's only ever one item

In XML, you might decide you want to represent a headline like this:

<headline>Dog Bites Man</headline>

And that, since a story can only ever have one headline, your XML schema confidently states that there must be exactly one headline. Later, you realize that there are multiple kinds of headline. Since XML was designed with eXtensiblity in mind (it is the "X" in XML), you can alter your XML schema to allow for multiple headline elements:

<headline>Man Bites Dog</headline>
<headline>This is news!</headline>

The good news? Your old XML documents with a single headline are still valid, according to your new schema.

However, once you have a JSON document like this:

"headline" : "Dog Bites Man"

It is incompatible for a document like this - a JSON property can't be both a string and an array of strings.

"headline" : ["Man Bites Dog", "This is news!"]

So, you might be tempted to construct your JSON defensively - to "future proof" it - by making your properties into arrays, so that you can easily have more than one. However, it becomes really tedious to have to access an array of things when there is only ever one item. (Remember: simpler JSON means simpler code).

Avoid making things arrays, "just in case".

Use the headline / headlines "cheat"


One technique I've used when having to switch from single instances to array properties is to name my properties carefully. When a property is an array, I make it a plural. This leaves open the possibility of having a singular property - such as "headline" - and then later adding an array property with the plural name - "headlines".

Flatter is better

In XML, it is natural to have multi-level structures. When XML is pretty-printed, the indentation of enclosing elements helps to make the document structure easier to grasp. It is tempting to do the same when designing your JSON representation. However, in the spirit of "Simpler JSON Means Simpler Code", it is much easier to deal with your JSON if there are an absolute minimum of "grouping" structures in your JSON.

In the early drafts of IPTC's NINJS, we initially grouped different types of metadata together (into administrative metadata, descriptive metadata and so on. This distinction is a useful one and is still reflected in the "data model" diagram for NINJS:

NINJS Data Model
http://dev.iptc.org/ninjs
However, once we started to create examples, we realized that it was much better to lose those groups in the actual JSON markup. In particular, it is difficult to query JSON using complex criteria. In part, this is due to a lack of standards for how to specify JSON queries. So, the less structure the better.


Use pattern properties to strike a balance between flexibility and interoperability

Most of the JSON formats I've worked on are designed to be used by multiple systems (whether internally to AP or as a standard to be used by many publishers). To help ensure that multiple implementations wind up using your JSON in compatible ways, you want to restrict the degrees of freedom to interpret the format in different ways. On the other hand, you need to allow for future requirements so that your JSON formats will be adopted and adapted, rather than discarded as being too inflexible.

It is pretty easy to add something unknown into a JSON format - just add another property. Implementations should implement the "must ignore" pattern so that they don't break when they encounter an unknown property. However, sometimes, you want to guide future changes to the format, so that certain predictable changes are all done in the same way.

I've found it useful in JSON Schema to use "pattern properties" to strike this balance. For example, in NINJS, we wanted to allow publishers to use whichever geographic geometry JSON they wanted (to represent lat/long shapes for centroids and the like). We therefore added a patternProperty of "geometry_*" to allow publishers to use a property with a name starting with "geometry_" and then a suffix to indicate which type of geometry they are using.

Start property labels with a lower case letter

Whilst developing IPTC's NINJS, we experimented with various libraries, to make sure what we were producing would work everywhere. One gotcha we tripped across: the Java Jaskson library chokes on JSON properties with an initial uppercase letter. It was the only library we discovered that had this problem, but why take the risk?

Use a very restricted set of characters when naming properties

Since it is very common to autogenerate code from JSON property names (such as Java or .Net classes), it makes sense to restrict the character set you use. In order to maximize compatibility across libraries and languages, we determined that this is the safest set of characters to use:

[a-zA-Z_0-9]

i.e. upper and lower case alphas, numbers and underscore.

Inline text markup alternatives

One of the areas where both XML and HTML excel is the rich markup of text, particularly via inline markup. (For a couple of examples using IPTC standards, check out this example in NITF and this one using Schema.org-compatible rNews).

There are different possible ways to tackle rich text markup in JSON. Three alternatives we identified within NINJS are:
  1. Strip out all the inline markup and just leave the plain, unmarked text. Probably fine for short bits of text but tedious as soon as you have any structure - such as paragraphs, never mind hyperlinks.  Could be useful for things like indexing in a full text search engine, though.
  2. Keep the marked up text (such as HTML) in a string, escaping as necessary. Particularly good for delivering bits of web-ready text that can be integrated into a larger page.
  3. Mechanically translate the original markup into JSON structures. JSONML is a nicely-documented example of this approach. However, given that I advise against this mechanical approach in the first place, I would be very careful before adopting something like JSONML for your text markup - for all the same reasons.
Which method you pick needs to be driven by your particular requirements. It isn't a bad idea to consider having the text represented more  than one way, though, if you can afford it.

Support APIs with a full / partial representation indicator

JSON has gained traction as a format for use in APIs. Performance is a key factor in most APIs, so you may well want to deliver an API result in JSON with just a key subset of properties. In which case, you should consider adding a property that indicates whether this is a full or partial representation of the given resource - ideally along with a property that lets you retrieve the entire representation.

When we came up with this idea whilst designing NINJS, we toyed with having a way to describing more than just two possibilities (full/partial). However we decided that - in the general case - those are the only two that matter.

JSON Design: A Series


This is the third and final posting in my series on JSON Design. Part one discussed an approach to designing JSON schema. Part two discussed JSON tools and standards.

Friday, May 9, 2014

JSON Design Principles and Lessons Learnt: Handy JSON Tools and Standards (Part Two of Three)

Lessons Learnt from JSON Designs I've Worked On

Over the last couple of years, I've worked on a few JSON schema. For example, IPTC's NINJS (for representing news) and W3C GC ODRL's ODRL in JSON (for representing permissions and restrictions). I've also done some work on JSON internal to AP, for various APIs and search systems.

Along the way, I've learnt some lessons about better or worse ways to design the JSON - both about the way to do it and some JSON "style" tips. I've broken this into three posts:

A Couple of Handy JSON Tools

For basic syntax checking of your JSON documents, JSONLint is invaluable. Alternatives include JSON Formatter and Validator (online) and demjson (Python). Most of the XML tools (such as XML Spy or oXygen) also support JSON, too.

Even though JSON is touted as being a lightweight alternative to XML, equivalents of many of the features of XML are gradually being added to JSON. One that I make extensive use of is JSON Schema. This is an IETF effort. Even though - at the time of writing - JSON Schema is still a draft, it already has decent software support - including online validation and support in many languages. Having a JSON schema for your format is a great way to document how you intend the format to be used and it can help you spot certain kinds of errors. (My blog post Ban Unknown Properties! discusses some of the finer points of JSON validation).

Selecting and Querying JSON

One of the fundamentals of XML (and related standards including XSLT and XQuery) is XPath. So, imagine my excitement when I discovered JSONPath which has the tag line "XPath for JSON". It holds out the promise of language-independent way to specify properties within a given JSON document. Very handy - and there are a couple of language bindings, already. Unfortunately, it only seems to work for fairly simple expressions - it certainly doesn't have the full power of XPath. And it isn't backed by a standards body or a consortium of companies, so the future path (sic) of JSONPath isn't clear to me.

Perhaps more promising is JSONiq a fully fledged query language for JSON, which claims to be "The SQL of NoSQL". In fact, JSONiq is based very much on XQuery. Again, this is not backed by an independent standards body. It has been implemented on top of some XQuery engines (28.io, zorba.io, IBM's Websphere and Pascal). However, notably, the major JSON-native engines are directly supporting it, which means you need to use their proprietary query languages.

And it seems that there is a bit of a Cambrian Explosion going on in this area. Tim Bray recently published his blog post Fat JSON. In part, he illustrates why you need a tool to pick out properties from within a JSON document (basically, some JSON objects contain way too many properties than you need for a particular purpose). He discusses one approach - support Partial Responses in your API. That works if you're the author of the API but more likely you're the client of an API or are dealing with a complete JSON document from MongoDB or Elasticsearch or the like.

He points out several attempts to recreate XPath for JSON, which are similar to JSONPath (none of which I have tried yet, but which are all imaginatively called "[jJ][Pp]ath"):


Not to be outdone, Mr. Bray has knocked together JWalk - some Java source code to very simply pick out properties based on their names alone (i.e. not based on parent names or child property values as you would want from a more full-fat XPath style library). I suspect that this won't be the last attempt to solve this problem.


JSON Standards

As is probably obvious by now, I'm a big fan of standards. Not just because I've helped to create a few (e.g. MDDL, NewsML-G2, hNews, rNews, RightsML, NINJS) but also because - whenever I'm faced with solving a problem - I think "surely someone has done this before me?". I've found that looking at how someone else has attempted to tackle some domain is very instructive. In the best case, you can simply adopt someone else's hard work, along with documentation, working code and a thriving community who will help to quickly bring you up to speed. Of course, not all prior work is great - the compromises required to create a consensus standard are notorious for producing unwieldy solutions. But, even then, it can be instructive to help you understand what you don't want to do.

Whilst developing IPTC's News in JSON (NINJS), for example, we looked at previous efforts - both public and proprietary - to render articles, blog posts, photos and video using JSON properties. We also researched particular areas that are not directly tied to news. For example, when we were figuring out how to represent place metadata, we found it really helpful to examine the different approaches taken by GeoJSON and Geonames, amongst others. (In the end, rather than pick a winner, we decided to add a "pattern property" into NINJS so that providers could select the JSON geometry representation that best fits their needs).

A somewhat different type of JSON-related standard are things like JSON-LD. JSON Linked Data is a way to serialize the RDF data model to and from the JSON format. This W3C Recommendation is an increasingly popular way to structure JSON and is equivalent to the XML and Turtle serializations of RDF. So, if you are fundamentally working with RDF, then you should consider it (however, there are at least some JSON-LD dissenters). If you are not working with the RDF data model, then I would consider whether the additional features / complexity of JSON-LD is going to be a barrier to adoption.

As I will discuss in the third and final post in this series, one goal I prize when designing a JSON schema is that simple examples make sense "intuitively". I want them to look sufficiently appealing to, say, a Ruby developer that she decides to use that schema rather than make one up herself.

JSON Design: A Series

Part one discussed an approach to designing JSON schema. Part three will discuss JSON style.

Monday, May 5, 2014

JSON Design Principles and Lessons Learnt: An Approach to Designing JSON (Part One of Three)

Lessons Learnt from JSON Designs I've Worked On

Over the last couple of years, I've worked on a few JSON schema. For example, IPTC's NINJS (for representing news) and W3C GC ODRL's ODRL in JSON (for representing permissions and restrictions). I've also done some work on JSON internal to AP, for various APIs and search systems.

Along the way, I've learnt some lessons about better or worse ways to design the JSON - both about the way to do it and some JSON "style" tips. I've broken this into three posts:

Automagic JSON?

One way to create a JSON schema is to automatically generate one from an XML Schema. For any given domain, there's probably a decent XML Schema available, so why not take advantage of that and use of the many tools that are available to automatically generate the JSON for you?

In fact, there are quite a few different ways you can translate between XML and JSON, depending on what you're trying to achieve. Therefore, each tool can potentially generate quite different JSON for a given XML document. For a good overview of the different approaches and techniques involved, I recommend this survey of ways to map between XML and JSON. (That PDF is IBM's submission to the W3C Workshop on Data and Services Integration).

If you have a large amount of XML you want to convert into JSON, you may well need to implement your own tool to do the conversion. Not only does this let you control the choices made, it also can give you the opportunity to fix the niggling issues that inevitably arise in your XML as you extended your design in unexpected ways.

However, I recommend that you hand craft the design of your JSON representation, to make it as natural as possible.

A JSON Design Process

What I've found it a good way to design a JSON schema is to follow this simple process:

  • Identify a list of candidate properties - perhaps by reviewing relevant XML schema for inspiration
  • Think of one or two ways to represent each set of related properties in JSON - and research whether anyone else has designed something like it already
  • Construct sample JSON documents for each of the alternatives
  • Prototype some code to see how they work for your intended use
  • Select the best alternative and add it to your schema
  • Write down the examples and your rationale for picking that representation (otherwise you will forget)
  • Repeat

After a while, you'll see some repeating patterns and you'll need to write fewer prototypes to try things out. But I still recommend writing down your rationale...

Trying out the JSON in code is particularly important if you haven't done a lot of JSON work before. It really gives you a feel for the best, most natural way to work with JSON and can help get you out of your XML Mindset (if that's where you're starting from).

JSON Design: A Series

Part two will discuss JSON tools and standards.

Wednesday, July 18, 2012

XML Namespaces

If you only take away one thing from this blog posting, let it be this:

XML Protip:

If you can’t figure out why your XPath expression isn’t working, check the namespace.

XML Namespaces

It is possible to define XML elements and attributes in different namespaces.
This promotes reuse of existing vocabularies because, rather than copying someone else's elements and attributes into your schema, you can just directly incorporate their XML vocabulary into your instance documents.

Namespaces Look Like URLs

XML Namespaces look like URLs, although there is no requirement that there be anything in particular that you can retrieve at the end of the URL. But URLs are convenient because they are a well-established way to have a federated naming scheme. In other words, if I own an Internet domain, I can make up URLs within that domain without needing to consult any centralized authority. That means I can use URLs to mint new, guaranteed unique namespace identifiers.

Declaring Namespaces

You can use xmlns to declare a default namespace
<newsItem xmlns='http://iptc.org/std/nar/2006-10-01/'>
  <itemMeta>
    <title>Pope Blesses Astronauts</title>
  </itemMeta>
</
newsItem>

In the above example, newsItem is in the http://iptc.org/std/nar/2006-10-01 namespace.
itemMeta and title are also in the http://iptc.org/std/nar/2006-10-01/ namespace, even though they don't have any xmlns listed on the elements. That's because child elements inherit the namespace from their parents.

XML Namespace Prefixes

You can use xmlns:prefix to declare a namespace and bind it to a prefix

<nar:newsItem xmlns:nar='http://iptc.org/std/nar/2006-10-01/'>
  <nar:itemMeta>
    <nar:title>Pope Blesses Astronauts</nar:title>
  </nar:itemMeta>
</nar:newsItem>

newsItem is in the http://iptc.org/std/nar/2006-10-01/ namespace. And so are itemMeta and title: to an XML parser, this document and the previous one are identical.

Whether you use a prefix on each namespaced element or you leave them unadorned is a matter of style and personal preference.

Namespace are Useful, but can be Confusing

Although namespaces are important in constructing modular XML documents and avoiding re-inventing the wheel of vocabularies, they can be quite confusing. In particular, the non-prefix syntax (in which an element inherits its namespace from its parent) can catch you out in various ways.

For example, if you were to just copy and paste the "inner" markup from the first document above, you'd wind up with the document below - and lose the namespace!


  <itemMeta>
    <title>Pope Blesses Astronauts</title>
  </itemMeta>


This is bad.

Similarly, it is routine to look at an instance document and construct an XPath such as this to pick out the value of the title element:

itemMeta/title


And spend hours trying to figure out why it isn't working. Of course, you know that it is because we didn't specify that the itemMeta  and  title elements need to be in the http://iptc.org/std/nar/2006-10-01/ namespace.


Hence my number one tip for debugging XML-related code:



XML Protip:

If you can’t figure out why your XPath expression isn’t working, check the namespace.


Updated

Paul Kelly adds his number one XPath tip: check the spelling first.