avatar
REST APIs AEM AEM

1. Writing OSGi configuration ui.config

ui.config
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config
---> com.flagtick.core.services.impl.FlagtickIntegrationServiceImpl.cfg.json
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.author
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.author.dev
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.author.prod
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.publish
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.publish.dev
+> ui.config/src/main/content/jcr_root/apps.flagtick.osgiconfig/config.publish.prod
Note: This is a new <PID>.cfg.json file. The PID is the Persistent Identity of the OSGi component. It is usually the full class name of the OSGi component implementation. Refer format for JSON here.
{
  "endPoint": "https://api.flagtick.com",
  "apiKey":"$[secret:FLAGTICK_API_KEY]"
}

2. Write service interface Method to DAO (Database)

ui.core
+> ui.core/src/main/java/com.flagtick.core/services/FlagtickIntegrationService.java
+> ui.core/src/main/java/com.flagtick.core/services/impl/FlagtickIntegrationServiceImpl.java

For example:

public interface FlagtickIntegrationService {
  LoginResponse login(Map<String, String> paramMap, String fcm_token);
}
/------------------------------------------------------------------------------/
@Component(
        immediate = true,
        service = FlagtickIntegrationService.class
)
@Designate(ocd = FlagtickIntegrationServiceImpl.Config.class)
public class FlagtickIntegrationServiceImpl implements FlagtickIntegrationService {
  
  private String endPoint;
  private String apiKey;
  
  @Activate
  protected void activate(Config config) {
     endPoint = config.endPoint();
     apiKey = config.apiKey();
  }

  @Override
  public LoginResponse login(Map<String, String> paramMap, String fcmToken) {
     // TODO
  }

  @ObjectClassDefinition(
        name = "FLAGTICK - Flagtick Service Configurations",
        description = "Flagtick Service Configurations"
  )
  protected @interface Config {
    
    @AttributeDefinition(
       name = "Login Endpoint",
       description = "URL endpoint for member login into the system",
       type = AttributeType.STRING
    )
    String endPoint();

    @AttributeDefinition(
       name = "API Key",
       description = "API Key",
       type = AttributeType.STRING
    )
    String apiKey();   
  }
}

3. Writing Servlet to help ajax or Front-end call request.

ui.core
+> ui.core/src/main/java/com.flagtick.core/servlets/LoginServlet.java

We will need to define resourceType with specific METHOD (GET/POST) to mapping action from ui.front-end site.

@Component(immediate = true, service = Servlet.class,
        property = {
                SERVICE_DESCRIPTION + VerifyUserServlet.SERVLET_SERVICE_DESCRIPTION,
                SLING_SERVLET_RESOURCE_TYPES + VerifyUserServlet.RESOURCE_TYPE,
                SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET,
                SLING_SERVLET_SELECTORS + VerifyUserServlet.SELECTOR,
                SLING_SERVLET_EXTENSIONS + "=" + Constants.EXTENSION_JSON
        })
public class LoginServlet extends SlingSafeMethodsServlet {
   public static final String RESOURCE_TYPE = "=flagtick/components/content/verification-form";
   public static final String SELECTOR = "=verify-user";

   @Reference
   transient private FlagtickIntegrationService flagtickIntegrationService;

   @Override
   protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)   throws IOException {
      // TODO
  }
}
Note: Resource Type + Selector => generate URL: http://localhost:4502/content/flagtick/us/en/verification/jcr:content/root/container/container/verification_form.verify-user.json?username=flagtick&password=Abc@123456

4. There are many different ways to pass data from AEM to JavaScript.

  • Using data-*

For example, use LoginFormComponent(login-form.html in ui.apps) to pass value. You can see structure of component in ui.app as below:

+> ui.apps/src/main/content/jcr_root/apps/flagtick/components/content/verification-form/verification-form.html

And there is an example HTL template:

<sly data-sly-use.templates="core/wcm/components/commons/v1/templates.html"
     data-sly-use.model="com.flagtick.core.models.FlagtickFormModel">
     <div class="flagtick-login"
       data-cmp-is="LoginForm"
       data-resource="${resource.path}"
       data-editmode="${wcmmode.edit ? 'true' : ''}">
       <!-- TODO -->
     </div>
</sly>
Note: LoginForm => LoginForm.ts or LoginForm.js. Using LoginModal as interface to get/set property from cq:dialog in AEM component.

5. Writing JS function to update code:

private async login(username: string, password: string): Promise<void> {
  const resource = this.$component.data('resource') as string;
  const editMode = this.$component.data('editmode') as string;
  const endpoint = `${resource}.${this.selector}.json?username=${username}&password=${password}`;
  if (!editMode) {
     await $.get(endpoint) { ... }
  }
}
24
You need to login to do this manipulation!