Working with JSON Pointers (RFC 6901)

JSON Pointer syntax, as defined in RFC 6901 offers means to navigate through JSON documents /using/paths/in/documents - here's how to make use of them in the upcoming version 2.0 of Zato.

Systems being integrated will usually offer standard ways to refer to certain objects transferred in JSON documents. For instance, a customer ID will almost always be in the same location across documents no matter the actual API call.

We can take advantage of it and define a set of reusable JSON Pointers that will be referred to in body of multiple services. They will be R in [IRA of Interesting, Reusable and Atomic APIs]/en/docs/3.3/intro/esb-soa.html) one should strive to design.

Here come the definitions and the net result..

.. the service ..

# -*- coding: utf-8 -*-

from __future__ import absolute_import, division, print_function, unicode_literals

# stdlib
from json import dumps

# Zato
from zato.server.service import Service

class IdMapper(Service):
    name = 'id.mapper'

    def handle(self):

        # Obtain a JSON pointer to the service's request
        req_jsp = self.msg.json_pointer()

        # Get a couple of request elements
        cust_id = req_jsp.get('ERP CustomerId')
        account_id = req_jsp.get('ERP AccountId')

        # Prepare a response and its associated JSON pointer.
        # Note that JSON pointers can be used with regular Python dicts.
        resp = {}
        resp_jsp = self.msg.json_pointer(resp)

        # Map request elements into response
        resp_jsp.set('CRM CustomerId', cust_id)
        resp_jsp.set('CRM AccountId', account_id)

        # Return response
        self.response.payload = dumps(resp)

.. and the discussion of what has been presented:

  • A JSON Pointer by default points to the request a service receives
  • Calling .get on a pointer fetches a value from the underlying document
  • JSON Pointers can work with regular Python dicts, they're not strictly limited to JSON
  • Calling .set assigns a value under the path previously configured
  • When setting values, all paths that don't exist are created on fly (similar to mkdir -p in shell)

JSON Pointers can be freely reused in more than one service - and should one day an ERP or CRM above decide to change their data model only the JSON Pointer's definition will have to be updated, with no code changes to the services necessary.

Note that the very same API is also available for XPath expressions, presented in [a companion post]/en/docs/3.3/index.html.