Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

CREATE RESTFul service in AEM 6

Avatar

Level 3

Hi, I have already done some investigation on how to do this.. but, no luck so far.. Any help would be much appreciated.

I need to CREATE a Rest Service in AEM that will be accessed by a mobile application. The service should perform actions like return list of countries supported, return list of regions in the country etc.. in JSON format

So, the URLs will be something like

http://abc.com/myservice/countries

http://abc.com/myservice/regions/uk

 

I need these REST services to be created in AEM as these information are stored in AEM JCR repository and can be modified by authors.

Can someone please let me know how to create REST Webservice in AEM (Please, not a bundle accessing third party web service).

Please correct me if I'm on wrong direction.

Thanks

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Hi,

when you request a page in AEM, there's always a resource behind it. Pages can be changed by authors, thus you just need to create the correct rendition for it.

To get into the right direction I would recommend you start in a way like this.

1) Create a page structure, which reflect the elements you want to have. For example:

  • /content/regions/europe
  • /content/regions/europe/uk
  • /content/regions/europe/germany
  • /content/regions/americas
  • /content/regions/usa
  • /content/regions/canada

2) Then give it a try:

These renderings are provided by the Default Get Servlet of sling and probably contain too much information, but ignore that for a moment. Now add more regions and more countries and try again.

You will see, that any changes are immediately reflected in the response. And the URLs look quite readable, and you don't need to register any servlet. Please note, that this just an experiment to demonstrate, how you could do that within AEM.

When you want to move that into more production-like code, you're likely to provide your own servlet to create the correct output (maybe using a special selector). But the basic idea is the same: Request a resource and then use the right rendition. For example this rendition can list all child resources in a special format you can consume. Or something else.

kind regards,
Jörg

View solution in original post

6 Replies

Avatar

Correct answer by
Employee Advisor

Hi,

when you request a page in AEM, there's always a resource behind it. Pages can be changed by authors, thus you just need to create the correct rendition for it.

To get into the right direction I would recommend you start in a way like this.

1) Create a page structure, which reflect the elements you want to have. For example:

  • /content/regions/europe
  • /content/regions/europe/uk
  • /content/regions/europe/germany
  • /content/regions/americas
  • /content/regions/usa
  • /content/regions/canada

2) Then give it a try:

These renderings are provided by the Default Get Servlet of sling and probably contain too much information, but ignore that for a moment. Now add more regions and more countries and try again.

You will see, that any changes are immediately reflected in the response. And the URLs look quite readable, and you don't need to register any servlet. Please note, that this just an experiment to demonstrate, how you could do that within AEM.

When you want to move that into more production-like code, you're likely to provide your own servlet to create the correct output (maybe using a special selector). But the basic idea is the same: Request a resource and then use the right rendition. For example this rendition can list all child resources in a special format you can consume. Or something else.

kind regards,
Jörg

Avatar

Level 10

AEM supports Restful services. Simply create Sling Servlets that can be accessed using an HTTP GET or HTTP POST.

 If you  want to get page data, you can use default sling Get servlets as Joerg points out.

However - if you want to get non-page data - for example - a list of DAM assets in XML or pull data from a 3rd party database, encode the data into a specific JSON structure, and serve that data as the servlet's response - then you need to write your own Servlets. Rest of this is about that use case.

YOu can write custom application logic in the Servlets to perform business logic to meet your business requirements. For example, you can use the JCR API within the servlet to perform CRUD operations on JCR Data or JDBC data to get data from an external database (you can do what ever you want to meet your business requirements). 

As far as getting a Sling Servlet to return JSON - see this community article that shows how to write a Sling Servlet that returns JSON data:

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

This servlet uses the org.json.simple.JSONObject object to create JSON formatted data on the back end. 

https://code.google.com/p/json-simple/

Now this article invokes the servlet from a CQ page. However - you can easily hit the AEM Servlet from other apps that support Restful operations - including a mobile app. 

Now with respect to mobile apps - you can create mobile apps using AEM as well. See this Ask the Community Experts session on getting started with AEM and mobile apps:

Ask the Community Experts Session: Getting Started with AEM Apps

So the mobile app can perform a GET or POST to the AEM Servlet.

Here is another example of a Java Swing app invoking an AEM sling servlet:

https://helpx.adobe.com/experience-manager/using/post_files.html

In this example - a Java app uses a Restful call to pass files to an AEM servlet.  There is also another example of writing a sling servlet. 

Hope this points you in the right direction

Avatar

Level 3

Thanks Scott for the reply and guiding me on the right direction.

So, Sling Servlet is the best way to implement this. I know that AEM has ability to develop mobile apps, but our mobile apps have been developed by a third party and is in the last stage.

Coming back to my question, say I have the path defined in my servlet as "/bin/myServlet", I will be accessing this servlet with the following URL

http://abc.com/bin/myServlet

Now, how do I pass the parameters to the servlet in a RESTful way? like..

http://abc.com/bin/myServlet/countries

http://abc.com/bin/myServlet/regions/uk

 

I know I can pass then as request parameter with question mark in the URL. In that case, dispatcher will not cache the JSON response. I would like the response to be cached as they don't change often.

Please suggest..

Thanks

Avatar

Level 3

Hi Jörg,

Thanks for the information. That was very helpful and now I know what to implement.

So to summarize, I can create a servlet with a particular path (bin/location) and then access the servlet with selectors specifying whether to return countries or regions and their ids if needed as below:

http://abc.com/bin/location.json   - Returns all countries

http://abc.com/bin/location.regions.uk.json   - Returns all regions in UK

Thanks.

Avatar

Level 10

Use a standard like AJAX to hit the servlet and pass information - notice the example in the article i specified. Also  - more info:

http://sonycharan.blogspot.ca/2014/03/how-to-call-servlet-using-ajax-calling.html

And yeah - given:

@SlingServlet(paths="bin/myServlet/mycountry", methods = "POST", metatype=true)
public class HandleFile extends org.apache.sling.api.servlets.SlingAllMethodsServlet {

 

 

http://abc.com/bin/myServlet/mycountry

Create a 2nd servlet for http://abc.com/bin/myServlet/regions/uk

Each should have unique app logic too. That is the powerful thing about AEM - the ability to create these custom Servlet and invoke them from different clients.  

Avatar

Level 3

Hi Scott,

I think I didn't explain the situation in detail.

http://abc.com/bin/myServlet/mycountry - returns list of countries which is authored list

The second service to return list of regions are based on the country list returned by the first service. So, it is not feasible for me to create / modify the servlets whenever authors add or delete countries. 

In short, "uk" is the parameter passed to the servcice. So I will have REST URLs like below that will return regions within those countries

http://abc.com/bin/myServlet/regions/uk

http://abc.com/bin/myServlet/regions/us

http://abc.com/bin/myServlet/regions/de

Thanks,