Skip to content

Latest commit

 

History

History

cdc

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

JSONx Sample: Consumer Driven Contracts

JSON Schema for the enterprise

Build Status Coverage Status Javadocs Released Version Snapshot Version

Abstract

This document presents the Consumer Driven Contracts sample application.

Table of Contents

  1 Consumer Driven Contracts
  2 Contributing
  3 Special Thanks
  4 License

1 Consumer Driven Contracts

The JSONx Framework was created specifically for Consumer Driven Contracts. With the JSON Schema Definition Language (JSD), one can create a Consumer Driven Contract (CDC) with an evolution model based on schema versioning. The JSD can be used by producers and consumers to validate documents in a communication protocol.

The following example illustrates a simple protocol that uses the Consumer Driven Contracts approach, and consists of the actors:

  1. Producer: Representing the provider of the ProductSearch service.
  2. Consumer1: The first consumer of the ProductSearch service.
  3. Consumer2: The second consumer of the ProductSearch service.

Consider a simple ProductSearch service, which allows consumer applications to search a product catalogue.

Version v1 of the protocol defines the contract:

  • Request

    GET /ProductSearch?name=<name>
    
  • Response

    {
      "Version": "v1",
      "CatalogueID": <number>,
      "Name": <string>,
      "Price": <string>,
      "Manufacturer": <string>,
      "InStock": <boolean>
    }

The schema that describes the Response contract is:

JSD
{
  "jx:ns": "http://www.jsonx.org/schema-0.3.jsd",
  "jx:schemaLocation": "http://www.jsonx.org/schema-0.3.jsd http://www.jsonx.org/schema.jsd",

  "product": { "jx:type": "object", "abstract": true, "properties": {
    "CatalogueID": { "jx:type": "number", "range": "[1,]", "scale": 0, "nullable": false},
    "Name": { "jx:type": "string", "pattern": "\\S|\\S.*\\S", "nullable": false },
    "Price": { "jx:type": "string", "pattern": "\\$\\d+\\.\\d{2}", "nullable": false },
    "Manufacturer": { "jx:type": "string", "pattern": "\\S|\\S.*\\S", "nullable": false },
    "InStock": { "jx:type": "boolean", "nullable": false} } },

  "product1": { "jx:type": "object", "extends": "product", "properties": {
    "Version": { "jx:type": "string", "pattern": "v1", "nullable": false } } }
}
JSDx
<schema
  xmlns="http://www.jsonx.org/schema-0.3.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.jsonx.org/schema-0.3.xsd http://www.jsonx.org/schema.xsd">

  <object name="product" abstract="true">
    <property name="CatalogueID" xsi:type="number" range="[1,]" scale="0" nullable="false"/>
    <property name="Name" xsi:type="string" pattern="\S|\S.*\S" nullable="false"/>
    <property name="Price" xsi:type="string" pattern="\$\d+\.\d{2}" nullable="false"/>
    <property name="Manufacturer" xsi:type="string" pattern="\S|\S.*\S" nullable="false"/>
    <property name="InStock" xsi:type="boolean" nullable="false"/>
  </object>

  <object name="product1" extends="product">
    <property name="Version" xsi:type="string" pattern="v1" nullable="false"/>
  </object>

</schema>

Note: The Converter utility automatically converts between JSD and JSDx.

All actors -- Producer, Consumer1, and Consumer2 -- agree on the contract, and implement and integrate the protocol into their systems. To assert receipt of contract-compliant documents, all actors use the contract definition to automatically validate received and sent messages.

After many months of running in production, Consumer2 issues a request to the Producer to provide additional information in the response. Specifically, Consumer2 requests for the addition of another field in the JSON response:

{
- "Version": "v1.0",
+ "Version": "v2.0",
  "CatalogueID": <number>,
  "Name": <string>,
  "Price": <string>,
  "Manufacturer": <string>,
  "InStock": <boolean>,
+ "Description": <string>
}

To satisfy Consumer2's request, the contract is updated to support version v2 of the Response:

JSD
{
  "jx:ns": "http://www.jsonx.org/schema-0.3.jsd",
  "jx:schemaLocation": "http://www.jsonx.org/schema-0.3.jsd http://www.jsonx.org/schema.jsd",

  "product": { "jx:type": "object", "abstract": true, "properties": {
    "CatalogueID": { "jx:type": "number", "range": "[1,]", "scale": 0, "nullable": false},
    "Name": { "jx:type": "string", "pattern": "\\S|\\S.*\\S", "nullable": false },
    "Price": { "jx:type": "string", "pattern": "\\$\\d+\\.\\d{2}", "nullable": false },
    "Manufacturer": { "jx:type": "string", "pattern": "\\S|\\S.*\\S", "nullable": false },
    "InStock": { "jx:type": "boolean", "nullable": false} } },

  "product1": { "jx:type": "object", "extends": "product", "properties": {
    "Version": { "jx:type": "string", "pattern": "v1", "nullable": false } } }

+ "product2": { "jx:type": "object", "extends": "product", "properties": {
+   "Version": { "jx:type": "string", "pattern": "v2", "nullable": false },
+   "Description": { "jx:type": "string", "pattern": "\\S|\\S.*\\S", "nullable": false } } }
}
JSDx
<schema
  xmlns="http://www.jsonx.org/schema-0.3.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.jsonx.org/schema-0.3.xsd http://www.jsonx.org/schema.xsd">

  <object name="product" abstract="true">
    <property name="CatalogueID" xsi:type="number" range="[1,]" scale="0" nullable="false"/>
    <property name="Name" xsi:type="string" pattern="\S|\S.*\S" nullable="false"/>
    <property name="Price" xsi:type="string" pattern="\$\d+\.\d{2}" nullable="false"/>
    <property name="Manufacturer" xsi:type="string" pattern="\S|\S.*\S" nullable="false"/>
    <property name="InStock" xsi:type="boolean" nullable="false"/>
  </object>

  <object name="product1" extends="product">
    <property name="Version" xsi:type="string" pattern="v1" nullable="false"/>
  </object>

+ <object name="product2" extends="product">
+   <property name="Version" xsi:type="string" pattern="v2" nullable="false"/>
+   <property name="Description" xsi:type="string" pattern="\S|\S.*\S" nullable="false"/>
+ </object>

</schema>

Note: The Converter utility automatically converts between JSD and JSDx.

With this approach, the v2 evolution of the contract satisfies Customer2. And, since the contract also retains support for v1, integration with Customer1 is unaffected.

The code included in this module implements this example.

2 Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

3 Special Thanks

Java Profiler
Special thanks to EJ Technologies for providing their award winning Java Profiler (JProfiler) for development of the JSONx Framework.

4 License

This project is licensed under the MIT License - see the LICENSE.txt file for details.