Developing Custom Service APIs

Liferay Objects provides a no-code way to define custom data models with dedicated REST APIs. However, you may need to customize Liferay's endpoints for complex scenarios, such as integrating external systems or orchestrating workflows. While this customization requires extensive coding (e.g., JAX-RS), Liferay's REST Builder accelerates development by automating code generation.

Diagram - Conceptual REST Builder Representation.png

In this lesson, you'll explore the architecture and strategic considerations for developing custom APIs with REST Builder.

Since REST Builder relies on deploying custom OSGi modules, it is only available for Liferay PaaS and Self-Hosted deployments. It is not available for Liferay SaaS.

Understanding REST Builder Implementations

REST Builder development centers around two configuration files: rest-config.yaml and rest-openapi.yaml. These files determine your API's structure and behavior. Once defined, you execute a Gradle task within your Liferay workspace to generate a significant portion of your API's required code. This generated code includes interfaces, resource classes, and other essential scaffolding. It also generates packages containing GraphQL endpoints, JAX-RS application code, and a resource package with your API implementation code.

image-20250528-182129.png

With the migration to Jakarta EE, you can include a property that indicates whether to use .javax or .jakarta for newer versions.

Before setting up REST Builder projects, it's essential to grasp additional concepts and prerequisites for successful implementations.

Preparing with Service Builder

Optimal API development using REST Builder begins with creating a corresponding Service Builder (SB) module. This establishes a foundation for managing entity permissions and provides structure for defining business logic, default permissions, and remote service methods. When constructing SB modules for REST Builder APIs, follow these best practices:

  • Database Persistence: Define and persist entities in the database using Liferay's Service Builder tool, configuring column types and relationships according to RDBMS best practices. See Service Builder for more information on creating SB modules.
  • Default Permissions: Specify default entity permissions in resources/actions/default.xml to ensure proper role-based access control (RBAC).
  • Remote Service Implementation: Configure service.xml to generate local and remote services, incorporating permission checks in your remote service methods using PermissionChecker.
  • REST Builder Integration: Use SB remote service methods within your REST Builder resource implementations, leveraging the effective user for permission checks when invoking remote SB services.

With your database framework in place, you can begin your API implementation.

Advantages of REST Builder

While Java API developers often turn to JAX-RS for creating RESTful services, Liferay's REST Builder offers distinct advantages within the Liferay ecosystem.

  • Automatic Framework Generation: REST Builder generates many elements you’d need to manually configure with JAX-RS (e.g., annotations, converters, multipart support, code structuring). By enforcing OpenAPI specifications, REST Builder ensures a consistent structure and behavior across all APIs, enhancing maintainability.
  • Streamlined Testing: Built-in templates simplify API unit and integration testing.
  • Liferay Integration: REST Builder leverages Liferay's built-in authentication, CORS handling, and headless capabilities for search, filtering, and paging.

While JAX-RS remains a viable option for specific business needs, REST Builder is often a better fit for Liferay development.

Best Practices for REST Builder Development

A well-defined plan for schema definition and API versioning is vital for successful REST Builder projects.

Schema and Endpoint Definition

Your schema's organization directly impacts REST endpoint performance. Consider these essential schema definition practices:

  • Minimize Network Latency: When designing your endpoint, consider how many requests a client would need to make to Liferay to retrieve all necessary information, especially if the entity has multiple relationships. Consider whether it would make sense to build business logic that merges related entities into a single response object.
  • Avoid Overly Granular Endpoints: Instead of creating a dedicated API to fetch a single attribute, consider returning the entire object and allowing consumers to filter fields via Liferay's built-in field selection support.
  • Optimize Large Objects: If a resource contains extensive data, consider adding query parameters to limit the returned fields.

API Versioning

API versioning ensures backward compatibility and smooth transitions for consumers. Consider these principles when determining whether versioning is appropriate:

  • Path Changes: Introduce a new version when modifying URL structures.
  • Schema Modifications: Introduce a new version when removing or changing fields in existing responses.
  • Optional Additions: Assess whether versioning is necessary when adding new optional fields that don't impact existing consumers.

Equally important is avoiding unnecessary versioning. Minimize breaking changes by designing APIs with forward compatibility in mind, and implement shims for legacy versions to transform responses to match newer versions when feasible. Whenever possible, continue supporting legacy API versions to avoid forcing consumers to upgrade immediately.

Conclusion

By automating the generation of complex framework code, Liferay's REST Builder significantly accelerates the development of custom headless APIs. Service Builder modules establish the foundational structure for business logic, permissions, and remote service methods. REST Builder then automates the generation of essential API project elements.

Next, you’ll learn about setting up REST Builder projects.

loading-knowledge-label