Recently I've been experimenting with Liferay's new headless API. Specifically, it's a React-based SAP that leverages headless delivery and headless user management modules. We'll cover the implementation four times, but this time we'll show you how to use the REST Builder tools to create your own headless API.
You may have the following questions here.
"_Why use REST Builder instead of your own REST based on traditional JAX-RS? _"
Liferay's REST Builder does more than just build an application that exposes endpoints. It also provides the following additional features: :
--Integration with Liferay's authentication pipeline --Integration with Liferay's handling of CORS --Headless facility to support integration with Liferay search, filtering, paging, etc. --JSON or XML generation function for caller request --Integration with the upcoming Liferay GraphQL endpoint for use via GraphQL without customizing the REST Builder API --Ensuring consistency for mobile and SPA application developers.
You don't have to use all of these, just use these features in the right place.
In this article, which marks the beginning of the blog series, we'll show you the main parts of the YAML file that sets up a project to use the new REST Builder and defines entry points. Since this article will be long, I will divide it into several parts, starting with the definition of the service path (entry point) and explaining the construction of the service.
Before you start, Liferay's official documentation on how to use REST Builder (https://portal.liferay.dev/docs/7-2/appdev/-/knowledge_base/a/generating-apis-with-rest- Please read builder). It doesn't take long to read the article, so please come back to this article after reading it.
Run the following command to create a working project:
blade init -v 7.2 vitamins
This time, we named the project "** Vitamin **" to make it easier to imagine the structure of the project. This project consists of vitamins and minerals, which need to hold more vitamins and minerals than web content. Therefore, a custom service layer (Service Builder) is required in addition to the headless REST layer (REST Builder).
Then load your project into the IDE and follow these steps to edit the build.gradle file with the headless-vitamins-impl module (discussed later): https://portal.liferay.dev/docs/7-2/reference /-/ knowledge_base / r / rest-builder-gradle-plugin
build.gradle
in the headress- <name> -impl
module, as a caveat not mentioned in the reference article. It goes into a file, not the settings.gradle
file or the root level build.gradle
file. In this case, if you try to put the build script in the settings.gradle
file, you will get an unexpected error like ʻorg.gradle.initialization.DefaultSettings_Decorated cannot be cast to org.gradle.api.Project`. If this happens, it means that your REST Builder plugin is listed in an incorrect file. *You can verify that REST Builder is actually available by running the ./gradlew tasks
command inside the headless-vitamins-impl
module:
$ ./gradlew tasks
> Task :tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildCSS - Build CSS files.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildLang - Runs Liferay Lang Builder to translate language property files.
buildNeeded - Assembles and tests this project and all projects it depends on.
buildREST - Runs Liferay REST Builder.
...abridgement...
I need a set of modules, so I put headless-vitamins-api
,headless-vitamins in the
modules / headless-vitamins folder in the workspace (I created this subdirectory to put the headless modules together). Create -impl
, headless-vitamins-client
, and headless-vitamins-test
. The reference documentation doesn't mention creating these additional modules, but you'll need them, as we'll see later.
$ cd modules/headless-vitamins
$ blade create -t api -v 7.2 -p com.dnebinger.headless.vitamins headless-vitamins-api
Successfully created project headless-vitamins-api in vitamins/modules/headless-vitamins
$ blade create -t api -v 7.2 -p com.dnebinger.headless.vitamins headless-vitamins-impl
Successfully created project headless-vitamins-impl in vitamins/modules/headless-vitamins
$ blade create -t api -v 7.2 -p com.dnebinger.headless.vitamins headless-vitamins-client
Successfully created project headless-vitamins-client in vitamins/modules/headless-vitamins
$ blade create -t api -v 7.2 -p com.dnebinger.headless.vitamins headless-vitamins-test
Successfully created project headless-vitamins-test in vitamins/modules/headless-vitamins
Since I specified ʻapias the type when creating the module with the above command, some unnecessary packages and java files are also generated. It will take some time to clean up these. You also need to rename the
src / mai directory in the
headless-vitamins-testdirectory to
src / testIntegration`.
For this project, REST Builder will generate some integration test cases, but you need the appropriate directories for them to work.
The bnd.bnd file is updated with com.dnebinger.headless.vitamins.api
and com.dnebinger.headless.vitamins.impl
symbolic names, etc. to follow Liferay's standard naming conventions for bundles. The build.gradle
file will require a lot of additions, but it's a breather.
From here it will gradually become fun. Let's create a YAML file to define the service endpoint. If this is your first time doing this, you may find it daunting.
First of all, as a simple task. You need to add the rest-config.yamlfile inside
headless-vitamins-impl`.
apiDir: "../headless-vitamins-api/src/main/java"
apiPackagePath: "com.dnebinger.headless.vitamins"
application:
baseURI: "/headless-vitamins"
className: "HeadlessVitaminsApplication"
name: "dnebinger.Headless.Vitamins"
author: "Dave Nebinger"
clientDir: "../headless-vitamins-client/src/main/java"
testDir: "../headless-vitamins-test/src/testIntegration/java"
It's a collection of the elements you've created that Liferay's headless needs to work. The last two entries refer to the client and the test. Therefore, this work should be done first.
Then work with the rest-openapi.yaml
file. This file is also created inside the headless-vitamins-impl
module. Instead of throwing everything away at once, here's a step-by-step understanding of the details. All file structures can be found in this repository (https://github.com/dnebing/vitamins).
Each OpenAPI YAML file consists of three sections, ** Meta **, ** Paths ** (endpoints) and ** Reusable Components ** (type definitions), and is no different from the one created this time.
My meta section is:
openapi: 3.0.1
info:
title: "Headless Vitamins"
version: v1.0
description: "API for accessing Vitamin details."
We are making good progress so far.
Next, share the reusable component you just created. These don't work on their own, but they do lighten the burden of covering Paths later.
My main type and "vitamin" type:
components:
schemas:
Vitamin:
description: Contains all of the data for a single vitamin or mineral.
properties:
name:
description: The vitamin or mineral name.
type: string
id:
description: The vitamin or mineral internal ID.
type: string
chemicalNames:
description: The chemical names of the vitamin or mineral if it has some.
items:
type: string
type: array
properties:
description: The chemical properties of the vitamin or mineral if it has some.
items:
type: string
type: array
group:
description: The group the vitamin or mineral belongs to, i.e. the B group or A group.
type: string
description:
description: The description of the vitamin or mineral.
type: string
articleId:
description: A journal articleId if there is a web content article for this vitamin.
type: string
type:
description: The type of the vitamin or mineral.
enum: [Vitamin, Mineral, Other]
type: string
attributes:
description: Health properties attributed to the vitamin or mineral.
items:
type: string
type: array
risks:
description: Risks associated with the vitamin or mineral.
items:
type: string
type: array
symptoms:
description: Symptoms associated with the vitamin or mineral deficiency.
items:
type: string
type: array
creator:
$ref: "#/components/schemas/Creator"
type: object
The above is the YAML format. Indentation represents a hierarchy, with rows of deeper indentation being its children and rows of the same hierarchy meaning siblings.
The "vitamin" type has many properties. Properties range from simple ones such as name and id to more complex ones. The type property is String
, but it is limited by the enumeration of possible values. The creator is a reference to another object ($ ref
is this) in this file.
If you see $ ref
in the same file, it means you need to include a reference. The creator types of "vitamins" copied from Liferay's headless-delivery
file are:
Creator:
description: Represents the user account of the content's creator/author. Properties follow the [creator](https://schema.org/creator) specification.
properties:
additionalName:
description: The author's additional name (e.g., middle name).
readOnly: true
type: string
familyName:
description: The author's surname.
readOnly: true
type: string
givenName:
description: The author's first name.
readOnly: true
type: string
id:
description: The author's ID.
format: int64
readOnly: true
type: integer
image:
description: A relative URL to the author's profile image.
format: uri
readOnly: true
type: string
name:
description: The author's full name.
readOnly: true
type: string
profileURL:
description: A relative URL to the author's user profile.
format: uri
readOnly: true
type: string
type: object
That's all for the type description.
Is it too early to put together? Certainly the work is still incomplete! Rest assured that the next part has already been published.
In this part, we showed you how to create a new Liferay Gradle Workspace with custom headless services and the required modules. I also skipped the Path section and touched on the Meta section to define the "Vitamin" project and creator objects to better understand the reusable components, including the OpenAPI YAML file.
Next time will identify Paths (entry points) See you in the next part!
https://github.com/dnebing/vitamins
Recommended Posts