1. 概要

マイクロサービスアーキテクチャとクラウドネイティブアプリケーション開発の人気に伴い、高速で軽量なアプリケーションサーバーの必要性が高まっています。

この入門チュートリアルでは、 Open Libertyフレームワークを探索して、RESTfulWebサービスを作成および使用します。 また、それが提供するいくつかの重要な機能についても検討します。

2. リバティを開く

Open Libertyは、EclipseMicroProfileおよびJakartaEEプラットフォームの機能を使用してマイクロサービスを開発できるようにするJavaエコシステムのオープンフレームワークです。

これは、クラウドネイティブのマイクロサービス開発に有望であると思われる、柔軟で高速かつ軽量のJavaランタイムです。

フレームワークでは、アプリに必要な機能のみを構成できるため、起動時のメモリフットプリントが小さくなります。また、Dockerなどのコンテナーを使用して任意のクラウドプラットフォームにデプロイできます]Kubernetes

迅速な反復のためにコードをライブリロードすることにより、迅速な開発をサポートします。

3. ビルドして実行

まず、 open-liberty という名前の単純なMavenベースのプロジェクトを作成し、次に最新のliberty-maven-pluginプラグインをpom.xmlに追加します。 :

<plugin>
    <groupId>io.openliberty.tools</groupId>
    <artifactId>liberty-maven-plugin</artifactId>
    <version>3.3-M3</version>
</plugin>

または、 liberty-maven-plugin の代わりに、最新の openliberty-runtimeMaven依存関係を追加できます。

<dependency>
    <groupId>io.openliberty</groupId>
    <artifactId>openliberty-runtime</artifactId>
    <version>20.0.0.1</version>
    <type>zip</type>
</dependency>

同様に、最新のGradle依存関係をbuild.gradleに追加できます。

dependencies {
    libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '20.0.0.1'
}

次に、最新のjakarta.jakartaee-web-apiおよびmicroprofileMavenの依存関係を追加します。

<dependency>
    <groupId>jakarta.platform</groupId>
    <artifactId>jakarta.jakartaee-web-api</artifactId>
    <version>8.0.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.eclipse.microprofile</groupId>
    <artifactId>microprofile</artifactId>
    <version>3.2</version>
    <type>pom</type>
    <scope>provided</scope>
</dependency>

次に、デフォルトのHTTPポートプロパティをpom.xmlに追加しましょう。

<properties>
    <liberty.var.default.http.port>9080</liberty.var.default.http.port>
    <liberty.var.default.https.port>9443</liberty.var.default.https.port>
</properties>

次に、server.xmlファイルをsrc/ main / liberty /configディレクトリに作成します。

<server description="Baeldung Open Liberty server">
    <featureManager>
        <feature>mpHealth-2.0</feature>
    </featureManager>
    <webApplication location="open-liberty.war" contextRoot="/" />
    <httpEndpoint host="*" httpPort="${default.http.port}" 
      httpsPort="${default.https.port}" id="defaultHttpEndpoint" />
</server>

ここでは、アプリケーションの状態をチェックするためのmpHealth-2.0機能を追加しました。

基本的な設定は以上です。 Mavenコマンドを実行して、初めてファイルをコンパイルしてみましょう。

mvn clean package

最後に、Libertyが提供するMavenコマンドを使用してサーバーを実行しましょう。

mvn liberty:dev

出来上がり! アプリケーションが起動し、 localhost:9080からアクセスできるようになります。

また、 localhost:9080 /healthでアプリのヘルスにアクセスできます。

{"checks":[],"status":"UP"}

liberty:devコマンドは、Open Libertyサーバーを開発モードで起動します。これにより、サーバーを再起動せずに、コードまたは構成に加えられた変更がホットリロードされます。

同様に、 liberty:run コマンドを使用して、サーバーを実稼働モードで起動できます。

また、 liberty:start-serverおよびliberty:stop-serverを使用して、バックグラウンドでサーバーを起動/停止することができます

4. サーブレット

アプリでサーブレットを使用するには、servlet-4.0機能をserver.xmlに追加します。

<featureManager>
    ...
    <feature>servlet-4.0</feature>
</featureManager>

pom.xmlopenliberty-runtime Maven依存関係を使用する場合は、最新の servlet-4.0Maven依存関係を追加します。

<dependency>
    <groupId>io.openliberty.features</groupId>
    <artifactId>servlet-4.0</artifactId>
    <version>20.0.0.1</version>
    <type>esa</type>
</dependency>

ただし、 liberty-maven-plugin プラグインを使用している場合、これは必要ありません。

次に、HttpServletクラスを拡張するAppServletクラスを作成します。

@WebServlet(urlPatterns="/app")
public class AppServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException {
        String htmlOutput = "<html><h2>Hello! Welcome to Open Liberty</h2></html>";
        response.getWriter().append(htmlOutput);
    }
}

ここでは、 @WebServlet アノテーションを追加して、指定されたURLパターンでAppServletを使用できるようにします。

localhost:9080 /appでサーブレットにアクセスしてみましょう。

5. RESTfulWebサービスを作成する

まず、jaxrs-2.1機能をserver.xmlに追加しましょう。

<featureManager>
    ...
    <feature>jaxrs-2.1</feature>
</featureManager>

次に、 ApiApplication クラスを作成します。これは、RESTfulWebサービスにエンドポイントを提供します。

@ApplicationPath("/api")
public class ApiApplication extends Application {
}

ここでは、URLパスに@ApplicationPathアノテーションを使用しました。

次に、モデルを提供するPersonクラスを作成しましょう。

public class Person {
    private String username;
    private String email;

    // getters and setters
    // constructors
}

次に、 PersonResource クラスを作成して、HTTPマッピングを定義します。

@RequestScoped
@Path("persons")
public class PersonResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Person> getAllPersons() {
        return Arrays.asList(new Person(1, "normanlewis", "[email protected]"));
    }
}

ここでは、GETマッピング用のgetAllPersonsメソッドを/api /peopleエンドポイントに追加しました。 これで、RESTful Webサービスの準備が整い、 liberty:devコマンドがオンザフライで変更をロードします。

curl GETリクエストを使用して、 / api / peoples RESTfulWebサービスにアクセスしてみましょう。

curl --request GET --url http://localhost:9080/api/persons

次に、応答としてJSON配列を取得します。

[{"id":1, "username":"normanlewis", "email":"[email protected]"}]

同様に、 addPerson メソッドを作成することにより、POSTマッピングを追加できます。

@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response addPerson(Person person) {
    String respMessage = "Person " + person.getUsername() + " received successfully.";
    return Response.status(Response.Status.CREATED).entity(respMessage).build();
}

これで、curlPOSTリクエストを使用してエンドポイントを呼び出すことができます。

curl --request POST --url http://localhost:9080/api/persons \
  --header 'content-type: application/json' \
  --data '{"username": "normanlewis", "email": "[email protected]"}'

応答は次のようになります。

Person normanlewis received successfully.

6. 永続性

6.1. 構成

RESTfulWebサービスに永続性サポートを追加しましょう。

まず、 derbyMaven依存関係をpom.xmlに追加します。

<dependency>
    <groupId>org.apache.derby</groupId>
    <artifactId>derby</artifactId>
    <version>10.14.2.0</version>
</dependency>

次に、 jpa-2.2 jsonp-1.1 cdi-2.0などの機能をserver.xmlに追加します。 ]:

<featureManager>
    ...
    <feature>jpa-2.2</feature> 
    <feature>jsonp-1.1</feature>
    <feature>cdi-2.0</feature>
</featureManager>

ここで、 jsonp-1.1機能はJSON処理用のJavaAPIを提供し、cdi-2.0機能はスコープと依存性注入を処理します。

次に、 src / main / resources /META-INFディレクトリにpersistence.xmlを作成します。

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
                        http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    <persistence-unit name="jpa-unit" transaction-type="JTA">
        <jta-data-source>jdbc/jpadatasource</jta-data-source>
        <properties>
            <property name="eclipselink.ddl-generation" value="create-tables"/>
            <property name="eclipselink.ddl-generation.output-mode" value="both" />
        </properties>
    </persistence-unit>
</persistence>

ここでは、 EclipseLink DDL生成を使用して、データベーススキーマを自動的に作成しました。 Hibernateのような他の代替手段を使用することもできます。

次に、dataSource構成をserver.xmlに追加しましょう。

<library id="derbyJDBCLib">
    <fileset dir="${shared.resource.dir}" includes="derby*.jar"/> 
</library>
<dataSource id="jpadatasource" jndiName="jdbc/jpadatasource">
    <jdbcDriver libraryRef="derbyJDBCLib" />
    <properties.derby.embedded databaseName="libertyDB" createDatabase="create" />
</dataSource>

jndiName は、persistence.xml。jta-data-sourceタグへの同じ参照を持っていることに注意してください。

6.2. エンティティとDAO

次に、@Entityアノテーションと識別子を[X73X]Personクラスに追加します。

@Entity
public class Person {
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    private int id;
    
    private String username;
    private String email;

    // getters and setters
}

次に、EntityManagerインスタンスを使用してデータベースと対話するPersonDaoクラスを作成しましょう。

@RequestScoped
public class PersonDao {
    @PersistenceContext(name = "jpa-unit")
    private EntityManager em;

    public Person createPerson(Person person) {
        em.persist(person);
        return person;
    }

    public Person readPerson(int personId) {
        return em.find(Person.class, personId);
    }
}

@PersistenceContext は、persistence.xmlpersistence-unitタグへの同じ参照を定義していることに注意してください。

次に、PersonDao依存関係をPersonResourceクラスに挿入します。

@RequestScoped
@Path("person")
public class PersonResource {
    @Inject
    private PersonDao personDao;

    // ...
}

ここでは、CDI機能によって提供される@Injectアノテーションを使用しました。

最後に、PersonResourceクラスのaddPersonメソッドを更新して、Personオブジェクトを永続化します。

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Transactional
public Response addPerson(Person person) {
    personDao.createPerson(person);
    String respMessage = "Person #" + person.getId() + " created successfully.";
    return Response.status(Response.Status.CREATED).entity(respMessage).build();
}

ここで、 addPerson メソッドには、 @Transactional アノテーションが付けられ、CDI管理対象Beanのトランザクションを制御します。

すでに説明したcurlPOSTリクエストを使用してエンドポイントを呼び出しましょう。

curl --request POST --url http://localhost:9080/api/persons \
  --header 'content-type: application/json' \
  --data '{"username": "normanlewis", "email": "[email protected]"}'

次に、テキスト応答を受け取ります。

Person #1 created successfully.

同様に、 getPerson メソッドとGETマッピングを追加して、Personオブジェクトをフェッチします。

@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
@Transactional
public Person getPerson(@PathParam("id") int id) {
    Person person = personDao.readPerson(id);
    return person;
}

curlGETリクエストを使用してエンドポイントを呼び出しましょう。

curl --request GET --url http://localhost:9080/api/persons/1

次に、PersonオブジェクトをJSON応答として取得します。

{"email":"[email protected]","id":1,"username":"normanlewis"}

7. JSON-Bを使用してRESTfulWebサービスを使用する

まず、jsonb-1.0機能をserver.xmlに追加することにより、モデルを直接シリアル化および逆シリアル化する機能を有効にします。

<featureManager>
    ...
    <feature>jsonb-1.0</feature>
</featureManager>

次に、consumeWithJsonbメソッドを使用してRestConsumerクラスを作成しましょう。

public class RestConsumer {
    public static String consumeWithJsonb(String targetUrl) {
        Client client = ClientBuilder.newClient();
        Response response = client.target(targetUrl).request().get();
        String result = response.readEntity(String.class);
        response.close();
        client.close();
        return result;
    }
}

ここでは、 ClientBuilder クラスを使用して、RESTfulWebサービスエンドポイントを要求しました。

最後に、 / api / person RESTful Webサービスを使用して、応答を確認する単体テストを作成しましょう。

@Test
public void whenConsumeWithJsonb_thenGetPerson() {
    String url = "http://localhost:9080/api/persons/1";
    String result = RestConsumer.consumeWithJsonb(url);        
    
    Person person = JsonbBuilder.create().fromJson(result, Person.class);
    assertEquals(1, person.getId());
    assertEquals("normanlewis", person.getUsername());
    assertEquals("[email protected]", person.getEmail());
}

ここでは、 JsonbBuilder クラスを使用して、String応答をPersonオブジェクトに解析しました。

また、mpRestClient-1.3機能を追加して MicroProfile Rest Clientを使用し、RESTfulWebサービスを利用することもできます。 これは、RESTfulWebサービスエンドポイントを要求するためのRestClientBuilderインターフェースを提供します。

8. 結論

この記事では、OpenLibertyフレームワークについて説明しました。これはEclipseMicroProfileおよびJakartaEEプラットフォームの全機能を提供する高速で軽量のJavaランタイムです。

まず、JAX-RSを使用してRESTfulWebサービスを作成しました。 次に、JPAやCDIなどの機能を使用して永続化を有効にしました。

最後に、JSON-Bを使用してRESTfulWebサービスを利用しました。

いつものように、すべてのコード実装はGitHub利用できます。