1
votes

In my project we have few servlets that are osgi components and have properties tied to them. Like

@Component(label = "Default Address Servlet", immediate = true)
@Service(value = Servlet.class)
@Properties(
    @Property(name = "sling.servlet.resourceTypes", value = { "sling/servlet/default" }),
    @Property(name = "sling.servlet.selectors", value = { "defaultaddress" }),
    @Property(name = "sling.servlet.extensions", value = { "json" }),
    @Property(name = "sling.servlet.methods", value = { "POST" }), 
    @Property(name = "prop1", value = { "value1" }) })
public class SetDefaultAddressServlet extends SlingAllMethodsServlet {

Now I have a requirement to use this prop1 inside a sling model class during a load of a component. While technically servlets are osgi components, it is ok to reference this servlet as osgi component? Like

@Model(adaptables = SlingHttpServletRequest.class)
public class Address {

    @Inject
    @Reference
    private SetDefaultAddressServlet service;

Though this technically works right, is it a good approach? Or alternate, I need to create separate OSGi service with the respective property and reference it. What is the advisable approach?

2

2 Answers

1
votes

It's a philosophical question, rather than technical because nobody can give you 100% correct answer, but I will put my opinion there.

I prefer applying Hexagonal Architecture to my code (original post on this pattern or another great one) wich brings to your application high maintainability.

One of its main ideas is that dependencies should point inwards - so external world depends on your servlet, servlet depends on your business layer.

Servlet can be treated here as an adapter between external world and your business logic. Sling Model is just the same - it is sitting between your html page and service.

And according to this design pattern, it's a bad idea to reference one adapter from another.

Also, there is a light code smell: what do these classes need this property for? Should the code, which needs the same property be placed in 2 different places, rather than in one small Util class or Service?

Again, it's just my opinion.

1
votes

Just to add on the previous answer from another user and given that it's not a solid code architecture approach, in the AEM context, this is also not a good approach.

Your model (Address) is dependent on a service implementation. A servlet has a lot of information in it related to the HTTP request and normally this model does not need access to all the heavy information in the HTTP servlets.

You probably want to access some limited set of properties in the HTTP request and transform them into a POJO model and these properties can be a part of request information. In such cases you are better off making an adaptable from HttpRequest or some more value centric object which can be extracted from your request.

Also, think of code-smells as pointed by other users. What's stopping the Address object from calling Servlet methods on the referenced class and modifying the state of the request (like accessing the session etc.)

Again, it works but it's not the best way given that there are better ways just by limiting it to AEM best practices. I would recommend that you read the following article:

https://sling.apache.org/documentation/bundles/models.html

Hope this helps