Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.

Content Versioning

Avatar

Level 3

Hello,

I have a requirement to support two different code and content versions at a time in AEM. We are not using the AEM for content rendering in front end, just as content repository. Front end will call AEM Service (Publish instance) which gives content in JSON format. Front end will iterate the JSON object and render the content. Multiple clients (JS and other java services) talk to AEM to get the content in JSON formats. 

In our infrastructure all the applications will be deployed independently in production (distributed environment). Lets say AEM JSON service is used by 5 clients, and if AEM Service will return 5 json attributes.

If there is a requirement to get rid of one if the JSON attributes which results in 4 json attributes. If we deploy the new code in AEM only, that will break the existing clients with json structure changes (Applications which are consuming AEM will be deployed in different times). I am solving this problem as below.

We have 4 publish instances, out of which two will point to the old code and content, other two to the new code and content. When client hits publish 1,2 will get the older JSON structure as is, if they hit p3,p4 will get new json contract. But this solution needs lot of maintenance. 

 

Please suggest me for any better approach.

7 Replies

Avatar

Level 10

So you are using AEM simply as a repository and then invoke it to get JSON data about JCR content (talk to AEM to get the content in JSON formats). But you want control over what content is returned in JSON. 

One way to solve this use case is to write custom sling servlets and then have the external clients invoke the servlets. Then in the Java logic of the servlets - you can return JSON based on the latest versions. That is - external clients  can perform a GET request and pass an argument to determine what content to get. 

Using AEM in this manner is not really a standard use case.

Avatar

Level 10

Multiple approaches I can think of

1. If you want multiple json formats for each clients, then expose the json via a servlet service

2. or you can just keep sending all the 5 attributes and in your client just use the attributes it needed !

3. Create a different content with the different set of attributes through which you can access the json of respective content

Avatar

Administrator

Hi 

As mentioned by Scott, you need to write a custom Sling Servlets, this will act as creating a restful api in AEM.

You would need to call this rest API from you front-end and can get configured JSON as a response to this.

Community article :- https://helpx.adobe.com/experience-manager/using/custom-sling-servlets.html

// this is a example code to creating a restful api in AEM. Here in this "dopost" methid is catering all the request done for "url:'/bin/mySearchServlet'".

Front-end :- Do Ajex call to url:'/bin/mySearchServlet'

Back-end : AEM's dopost/doget method caters them and reply accordingly.

 

You can write a custom logic that you were referring to.

 

Some reference examples are listed below:-

Link:- https://helpx.adobe.com/experience-manager/using/querying-experience-manager-data-using1.html

Link:- https://helpx.adobe.com/experience-manager/using/programmatically-accessing-cq-content-using.html

 

I hope this would be some help to you.

Thanks and Regards

Kautuk Sahni



Kautuk Sahni

Avatar

Level 9

In my view, in this particular scenario, no matter what we create/develop, this problem will not go away. The reason is that we want to maintain two code bases and don't have a generic JSON structure for the external client.

I have a few questions, why don't we have generic JSON Format and does consumers of json (external client) expect different formats?. If there is any change in json attributes, why does client code break?. Do we have a fixed number of iterators to read json content?.

---

Jitendra

AEM dev wrote...

Hello,

I have a requirement to support two different code and content versions at a time in AEM. We are not using the AEM for content rendering in front end, just as content repository. Front end will call AEM Service (Publish instance) which gives content in JSON format. Front end will iterate the JSON object and render the content. Multiple clients (JS and other java services) talk to AEM to get the content in JSON formats. 

In our infrastructure all the applications will be deployed independently in production (distributed environment). Lets say AEM JSON service is used by 5 clients, and if AEM Service will return 5 json attributes.

If there is a requirement to get rid of one if the JSON attributes which results in 4 json attributes. If we deploy the new code in AEM only, that will break the existing clients with json structure changes (Applications which are consuming AEM will be deployed in different times). I am solving this problem as below.

We have 4 publish instances, out of which two will point to the old code and content, other two to the new code and content. When client hits publish 1,2 will get the older JSON structure as is, if they hit p3,p4 will get new json contract. But this solution needs lot of maintenance. 

 

Please suggest me for any better approach.

 

Avatar

Level 3

    Let me explain the problem in detail. Instead of custom sling servlet (with query params) i would like to go with JSON rendition as the content will be cached at dispatcher.

Multiple versions of code : I wanted to support two versions of a service on the same instance. Lets say if we create a json.jsp(custom json implemenation which will return 4 attributes in response) for particular template, when user hits https://.....content/../page1.json it returns 4 attributes. Wanted to implement another version of json service which returns 3 attributes which operates on the same content. I can solve this problem with below structure.
/apps/projectname/components/pageComponent (
pageComponent.jsp
v1/json.jsp -- https://...content.../page1.v1.json (return 4 attributes, attr1, attr2, attr3, attr4) 
v2/json.jsp -- https://...content.../page1.v2.json (return 3 attributes, key1, key2, key3 (all the key names are renamed)

Multiple versions of a content: Assume there is a component authoring dialog has three fields (text field and two RTE). In textfield, content author has to put some placeholder like {{page1}}, and input some data in other RTE fields. JSON service will return the content as below
{"key1": "{{page1}}", "key2":..., "key3"...}.

Front end will replace {{page1}} with something as per the logic (assume this is in production). As part of next AEM release, lets say user need to put the actual content in textfield1 instead of place holder. If we deploy this code in production and it start sending response as {"key1": "content1", "key2":..., "key3"... } which will break the front end as it is still expecting the placeholder (Front end application will be deployed in different times). To solve this problem we need to have two different versions of a page, servicec. Service 1 will operate on page 1 which should return placeholder and second service should return actual content.

We can solve this problem as below.
We have 4 publish instances, out of which two will point to the old code and content, other two to the new code and content. When client hits publish 1,2 will get the older JSON structure as is with placeholder, if they hit p3,p4 will get new json contract. But this solution needs lot of maintenance and code duplication. 

Avatar

Employee Advisor

My understanding is that you have multiple clients and each of them are consuming content in JSON format. Each of your clients are separate applications which may have independent build and deploy cycles with respect to AEM. So, you do not want to break the URL contracts with them as that would need code changes at the client side. 

First of all your assumption that servlets can not be cached at dispatcher is wrong. Instead of using query parameters you can use Sling selectors in the URL which can be cached by the dispatcher. 

Secondly to solve the problems of URL contracts - 

1. Isn't it possible to design your clients in such a way that they can ignore the JSON parsing if the placeholder is not present in the value or if a certain attribute is present in the JSON then turn off the processing?  

2. You can set custom response headers in your JSPs which can be read by your clients when they request the JSON. In the response headers you can pass the custom metadata information  which can tell the clients that for this page processing is not needed. 

Avatar

Level 10

For you usecase, I echo @kunal23 which also the option 2 which I have mentioned.

You need to handle that in your client to use the attributes required.