Expand my Community achievements bar.

SOLVED

What is the best way to name my servlet paths like an RESTFUL API? (Path vs ResourceType)

Avatar

Level 7

Hello, 

 

Question 1.

Currently we have a servlet endpoint like /bin/api/v3/pagestatus, how can I change the URL in AEM in a nice way, so I can use something like /api/v3/pagestatus

 

Question 2.

Currently we have a servlet using resource type, which can be accessed like /content/mysite/api/v2/pagestatus.json, how can I change the URL in AEM in a nice way, so I can use something like /api/v3/pagestatus

 

Thank you!

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @AEMWizard 

 

For #1, If you have only a limited number of servlets using /bin/api/v3/anything and you want to change all of these URLs pattern, you can directly make the change in the Servlet and allow /api path with "servletresolver.paths" property in Apache Sling Servlet/Script Resolver and Error Handler OSGi configuration.

 

If there are more number of servlets and if you feel it's difficult to change it then you can apply etc/maps redirects here as well like I am doing below.

 

But I will suggest you should move to resource type based servlet than using path based as it's more secure and provided better control over code.

 

For #2, you can apply URL shortening rules using etc/maps and it will shorten as per your need. Please see the rules below:

 

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:Mapping"
sling:internalRedirect="/content/mysite/api/v2/(.*).json"
sling:match="www.mysite.com/api/v3/$1"/>

 

Adding a regex will ensure that any new resource addition in future will automatically shortened and the pattern will be maintained consistently.


Add the below redirect in dispatcher if you do not receive the actual URL at the publish instance. This will be used for the reverse mapping of the resource when it is requested from dispatcher.

 

RewriteCond %{REQUEST_URI} ^/api/v3/(.*)
RewriteRule ^/api/v3/(.*) /content/mysite/api/v2/$1.json [PT,L]

 

Binding servlets by paths has several disadvantages when compared to binding by resource types, namely:

1. path-bound servlets cannot be access controlled using the default JCR repository ACLs
2. path-bound servlets can only be registered to a path and not a resource type (i.e. no suffix handling)
3. if a path-bound servlet is not active, e.g. if the bundle is missing or not started, a POST might result in unexpected results. usually creating a node at /bin/xyz which subsequently overlays the servlets path binding
4. the mapping is not transparent to a developer looking just at the repository

 

Given these drawbacks it is strongly recommended to bind servlets to resource types rather than paths.

 

Hope this helps!

 

Thanks!

View solution in original post

3 Replies

Avatar

Correct answer by
Community Advisor

Hi @AEMWizard 

 

For #1, If you have only a limited number of servlets using /bin/api/v3/anything and you want to change all of these URLs pattern, you can directly make the change in the Servlet and allow /api path with "servletresolver.paths" property in Apache Sling Servlet/Script Resolver and Error Handler OSGi configuration.

 

If there are more number of servlets and if you feel it's difficult to change it then you can apply etc/maps redirects here as well like I am doing below.

 

But I will suggest you should move to resource type based servlet than using path based as it's more secure and provided better control over code.

 

For #2, you can apply URL shortening rules using etc/maps and it will shorten as per your need. Please see the rules below:

 

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:Mapping"
sling:internalRedirect="/content/mysite/api/v2/(.*).json"
sling:match="www.mysite.com/api/v3/$1"/>

 

Adding a regex will ensure that any new resource addition in future will automatically shortened and the pattern will be maintained consistently.


Add the below redirect in dispatcher if you do not receive the actual URL at the publish instance. This will be used for the reverse mapping of the resource when it is requested from dispatcher.

 

RewriteCond %{REQUEST_URI} ^/api/v3/(.*)
RewriteRule ^/api/v3/(.*) /content/mysite/api/v2/$1.json [PT,L]

 

Binding servlets by paths has several disadvantages when compared to binding by resource types, namely:

1. path-bound servlets cannot be access controlled using the default JCR repository ACLs
2. path-bound servlets can only be registered to a path and not a resource type (i.e. no suffix handling)
3. if a path-bound servlet is not active, e.g. if the bundle is missing or not started, a POST might result in unexpected results. usually creating a node at /bin/xyz which subsequently overlays the servlets path binding
4. the mapping is not transparent to a developer looking just at the repository

 

Given these drawbacks it is strongly recommended to bind servlets to resource types rather than paths.

 

Hope this helps!

 

Thanks!

Avatar

Community Advisor

Hi @AEMWizard ,

                             Yes, whatever you want name for the servlet you can give it but make sure you need to add the same servlet name or path to the apache sling servlet script resolver configuration.

 

Kr,

Sanjay

Avatar

Community Advisor

Hi @AEMWizard 
It is recommeded to use resourceType to register the servlet.

Though you can add redirect mapping at apache to create short urls.



Arun Patidar