API-led Connectivity and CQRS: API layering and the CQRS API implementation

January 6 2016

2 comments 0

In this 4 part blog series, I describe in detail how one might go about modernizing a functional, but legacy Supplier Relationship Management (SRM) application without redeveloping (or even touching) it. Why? The release cycle for the legacy app is too long and it doesn’t scale in a way that will meet the needs of newly required mobile application.

Additionally, an aspect of SOLID software design is the Open/Closed Principle which in our case can be applied as we are extending and providing functionality without actually modifying the core application. The architectural pattern we apply is Command Query Responsibility Segregation (CQRS) as we expect a high amount of queries to our data and the result formats (views) should be highly tailored to multiple channels and independent from the SRM application.

To review:

  • Part 1 of the series explains goals, vision and application requirements in more detail
  • Part 2 walks through building a Mule application responsible for answering queries in a seamless and highly performant way. We also used Neo4j’s graph database.
  • Part 3 (this post) will show how to wrap the legacy database with an API that will then be used with our application handling commands.
  • Part 4 (next post) will finalize the use case showing how to keep a MySQL DB and Neo4j in sync.

Part 3 agenda

Here are the final steps required to complete the front end implementation:

  1. Wrap the SRM application’s DB with a RAML based REST API
  2. Publish the Query and Write applications API into Anypoint Exchange to empower ease of use and reuse
  3. Design an API using RAML that merges and exposes Query and Command capabilities
  4. Implement this API where Queries are handled synchronously and Commands are performed asynchronously
  5. Publish the CQRS API on API Portal and Anypoint Exchange

RESTful wrapping the Database

Just as you might wrap a gift before giving it to someone, let’s wrap our database with a clean API. RAML (the RESTful API Markup Language) provides a clean, easy-to-understand way to define these APIs . RAML also lets you describe exactly what you want to build and iterate on it. Due to its resource oriented and YAML-based nature, it is readable by everyone who can use a browser. If you come along with a coffee, even the functional expert might give it a review. To keep things simple and prove the point, you will just implement a price update of a specific part and adding a new supplier. Review the RAML gist for more details.

Once you designed the specification using RAML you can start implementing it in Anypoint Studio. Anypoint Studio is MuleSoft’s Eclipse based IDE for implementing Enterprise Application Integration (EAI) solutions, batch oriented applications and API-led Connectivity projects.

Here is a screenshot of the PUT implementation to update your parts prices:

CQRS 1

  • The request’s XML is converted into a Java Object Map for property access
  • The incoming parts price might be of any currency, e.g. Pounds, Swiss Francs, … which we convert into a Euro and USD price, as demanded by the legacy DB (you use a Message Enricher pattern)
  • The converted price and the new part information are updated in the legacy DB

You can find the complete implementation of the Command API application on GitHub.

Publishing the Command and Query APIs

To publish your APIs, you just need to register the RAML file locations and your Portal page into Anypoint Exchange.

Anypoint Exchange is the central place for all your integration templates, examples, How To’s and even APIs. Exchange is browser based and also integrated with and explorable within Studio. So as soon as you publish the Command and Query APIs into Exchange it is available to any developer interested in it. Note that the developer doesn’t need to know where (URL) the API is hosted or which data types is supports, as all of this is auto-configured.

Anypoint API Portal allows developers to request access to your published APIs and provides documentation. Once API access is requested you grant (manually or automatically) access for the developer and s/he will be provisioned with her client key and client secret.

Once published, those APIs are available in your tenant of Anypoint Platform and also accessible from Anypoint Studio.

CQRS 2

Design your Business Case – CQRS API

To combine aspects of the Query and Command API and implement them to fulfill your requirements feeding a mobile prototype UI at hand you need to:

  • List part instance resources
  • Update prices of parts
  • List suppliers
  • Create a new supplier

The RAML gist specifying the requirements above can be found on GitHub.

All of those capabilities will be orchestrated from the underlying API applications you just built on top of Neo4j and the legacy SRM application.

A logical implementation overview looks like this:

CQRS 3

 

Implementing the CQRS API

The implementation of your CQRS API is easily supported as you just configure the HTTP endpoints to the backend systems with the information that was added into Anypoint Exchange, all from Anypoint Studio.

CQRS 4

 

Asynchronous Command Requests

Make the request to the Parts Command API asynchronous by transacting the incoming request onto a queue. As the persistence to the queue can be transacted a reliability pattern is implemented, so the initial client request will fail when the queue can’t consume the message.

CQRS 5

Once you start extending functionality with public and/or cloud-based APIs, you can use Anypoint MQ as a fully fledged broker in the cloud to implement asynchronous behaviour. This provides future-proof flexibility as you scale your application either in the cloud and on-premises.

Synchronous Query Requests

Querying data from your underlying Neo4j database is already fast and is simply proxied. In certain cases data could be enriched or optimized for specific channels.

CQRS 6

Finally the CQRS API treats Commands and Queries differently, depending on the requirements. There is no limitation to include Event Sourcing mechanisms here.

The CQRS API source code is available on GitHub.

Publish the CQRS API

Publishing the API requires just a click of a button with Anypoint Platform. A testable API Console is immediately available from your API Portal as shown in the screenshot below.

CQRS 7

As with the Query and Command API, add the tailored CQRS API you just built to Anypoint Exchange to make it available for discovery and reuse by other developers so they can build new capabilities on top of it.

With the front end implementation of your mobile experience API now finalized, your mobile developers can finalize their implementation. The next and final post of this series will cover the more traditional Enterprise Application Integration aspects required to deliver this scenario and describe how Mule is used to keep Neo4j and the SRM application’s database in sync.


We'd love to hear your opinion on this post

2 Responses to “API-led Connectivity and CQRS: API layering and the CQRS API implementation”

  1. I want to know how CQRS Pattern is used in this Scenario.
    As per my understanding Neo4j and Mysql DBs having same data. Right?
    and for reading purpose we have created a Query API and for writing Command API.

    but I am unable to understand what data is stored in those databases how can i see that data and modify it.

    Could you please provide the code for those databases.

    Please let me know its correct information.

    Reply me soon

    Agree(0)Disagree(0)Comment
    • Hello Azeema,

      thanks for your question.
      The MySQL DB and Neo4j are kept in sync with another Mule app and uses the Legacy MySQL as a base.
      See this post in the series:
      /dev/mule-dev/api-led-connectivity-and-cqrs-how-mule-supports-traditional-integration-tasks/

      You will find all code snippets how the apps work in GitHub also. The idea is:
      – Command API is used to update / add new information to MySQL
      – The legacy sync application listens to changes in MySQL and creates a Graph representation of the change in Neo
      – Query API abstracts Neos querying language to query the graph
      – Command and Query API are once again abstracted to deliver a perfect experience for a consuming app

      I hope that makes sense. I will dig out the MySQL schema and add it into the legacy app GitHub code as soon as I can.

      Cheers,
      Patrick

      Agree(0)Disagree(0)Comment