Introduction to CRISP API
CRISP is Common Resource model Interface and Service Provider module for External APIs (e.g, API Gateway), which is introduced by BloomReach to enable simple, seamless, enterprise-ready, and performant external services integration.
Also, Content aggregation and personalization become easier, more transparent and reliable in application development if you adopt CRISP module as an integration backbone.
The project source is located at https://code.onehippo.org/cms-community/hippo-addon-crisp.
Let's think about a typical integration scenario with an external (REST, Web Services, API, etc) service in an application:
You could think of having a common invoker service to retrieve data from the external backend services, so that each component in pages makes a call on the common invoker service. Just a typical scenario, right?
Now, the architectural questions like the following arise right away from our experiences again and again whenever we implement content delivery or content authoring tier applications:
- Performance / Efficiency: How can we guarantee an enterprise-level performance and efficiency when invoking the external backend services? How can we avoid duplicate requests from different components in single page rendering? How can we cache data for performance in delivery tier for instance?
- Security: The backend services could require secured access and/or authentication such as OAuth2, especially in enterprise environments. How can we easily provide secured acccess and authentication if required?
- Availability: The backend service invocation must not affect the mission-critical system's availability due to any system failure (e.g, OutOfMemory, too much processor cycle overhead, etc.). How can we easily ensure that?
- Configurability / Manageability: Suppose you want to integrate with SalesForce backend REST services as an example. You want to be able to change the connection configuration sometimes at runtime without having to redeploy or restart the server. How can we achieve that kind of runtime configurabililty without compromising any other quality attributes? How can we maximize manageability to avoid unnecessary redeployments or restarts?
- Modifiability: Sometimes you want to fix or improve the underlying integration service components. How can we develop the code or configuration faster and easier to meet the challenges?
- Cost-effectiveness: It looked simple at first. But now if you think of the quality attributes mentioned above (performance, efficiency, security, availability, configurability, manageability and modifiability), then you will realize that it's not that simple. Especially if you're concerned about cost vs. benefit, the problem becomes more complex. The question is, how can we achieve all those qualities in a very cost-effective manner?
To address all the architectural questions above, CRISP module was introduced. CRISP can be characterized this way:
- CRISP is a core software asset which is designed as highly reusable and performant in higher quality expectations.
- CRISP enables faster and more cost-effective product and project delivery process.
- CRISP gives developers abilities to integrate and aggregate a wide range of data sources, content and services via various mechanisms, such as API Gateway, ESB, REST, RSS, etc., without much effort.
- CRISP allows to integrate and aggregate external data and content without having to migrate data or content into single repository.
- CRISP provides a cost-effective, performant and reliable toolkit to integrate with any different backends such as Commerce APIs, SalesForce, Eloqua, Marketo, etc. for personalization and content aggregation, with increasing digital experiences.
- Lightweight Common Resource API and Service Provider for various enterprise data, content aggregation and personalization.
- Easy to use, highly performant and reliable message exchange backbone. E.g, built-in caching control under the hood.
- Highly customizable and configurable message routing for variants of use cases.
- Core software asset for products/projects.
- Generic External (REST) API service invoking broker service, ResourceServiceBroker.
- Generic resource object model, Resource, that enables easy access to resources and properties.
- Resource space routing configuration through Spring Framework bean configuration in repository.
- Caching service in ResourceServiceBroker level as well as ResourceResolver level, and it is easily configurable and customizable.
- ResourceServiceBroker can be used in both Content Delivery and Content Authoring applications.
- HTTP invocations through Spring Framework RestTemplate (including OAuth2-based RestTemplate configuration example) for more configurability and maintainability.
- Dynamic configuration management at runtime through repository configuration.
- Resource level pagination.
- API support to allow to implement a web-hook (in order to invalidate cache for instance) easily.
The following features are considered to be shipped in the future, too.
- Default implementation support for XML based Resource representations such as RSS Feeds.
- Example ResourceResolver and Resource implementations for custom Java API calls on the backends instead of JSON/XML in the demo project. For example, if a backend media server supports a full Java API encapsulating REST API payloads for developers, then the example can show how to implement a custom ResourceResolver and Resource for the backend.
- More ResourceResolver Spring bean configuration examples for different backends to be copied and pasted right away. Please let us know if you want to contribute some from your experiences! :-)
The following diagram depicts a higher level Components and Connectors View to show how CRISP module helps easier and more seamless integration for applications. Please note that this higher level diagram does not necessarily describes all the details as exactly as it is designed or implemented in the detail level though.
CRISP Broker component provides the following:
- Single broker to retrieve content and data from the backend APIs.
- Configurability with proper routings and executions at runtime.
- Automatic caching and invalidation capabilities of external data and content for better performance.
- Resource link resolution capabilities of external data and content.
How does CRISP address the architectural questions?
- Performance / Efficiency: CRISP provides resource object model caching by default in a generic way. For example, it creates a cache key based on resource space name, operation name, relative resource path, path variables, etc. and it may keep the cached data for a specified time interval (N minute for instance) for best performance under the hood. Application code may simply invoke ResourceServiceBroker API operations transparently without having to consider the details such as caching and invalidation by itself. CRISP will take care of the details for best performance for application developers. Also, applications can implement a "Web-Hook" very easily through transparent API to invalidate caches. In addition, CRISP provides clear API interfaces to serve backend services, generate links for the external resources, cache or invalidate cache the resources, and so on.
- Security: CRISP adopts Spring Framework's RestTemplate, OAuth2RestTemplate, etc. for enterprise-ready secured REST service invocations with examples by default.
- Availability: CRISP implements all the service components very carefully to meet enterprise quality attributes to guarantee availability quality requirements.
- Configurability / Manageability: CRISP provides all the configuration in the repository. So, administrator may update the configuration stored in the repository and all the changes will be reflected at runtime on the fly without having to worry about redeployments or restarts at all.
- Modifiability: CRISP is designed with very clean APIs and taking advantage of Spring Framework, Spring Security Framework, Spring Security OAuth Framework, etc. to maximize productivity and modifiability. Also, CRISP provides a generic model API for any different backend data through Resource interface which can be used in the templates without any more code implementation for the models, which increases development productivity a lot.
- Cost-effectiveness: CRISP already solves all the backend integration requirements in a generic way. So, enterprise-ready, high-quality integration module can be simply done through simple configurations and minimal code / template implementations in most use cases.
The following diagram depicts a higher level Module View to show how CRISP module is composed of multiple submodules with dependencies. Please note that this higher level diagram does not necessarily describes all the details as exactly as it is designed or implemented in the detail level though.
- CRISP API submodule contains all the public APIs (interfaces and abstract base classes) that applications can depend on.
- CRISP CORE submodule contains core components and services that either implement public APIs or internal services.
- CRISP Repository submodule contains repository boostrap configurations, repository addon module to register/unregister configuration change event listener, etc.
- CRISP HST submodule contains utilities and tag libraries that can be used in Hippo CMS delivery tier applications.