Sling Models Done Right: From Boilerplate to Clean Architecture

If you have worked with Adobe Experience Manager (AEM) for more than a few months, you have likely encountered massive Sling Models filled with repetitive boilerplate code. You know the ones: endless @Inject annotations, manual null checks, and adaptable declarations that span multiple lines.

It doesn't have to be this way. In this guide, we will explore how to write clean, modern Sling Models for AEM 6.5 and AEM as a Cloud Service (AEMaaCS).

The Problem with Old Sling Models

Historically, developers used the generic @Inject annotation for everything. This caused several issues:

The Modern Approach

Instead of @Inject, we should use specific injector annotations. Here is an example of a perfectly structured Sling Model:

package com.mishraventures.aem.core.models;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;

@Model(
  adaptables = Resource.class,
  defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class HeroComponent {

  @ValueMapValue
  private String title;

  @ValueMapValue(name = "jcr:description")
  private String description;

  public String getTitle() {
    return title;
  }

  public String getDescription() {
    return description;
  }
}

Why is this better?

By using @ValueMapValue, we explicitly tell Sling to only look in the ValueMap (the properties of the node). This is significantly faster. Furthermore, by using DefaultInjectionStrategy.OPTIONAL, we prevent the model from completely failing if a single non-critical property is missing from the JCR.

Lombok: The Ultimate Boilerplate Killer

If your project allows it, Project Lombok can eliminate the need for getter methods entirely. By annotating the class with @Getter, Lombok generates the methods at compile time, leaving your source code incredibly clean.

However, always ensure that your AEM Maven archetype is properly configured to handle Lombok during the build phase, or you will run into pipeline errors in Cloud Manager.

Summary

Stop using @Inject. Start using specific annotations like @ValueMapValue, @ChildResource, and @OSGiService. Default your injection strategy to optional, and keep your Sling Models strictly focused on retrieving and formatting data for your HTL scripts.

Loved this article?

Get more AEM deep-dives and development tips delivered to your inbox.