Pengantar Open Liberty

1. Ikhtisar

Dengan popularitas arsitektur layanan mikro dan pengembangan aplikasi cloud-native, kebutuhan akan server aplikasi yang cepat dan ringan semakin meningkat.

Dalam tutorial pengantar ini, kita akan menjelajahi kerangka kerja Open Liberty untuk membuat dan menggunakan layanan web RESTful. Kami juga akan memeriksa beberapa fitur penting yang disediakannya.

2. Buka Liberty

Open Liberty adalah kerangka kerja terbuka untuk ekosistem Java yang memungkinkan pengembangan layanan mikro menggunakan fitur dari Eclipse MicroProfile dan platform Jakarta EE .

Ini adalah runtime Java yang fleksibel, cepat, dan ringan yang tampaknya menjanjikan untuk pengembangan layanan mikro cloud-native.

Kerangka kerja ini memungkinkan kita untuk hanya mengonfigurasi fitur yang dibutuhkan aplikasi kita, menghasilkan footprint memori yang lebih kecil selama startup. Selain itu, ini dapat diterapkan di platform cloud apa pun menggunakan container seperti Docker dan Kubernetes.

Ini mendukung pengembangan cepat dengan memuat ulang kode secara langsung untuk iterasi cepat.

3. Bangun dan Jalankan

Pertama, kita akan membuat proyek berbasis Maven sederhana bernama open-liberty dan kemudian menambahkan plugin liberty-maven- plugin terbaru ke pom.xml :

 io.openliberty.tools liberty-maven-plugin 3.3-M3 

Atau, kita dapat menambahkan dependensi Maven openliberty-runtime terbaru sebagai alternatif dari liberty-maven-plugin :

 io.openliberty openliberty-runtime 20.0.0.1 zip 

Demikian pula, kita bisa menambahkan dependensi Gradle terbaru ke build.gradle :

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

Kemudian, kami akan menambahkan dependensi jakarta.jakartaee-web-api dan microprofile Maven terbaru:

 jakarta.platform jakarta.jakartaee-web-api 8.0.0 provided   org.eclipse.microprofile microprofile 3.2 pom provided 

Kemudian, mari tambahkan properti port HTTP default ke pom.xml :

 9080 9443 

Selanjutnya, kita akan membuat file server.xml di direktori src / main / liberty / config :

  mpHealth-2.0    

Di sini, kami telah menambahkan fitur mpHealth-2.0 untuk memeriksa kesehatan aplikasi.

Itu saja dengan semua pengaturan dasar. Mari jalankan perintah Maven untuk mengkompilasi file untuk pertama kalinya:

mvn clean package

Terakhir, mari kita jalankan server menggunakan perintah Maven yang disediakan Liberty:

mvn liberty:dev

Voila! Aplikasi kami dimulai dan akan dapat diakses di localhost: 9080 :

Selain itu, kami dapat mengakses kesehatan aplikasi di localhost: 9080 / kesehatan :

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

Perintah liberty: dev memulai server Open Liberty dalam mode pengembangan , yang memuat ulang perubahan apa pun yang dibuat pada kode atau konfigurasi tanpa memulai ulang server.

Demikian pula, perintah liberty: run tersedia untuk memulai server dalam mode produksi.

Selain itu, kita dapat menggunakan liberty: start-server dan liberty: stop-server untuk memulai / menghentikan server di latar belakang .

4. Servlet

Untuk menggunakan servlet di aplikasi, kami akan menambahkan fitur servlet-4.0 ke server.xml :

 ... servlet-4.0 

Tambahkan dependensi servlet-4.0 Maven terbaru jika menggunakan dependensi Maven openliberty-runtime di pom.xml :

 io.openliberty.features servlet-4.0 20.0.0.1 esa 

Namun, jika kita menggunakan plugin liberty-maven- plugin, ini tidak perlu.

Kemudian, kita akan membuat kelas AppServlet yang memperluas kelas HttpServlet :

@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 = "

Hello! Welcome to Open Liberty

"; response.getWriter().append(htmlOutput); } }

Di sini, kami telah menambahkan anotasi @WebServlet yang akan membuat AppServlet tersedia pada pola URL yang ditentukan.

Mari akses servlet di localhost: 9080 / app :

5. Buat Layanan Web RESTful

Pertama, mari tambahkan fitur jaxrs-2.1 ke server.xml :

 ... jaxrs-2.1 

Then, we'll create the ApiApplication class, which provides endpoints to the RESTful web service:

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

Here, we've used the @ApplicationPath annotation for the URL path.

Then, let's create the Person class that serves the model:

public class Person { private String username; private String email; // getters and setters // constructors }

Next, we'll create the PersonResource class to define the HTTP mappings:

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

Here, we've added the getAllPersons method for the GET mapping to the /api/persons endpoint. So, we're ready with a RESTful web service, and the liberty:dev command will load changes on-the-fly.

Let's access the /api/persons RESTful web service using a curl GET request:

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

Then, we'll get a JSON array in response:

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

Similarly, we can add the POST mapping by creating the addPerson method:

@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(); }

Now, we can invoke the endpoint with a curl POST request:

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

The response will look like:

Person normanlewis received successfully.

6. Persistence

6.1. Configuration

Let's add persistence support to our RESTful web services.

First, we'll add the derby Maven dependency to the pom.xml:

 org.apache.derby derby 10.14.2.0 

Then, we'll add a few features like jpa-2.2, jsonp-1.1, and cdi-2.0 to the server.xml:

 ... jpa-2.2 jsonp-1.1 cdi-2.0  

Here, the jsonp-1.1 feature provides the Java API for JSON Processing, and the cdi-2.0 feature handles the scopes and dependency injection.

Next, we'll create the persistence.xml in the src/main/resources/META-INF directory:

   jdbc/jpadatasource      

Here, we've used the EclipseLink DDL generation to create our database schema automatically. We can also use other alternatives like Hibernate.

Then, let's add the dataSource configuration to the server.xml:

Note, the jndiName has the same reference to the jta-data-source tag in the persistence.xml.

6.2. Entity and DAO

Then, we'll add the @Entity annotation and an identifier to our Person class:

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

Next, let's create the PersonDao class that will interact with the database using the EntityManager instance:

@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); } }

Note that the @PersistenceContext defines the same reference to the persistence-unit tag in the persistence.xml.

Now, we'll inject the PersonDao dependency in the PersonResource class:

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

Here, we've used the @Inject annotation provided by the CDI feature.

Last, we'll update the addPerson method of the PersonResource class to persist the Person object:

@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(); }

Here, the addPerson method is annotated with the @Transactional annotation to control transactions on CDI managed beans.

Let's invoke the endpoint with the already discussed curl POST request:

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

Then, we'll receive a text response:

Person #1 created successfully.

Similarly, let's add the getPerson method with GET mapping to fetch a Person object:

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

Let's invoke the endpoint using a curl GET request:

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

Then, we'll get the Person object as JSON response:

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

7. Consume RESTful Web Service Using JSON-B

First, we'll enable the ability to directly serialize and deserialize models by adding the jsonb-1.0 feature to the server.xml:

 ... jsonb-1.0 

Then, let's create the RestConsumer class with the consumeWithJsonb method:

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; } }

Here, we've used the ClientBuilder class to request the RESTful web service endpoints.

Last, let's write a unit test to consume the /api/person RESTful web service and verify the response:

@Test public void whenConsumeWithJsonb_thenGetPerson() { String url = "//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()); }

Here, we've used the JsonbBuilder class to parse the String response into the Person object.

Also, we can use MicroProfile Rest Client by adding the mpRestClient-1.3 feature to consume the RESTful web services. It provides the RestClientBuilder interface to request the RESTful web service endpoints.

8. Kesimpulan

Pada artikel ini, kami menjelajahi kerangka kerja Open Liberty - runtime Java yang cepat dan ringan yang menyediakan fitur lengkap dari Eclipse MicroProfile dan platform Jakarta EE.

Untuk memulainya, kami membuat layanan web RESTful menggunakan JAX-RS. Kemudian, kami mengaktifkan persistensi menggunakan fitur seperti JPA dan CDI.

Terakhir, kami menggunakan layanan web RESTful menggunakan JSON-B.

Seperti biasa, semua implementasi kode tersedia di GitHub.