Saturday, March 21, 2020

Liferay 7/DXP JAX-RS Rest Services Introduction


Liferay is leveraging JAX-RS implementation to generate portal services to outside world. Liferay 7/DXP provided inbuilt capability to use JAX-RS implementation in OSGi modules with simple configuration in code level.  Rest of the code and services implementation will follow the same as JAX-RS compliance.

Liferay implemented OAtuh2 Authorization to secure JAX-RS services which is exposed from Liferay Portal Modules and its inbuilt capability provided by Liferay 7/DXP Portal.
Liferay 7/DXP used the JAX-RS Whiteboard design pattern implementation to make use of JAX-RS in Liferay OSGi Module Framework.


Liferay Rest Module Application Component have following two properties.
Rest Service Base Path

Service name that is available in OAuth portal configuration

Example


@Component(
       property = {
             JaxrsWhiteboardConstants.JAX_RS_APPLICATION_BASE + "=/liferaysavvy",
             JaxrsWhiteboardConstants.JAX_RS_NAME + "=LiferaySavvy.Rest"
       },
       service = Application.class
)
public class Liferay72EmployeeRestApplication extends Application {

}


We can use all JAX-RS annotation in the Application component class to expose services
Example


@Component(
       property = {
             JaxrsWhiteboardConstants.JAX_RS_APPLICATION_BASE + "=/liferaysavvy",
             JaxrsWhiteboardConstants.JAX_RS_NAME + "=LiferaySavvy.Rest"
       },
       service = Application.class
)
public class Liferay72EmployeeRestApplication extends Application {

       @GET
       @Produces("text/plain")
       public String working() {
             return "It works!";
       }

       @GET
       @Path("/morning")
       @Produces("text/plain")
       public String hello() {
             return "Good morning!";
       }
}


Instead of writing all service implementation methods in one component class we can use JAX-RS Resources to provide services implementation.

JAX-RS resources is a java class which will handle the all incoming requests based on URL. Resource class have methods which distinguish each request with help of JAX-RS annotations like @Path and each method will fulfill specific requirement.

We have to add these JAX-RS resources to Application singleton set, for this we need to override getSingletons method in Application Component class. We can add as many as resources to the set.

Example:

      
      @Override
       public Set<Object> getSingletons() {
            
             Set<Object> singletons = new HashSet<Object>();
             //add the automated Jackson marshaller for JSON.
             singletons.add(new JacksonJsonProvider());
            
             // add Employee REST endpoints (resources)
             singletons.add(new EmployeeResource());
             return singletons;
       }


JAX-RS Resource some of the important annotations


@Path("<RESOURCE/METHOD-PATH>/<PAT")
@GET
@POST
@PUT
@DELETE
@Produces("<Media-Type>")
@Consumes("<Media-Type>")


Example Usage


@Path("/employee")
@GET
@POST
@PUT
@DELETE
@Path("{id}")
@Produces("application/json")
@Consumes("application/json")


Example Resource Class


@Path("/employee")

public class EmployeeResource {
       @GET
       @Produces("application/json")
       public List<Employee> getAllPeople() {
         // Implementation
       }
      
       @GET
       @Path("{id}")
       @Produces("application/json")
       public Response getEmployee(@PathParam("id") String id) {
             // Implementation  
       }
            
       @POST
       @Consumes("application/json")
       @Produces("application/json")
       public Employee addEmployee(Employee newEmployee) {
             // Implementation  
       }
      
       @PUT
       @Path("{id}")
       @Consumes("application/json")
       @Produces("application/json")
       public Response updateEmployee(Employee newEmployee, @PathParam("id") String id) {
            // Implementation   
     }
      
     @DELETE
     @Path("{id}")
     public Response deleteEmployee(@PathParam("id") String id) {
          // Implementation
       }
      
}
      

Example Rest Endpoints as follows


Add Employee --> Request Type: POST


GET All Employees --> Request Type: GET


Get Employee --> Request Type: GET


Delete Employee --> Request Type: DELETE


UPDATE Employee --> Request Type: PUT


To provide Automated Object Marshaling and Un-Marshaling feature we have to use Jackson libraries. JacksonJsonProvider will provide these capabilities and we have to add JacksonJsonProvider in singleton set.

Example:

      
      @Override
       public Set<Object> getSingletons() {
            
             Set<Object> singletons = new HashSet<Object>();
             //add the automated Jackson marshaller for JSON.
             singletons.add(new JacksonJsonProvider());
            
             // add Employee REST endpoints (resources)
             singletons.add(new EmployeeResource());
             return singletons;
       }


Before use Jackson features in modules, we have to deploy Jackson OSGi modules in Liferay Module Framework. Deploy following Jackson OSGi module jar files in Liferay Portal “osgi/modules” directory.


jackson-core-2.10.3.jar
jackson-databind-2.10.3.jar
jackson-jaxrs-base-2.10.3.jar
jackson-module-jaxb-annotations-2.10.3.jar
jackson-annotations-2.10.3.jar
jackson-jaxrs-json-provider-2.10.3.jar


Gradle Module we have add above dependencies in buld.gradle file with CompileOnly scope.


compileOnly group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-json-provider', version: '2.10.3'
       compileOnly group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.10.3'
       compileOnly group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.10.3'
       compileOnly group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.10.3'
       compileOnly group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-base', version: '2.10.3'
       compileOnly group: 'com.fasterxml.jackson.module', name: 'jackson-module-jaxb-annotations', version: '2.10.3'


Maven module add same dependencies with provided scope

                          
                        <dependency>
                                    <groupId>com.fasterxml.jackson.jaxrs</groupId>
                                    <artifactId>jackson-jaxrs-json-provider</artifactId>
                                    <version>2.10.3</version>
                                    <scope>provided</scope>
                        </dependency>
                        <dependency>
                                    <groupId>com.fasterxml.jackson.core</groupId>
                                    <artifactId>jackson-annotations</artifactId>
                                    <version>2.10.3</version>
                                    <scope>provided</scope>
                        </dependency>
                        <dependency>
                                    <groupId>com.fasterxml.jackson.core</groupId>
                                    <artifactId>jackson-core</artifactId>
                                    <version>2.10.3</version>
                                    <scope>provided</scope>
                        </dependency>
                        <dependency>
                                    <groupId>com.fasterxml.jackson.core</groupId>
                                    <artifactId>jackson-databind</artifactId>
                                    <version>2.10.3</version>
                                    <scope>provided</scope>
                        </dependency>
                        <dependency>
                                    <groupId>com.fasterxml.jackson.jaxrs</groupId>
                                    <artifactId>jackson-jaxrs-base</artifactId>
                                    <version>2.10.3</version>
                                    <scope>provided</scope>
                        </dependency>
                        <dependency>
                                    <groupId>com.fasterxml.jackson.module</groupId>
                                    <artifactId>jackson-module-jaxb-annotations</artifactId>
                                    <version>2.10.3</version>
                                    <scope>provided</scope>
                        </dependency>  


Liferay JAX-RS OSGi Module Development
  1. Create Liferay OSGi Rest Module
  2. Create JAX-RS Resource Class
  3. Implement Required Rest Services with JAX-RS Annotations
  4. Override getSingletons method in Application component to add Resources and Providers to set Collection.
  5. Add Required Dependencies (Jackson libraries)
  6. Build and Deploy

Example to Access API End points




Author

0 comments :

Post a Comment

Recent Posts

Recent Posts Widget

Popular Posts