diff --git a/microprofile/pom.xml b/microprofile/pom.xml
new file mode 100644
index 0000000000..ce8a2d13ca
--- /dev/null
+++ b/microprofile/pom.xml
@@ -0,0 +1,87 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ microprofile
+ 1.0-SNAPSHOT
+ war
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 1.8
+ library
+ ${project.build.directory}/${app.name}-service.jar
+ runnable
+
+
+
+
+ org.eclipse.microprofile
+ microprofile
+ 1.2
+ provided
+ pom
+
+
+
+
+
+
+ maven-war-plugin
+
+ false
+ pom.xml
+
+
+
+ net.wasdev.wlp.maven.plugins
+ liberty-maven-plugin
+ 2.1.2
+
+
+ io.openliberty
+ openliberty-runtime
+ 17.0.0.4
+ zip
+
+ ${basedir}/src/main/liberty/config/server.xml
+ ${package.file}
+ ${packaging.type}
+ false
+ project
+
+ /
+ ${project.artifactId}-${project.version}.war
+ 9080
+ 9443
+
+
+
+
+ install-server
+ prepare-package
+
+ install-server
+ create-server
+ install-feature
+
+
+
+ package-server-with-apps
+ package
+
+ install-apps
+ package-server
+
+
+
+
+
+
+
+
diff --git a/microprofile/src/main/java/com/baeldung/microprofile/LibraryApplication.java b/microprofile/src/main/java/com/baeldung/microprofile/LibraryApplication.java
new file mode 100644
index 0000000000..f5eccf969e
--- /dev/null
+++ b/microprofile/src/main/java/com/baeldung/microprofile/LibraryApplication.java
@@ -0,0 +1,8 @@
+package com.baeldung.microprofile;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("/library")
+public class LibraryApplication extends Application {
+}
diff --git a/microprofile/src/main/java/com/baeldung/microprofile/model/Book.java b/microprofile/src/main/java/com/baeldung/microprofile/model/Book.java
new file mode 100644
index 0000000000..44b7f5428d
--- /dev/null
+++ b/microprofile/src/main/java/com/baeldung/microprofile/model/Book.java
@@ -0,0 +1,50 @@
+package com.baeldung.microprofile.model;
+
+public class Book {
+
+ private String id;
+ private String isbn;
+ private String name;
+ private String author;
+ private Integer pages;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getIsbn() {
+ return isbn;
+ }
+
+ public void setIsbn(String isbn) {
+ this.isbn = isbn;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ public Integer getPages() {
+ return pages;
+ }
+
+ public void setPages(Integer pages) {
+ this.pages = pages;
+ }
+}
diff --git a/microprofile/src/main/java/com/baeldung/microprofile/providers/BookListMessageBodyWriter.java b/microprofile/src/main/java/com/baeldung/microprofile/providers/BookListMessageBodyWriter.java
new file mode 100644
index 0000000000..f7d0bfc5f7
--- /dev/null
+++ b/microprofile/src/main/java/com/baeldung/microprofile/providers/BookListMessageBodyWriter.java
@@ -0,0 +1,42 @@
+package com.baeldung.microprofile.providers;
+
+import com.baeldung.microprofile.model.Book;
+import com.baeldung.microprofile.util.BookMapper;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonWriter;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.List;
+
+@Provider
+@Produces(MediaType.APPLICATION_JSON)
+public class BookListMessageBodyWriter implements MessageBodyWriter> {
+
+ @Override
+ public boolean isWriteable(Class> clazz, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return true;
+ }
+
+ @Override
+ public long getSize(List books, Class> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return 0;
+ }
+
+ @Override
+ public void writeTo(List books, Class> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
+ JsonWriter jsonWriter = Json.createWriter(entityStream);
+ JsonArray jsonArray = BookMapper.map(books);
+ jsonWriter.writeArray(jsonArray);
+ jsonWriter.close();
+ }
+}
diff --git a/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyReader.java b/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyReader.java
new file mode 100644
index 0000000000..26ce4c1b64
--- /dev/null
+++ b/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyReader.java
@@ -0,0 +1,30 @@
+package com.baeldung.microprofile.providers;
+
+import com.baeldung.microprofile.model.Book;
+import com.baeldung.microprofile.util.BookMapper;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+@Provider
+@Consumes(MediaType.APPLICATION_JSON)
+public class BookMessageBodyReader implements MessageBodyReader {
+
+ @Override
+ public boolean isReadable(Class> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return type.equals(Book.class);
+ }
+
+ @Override
+ public Book readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
+ return BookMapper.map(entityStream);
+ }
+}
\ No newline at end of file
diff --git a/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyWriter.java b/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyWriter.java
new file mode 100644
index 0000000000..9bc6e89958
--- /dev/null
+++ b/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyWriter.java
@@ -0,0 +1,57 @@
+package com.baeldung.microprofile.providers;
+
+import com.baeldung.microprofile.model.Book;
+import com.baeldung.microprofile.util.BookMapper;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonWriter;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+@Provider
+@Produces(MediaType.APPLICATION_JSON)
+public class BookMessageBodyWriter implements MessageBodyWriter {
+ @Override
+ public boolean isWriteable(Class> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return type.equals(Book.class);
+ }
+
+ /*
+ Deprecated in JAX RS 2.0
+ */
+ @Override
+ public long getSize(Book book, Class> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return 0;
+ }
+
+ /**
+ * Marsahl Book to OutputStream
+ *
+ * @param book
+ * @param type
+ * @param genericType
+ * @param annotations
+ * @param mediaType
+ * @param httpHeaders
+ * @param entityStream
+ * @throws IOException
+ * @throws WebApplicationException
+ */
+ @Override
+ public void writeTo(Book book, Class> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
+ JsonWriter jsonWriter = Json.createWriter(entityStream);
+ JsonObject jsonObject = BookMapper.map(book);
+ jsonWriter.writeObject(jsonObject);
+ jsonWriter.close();
+ }
+
+}
diff --git a/microprofile/src/main/java/com/baeldung/microprofile/repo/BookManager.java b/microprofile/src/main/java/com/baeldung/microprofile/repo/BookManager.java
new file mode 100644
index 0000000000..924cf0ce71
--- /dev/null
+++ b/microprofile/src/main/java/com/baeldung/microprofile/repo/BookManager.java
@@ -0,0 +1,53 @@
+package com.baeldung.microprofile.repo;
+
+import com.baeldung.microprofile.model.Book;
+
+import javax.enterprise.context.ApplicationScoped;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@ApplicationScoped
+public class BookManager {
+
+ private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMM");
+ private AtomicInteger bookIdGenerator = new AtomicInteger(0);
+
+ private ConcurrentMap inMemoryStore = new ConcurrentHashMap<>();
+
+ public BookManager() {
+ Book book = new Book();
+ book.setId(getNextId());
+ book.setName("Building Microservice With Eclipse MicroProfile");
+ book.setIsbn("1");
+ book.setAuthor("baeldung");
+ book.setPages(420);
+ inMemoryStore.put(book.getId(), book);
+ }
+
+ private String getNextId() {
+ String date = LocalDate.now().format(formatter);
+ return String.format("%04d-%s", bookIdGenerator.incrementAndGet(), date);
+ }
+
+ public String add(Book book) {
+ String id = getNextId();
+ book.setId(id);
+ inMemoryStore.put(id, book);
+ return id;
+ }
+
+ public Book get(String id) {
+ return inMemoryStore.get(id);
+ }
+
+ public List getAll() {
+ List books = new ArrayList<>();
+ books.addAll(inMemoryStore.values());
+ return books;
+ }
+}
diff --git a/microprofile/src/main/java/com/baeldung/microprofile/util/BookMapper.java b/microprofile/src/main/java/com/baeldung/microprofile/util/BookMapper.java
new file mode 100644
index 0000000000..861b172299
--- /dev/null
+++ b/microprofile/src/main/java/com/baeldung/microprofile/util/BookMapper.java
@@ -0,0 +1,72 @@
+package com.baeldung.microprofile.util;
+
+import com.baeldung.microprofile.model.Book;
+
+import javax.json.*;
+import java.io.InputStream;
+import java.util.List;
+
+public class BookMapper {
+
+ public static JsonObject map(Book book) {
+ JsonObjectBuilder builder = Json.createObjectBuilder();
+ addValue(builder, "id", book.getId());
+ addValue(builder, "isbn", book.getIsbn());
+ addValue(builder, "name", book.getName());
+ addValue(builder, "author", book.getAuthor());
+ addValue(builder, "pages", book.getPages());
+ return builder.build();
+ }
+
+ private static void addValue(JsonObjectBuilder builder, String key, Object value) {
+ if (value != null) {
+ builder.add(key, value.toString());
+ } else {
+ builder.addNull(key);
+ }
+ }
+
+ public static JsonArray map(List books) {
+ final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+ books.forEach(book -> {
+ JsonObject jsonObject = map(book);
+ arrayBuilder.add(jsonObject);
+ });
+ return arrayBuilder.build();
+ }
+
+ public static Book map(InputStream is) {
+ try(JsonReader jsonReader = Json.createReader(is)) {
+ JsonObject jsonObject = jsonReader.readObject();
+ Book book = new Book();
+ book.setId(getStringFromJson("id", jsonObject));
+ book.setIsbn(getStringFromJson("isbn", jsonObject));
+ book.setName(getStringFromJson("name", jsonObject));
+ book.setAuthor(getStringFromJson("author", jsonObject));
+ book.setPages(getIntFromJson("pages",jsonObject));
+ return book;
+ }
+ }
+
+ private static String getStringFromJson(String key, JsonObject json) {
+ String returnedString = null;
+ if (json.containsKey(key)) {
+ JsonString value = json.getJsonString(key);
+ if (value != null) {
+ returnedString = value.getString();
+ }
+ }
+ return returnedString;
+ }
+
+ private static Integer getIntFromJson(String key, JsonObject json) {
+ Integer returnedValue = null;
+ if (json.containsKey(key)) {
+ JsonNumber value = json.getJsonNumber(key);
+ if (value != null) {
+ returnedValue = value.intValue();
+ }
+ }
+ return returnedValue;
+ }
+}
diff --git a/microprofile/src/main/java/com/baeldung/microprofile/web/BookEndpoint.java b/microprofile/src/main/java/com/baeldung/microprofile/web/BookEndpoint.java
new file mode 100644
index 0000000000..13143a5644
--- /dev/null
+++ b/microprofile/src/main/java/com/baeldung/microprofile/web/BookEndpoint.java
@@ -0,0 +1,42 @@
+package com.baeldung.microprofile.web;
+
+import com.baeldung.microprofile.model.Book;
+import com.baeldung.microprofile.repo.BookManager;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+
+@Path("books")
+@RequestScoped
+public class BookEndpoint {
+
+ @Inject
+ private BookManager bookManager;
+
+ @GET
+ @Path("{id}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getBook(@PathParam("id") String id) {
+ Book book = bookManager.get(id);
+ return Response.ok(book).build();
+ }
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getAllBooks() {
+ return Response.ok(bookManager.getAll()).build();
+ }
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response add(Book book) {
+ String bookId = bookManager.add(book);
+ return Response.created(
+ UriBuilder.fromResource(this.getClass()).path(bookId).build())
+ .build();
+ }
+}
diff --git a/microprofile/src/main/liberty/config/server.xml b/microprofile/src/main/liberty/config/server.xml
new file mode 100644
index 0000000000..2b855bee05
--- /dev/null
+++ b/microprofile/src/main/liberty/config/server.xml
@@ -0,0 +1,11 @@
+
+
+ jaxrs-2.0
+ cdi-1.2
+ jsonp-1.0
+
+
+
+
+