<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andy McCright</title>
    <description>The latest articles on DEV Community by Andy McCright (@andymc12).</description>
    <link>https://dev.to/andymc12</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F484845%2Febf97b1a-71ce-4793-848b-768653f744d9.jpeg</url>
      <title>DEV Community: Andy McCright</title>
      <link>https://dev.to/andymc12</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andymc12"/>
    <language>en</language>
    <item>
      <title>Book Excerpt: Real World Jakarta REST Example</title>
      <dc:creator>Andy McCright</dc:creator>
      <pubDate>Tue, 03 Aug 2021 12:46:00 +0000</pubDate>
      <link>https://dev.to/andymc12/book-excerpt-real-world-jakarta-rest-example-1en5</link>
      <guid>https://dev.to/andymc12/book-excerpt-real-world-jakarta-rest-example-1en5</guid>
      <description>&lt;p&gt;The following in an excerpt from &lt;a href="https://www.amazon.com/gp/product/1801078807/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1801078807&amp;amp;linkCode=as2&amp;amp;tag=andymc12-20&amp;amp;linkId=700b082a8ed53af047ab2d880cf395de"&gt;Practical Cloud-Native Java Development with MicroProfile&lt;/a&gt; from &lt;a href="https://www.packtpub.com/"&gt;Packt Publishing&lt;/a&gt;. It is available for pre-order from &lt;a href="https://www.amazon.com/gp/product/1801078807/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1801078807&amp;amp;linkCode=as2&amp;amp;tag=andymc12-20&amp;amp;linkId=700b082a8ed53af047ab2d880cf395de"&gt;Amazon.com&lt;/a&gt; and directly from &lt;a href="https://www.packtpub.com/product/practical-cloud-native-java-development-with-microprofile/9781801078801"&gt;Packt&lt;/a&gt;. It is scheduled for release in September. This excerpt comes from chapter 4: Building Cloud-Native Applications and describes how to build a more real-world RESTful application using Jakarta REST (aka JAX-RS):&lt;/p&gt;




&lt;h2&gt;
  
  
  A More Real-world Example
&lt;/h2&gt;

&lt;p&gt;Now that we have built a simple JAX-RS application, let’s build a more complex application – a thesaurus service where clients can search and update synonymous words. First, we’ll start with an &lt;em&gt;exception mapper&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Provider
public class NoSuchWordExceptionMapper implements ExceptionMapper&amp;lt;NoSuchWordException&amp;gt; {

    @Override
    public Response toResponse(NoSuchWordException ex) {
        return Response.status(404)
                       .entity(ex.getMessage())
                       .build();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most applications will have &lt;em&gt;business exceptions&lt;/em&gt; – exceptions specific to the application domain. For a thesaurus service, that might include a &lt;code&gt;NoSuchWordException&lt;/code&gt;, which could be used to indicate that a searched word does not exist. It is clear in the application that somebody specified a word that does not exist, but it is not clear to an HTTP client. The provider class, &lt;code&gt;NoSuchWordExceptionMapper&lt;/code&gt;, makes that possible. It enables the resource class methods to throw a &lt;code&gt;NoSuchWordException&lt;/code&gt;, and the JAX-RS container will map the exception to an HTTP response (in this case, a &lt;code&gt;404 Not Found&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Next is the resource class (full source code available at: &lt;a href="https://github.com/PacktPublishing/Practical-Cloud-Native-Development-with-MicroProfile-4.0/blob/main/Chapter04/src/main/java/com/packt/microprofile/book/ch4/thesaurus/ThesaurusResource.java"&gt;https://github.com/PacktPublishing/Practical-Cloud-Native-Development-with-MicroProfile-4.0/blob/main/Chapter04/src/main/java/com/packt/microprofile/book/ch4/thesaurus/ThesaurusResource.java&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Path(“/thesaurus/{word}”)
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
public class ThesaurusResource { // … 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a few new annotations on the resource class: &lt;code&gt;@Produces&lt;/code&gt; and &lt;code&gt;@Consumes&lt;/code&gt;. These annotations can be placed on resource classes or methods – like most annotations of this type in JAX-RS, annotations on the method take priority over annotations on the class. These annotations help control the matching of requests and the entity providers (&lt;code&gt;MessageBodyReaders&lt;/code&gt; and &lt;code&gt;MessageBodyWriters&lt;/code&gt;) to be used in deserializing the HTTP entity from the request or serializing the HTTP entity in the response.&lt;/p&gt;

&lt;p&gt;HTTP requests and responses may contain a header that indicates the &lt;em&gt;media type&lt;/em&gt; (also known as &lt;em&gt;MIME type&lt;/em&gt;) of the HTTP entity – &lt;code&gt;Content-Type&lt;/code&gt;. HTTP requests may also contain a header that specifies the media type(s) that it expects to receive in the response – Accept. In the absence of these headers, all media types are allowed (i.e., &lt;code&gt;*/*&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;In the previous example, the resource class specifies &lt;code&gt;MediaType.TEXT_PLAIN&lt;/code&gt;, or &lt;code&gt;text/plain&lt;/code&gt;. Other media types include &lt;code&gt;text/html&lt;/code&gt;, &lt;code&gt;application/json&lt;/code&gt;, &lt;code&gt;application/xml&lt;/code&gt;, &lt;code&gt;image/jpeg&lt;/code&gt;, and much more. By specifying &lt;code&gt;text/plain&lt;/code&gt;, that would prevent the resource methods from being invoked if a request contained a header like &lt;code&gt;Content-Type: application/pdf&lt;/code&gt; or &lt;code&gt;Accept: image/png&lt;/code&gt; – instead of invoking the resource method, the JAX-RS container would return a &lt;code&gt;415 Unsupported Media Type&lt;/code&gt; error.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Best practice:&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Always use &lt;code&gt;@Produces&lt;/code&gt; and &lt;code&gt;@Consumes&lt;/code&gt; to limit media types. This will place limits on the types of requests your service will respond to. It will ensure that your application (if properly tested) can handle requests of the specified media types.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This example also introduces new method-level HTTP verb annotations: &lt;code&gt;@POST&lt;/code&gt;, &lt;code&gt;@PUT&lt;/code&gt;, &lt;code&gt;@DELETE&lt;/code&gt; and &lt;code&gt;@PATCH&lt;/code&gt;. Like &lt;code&gt;@GET&lt;/code&gt;, these annotations specify which method should be invoked based on the HTTP request’s verb (also known as method – HTTP method is probably the more commonly used term, but we will use verb in this book to disambiguate from Java methods). The JAX-RS API set includes these five verb annotations as well as &lt;code&gt;@HEAD&lt;/code&gt; and &lt;code&gt;@OPTIONS&lt;/code&gt; that are less commonly used.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Special note:&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;If the resource class contains a method annotated with &lt;code&gt;@GET&lt;/code&gt; but not &lt;code&gt;@HEAD&lt;/code&gt;, the JAX-RS container would invoke the &lt;code&gt;@GET&lt;/code&gt; method for matching HTTP HEAD requests, but it would remove the entity. Likewise, if a resource class contains any HTTP verb annotation other than &lt;code&gt;@OPTIONS&lt;/code&gt;, the JAX-RS container would return a response indicating all of the valid verbs that could be matched for that request. Using the example above, an OPTIONS request would result in a response with a header like, &lt;code&gt;Allow: DELETE, HEAD, GET, OPTIONS, PATCH, POST, PUT&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This example also introduces the idea of HTTP parameters, specifically:&lt;br&gt;&lt;br&gt;
&lt;code&gt;@PathParam(“word”) String word;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This annotation can be placed on fields or method parameters. The value of &lt;code&gt;@PathParam&lt;/code&gt; is &lt;em&gt;word&lt;/em&gt; which corresponds to the template variable in the resource class’s &lt;code&gt;@Path&lt;/code&gt; value (&lt;code&gt;“/thesaurus/{word}”&lt;/code&gt;). This means that for an HTTP request like &lt;code&gt;http://localhost:9080/myApp/rest/thesaurus/funny&lt;/code&gt;, the value injected in to the word field would be &lt;em&gt;funny&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;There are other HTTP parameter types that can be used in JAX-RS including &lt;code&gt;@QueryParam&lt;/code&gt;, &lt;code&gt;@FormParam&lt;/code&gt;, &lt;code&gt;@CookieParam&lt;/code&gt;, &lt;code&gt;@HeaderParam&lt;/code&gt;, &lt;code&gt;@MatrixParam&lt;/code&gt; which all correspond to different parts of an HTTP request. JAX-RS also allows multiple HTTP parameter annotations to be aggregated on a single Java class and then referenced in the resource class or method as a &lt;code&gt;@BeanParam&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;I hope you found this excerpt helpful and enticing. Chapter 4 is &lt;em&gt;packed&lt;/em&gt; (pun intended) full of useful knowledge for building and consuming robust RESTful services. It covers the basics, but also a lot of hidden gems in JAX-RS, JSON-B/P, CDI and MicroProfile Rest Client. And if that’s not enough, there’s eleven more chapters filled with cloud-native goodness. Ok, that’s enough advertising for one blog post… &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zCyXRrdx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zCyXRrdx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png" alt="🙂"&gt;&lt;/a&gt; Thanks for reading!&lt;/p&gt;

</description>
      <category>enterprisejava</category>
      <category>cloudnative</category>
      <category>jakarta</category>
      <category>java</category>
    </item>
    <item>
      <title>Practical Cloud-Native Java Development with MicroProfile</title>
      <dc:creator>Andy McCright</dc:creator>
      <pubDate>Wed, 14 Jul 2021 15:15:00 +0000</pubDate>
      <link>https://dev.to/andymc12/practical-cloud-native-java-development-with-microprofile-4ph6</link>
      <guid>https://dev.to/andymc12/practical-cloud-native-java-development-with-microprofile-4ph6</guid>
      <description>&lt;p&gt;For the past six months, I’ve had the privilege to work with some amazing co-authors (&lt;a href="https://twitter.com/emilyfhjiang"&gt;Emily Jiang&lt;/a&gt;, &lt;a href="https://twitter.com/jwalcorn"&gt;John Alcorn&lt;/a&gt;, &lt;a href="https://github.com/Channyboy"&gt;David Chan&lt;/a&gt; and &lt;a href="https://twitter.com/nottycode"&gt;Alasdair Nottingham&lt;/a&gt;) and a super-supportive publisher (&lt;a href="https://www.packtpub.com/"&gt;Packt&lt;/a&gt;) to produce the definitive guide to Java Cloud-native development.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;So, what’s in it?&lt;/em&gt; My co-authors and I don’t like fluff – it’s titled &lt;em&gt;Practical&lt;/em&gt; for a reason. The book takes a deep dive into &lt;a href="https://microprofile.io/"&gt;MicroProfile&lt;/a&gt; technologies – this include some of the technologies that MP “borrowed” from &lt;a href="https://jakarta.ee/"&gt;Jakarta&lt;/a&gt; (REST, CDI, JSON-P/B) as well as the original MicroProfile technologies like Rest Client, Config, Fault Tolerance, Metrics, etc. But this book isn’t a textbook – there are practical examples with &lt;a href="https://github.com/IBMStockTrader/portfolio"&gt;a real-world application&lt;/a&gt; at the core.&lt;/p&gt;

&lt;p&gt;We also cover deployment strategies like how to run and test your application in open source servers like &lt;a href="https://openliberty.io/"&gt;Open Liberty&lt;/a&gt; – then deploy in &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt; and &lt;a href="https://openliberty.io/guides/#kubernetes"&gt;Kubernetes&lt;/a&gt;. All of the examples in the book are available in &lt;a href="https://github.com/PacktPublishing/Practical-Cloud-Native-Development-with-MicroProfile-4.0"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;So, where can I get it?&lt;/em&gt; I’m glad you asked! It’s available for pre-sale on &lt;a href="https://amzn.to/3hDnQkd"&gt;Amazon&lt;/a&gt; and &lt;a href="https://www.packtpub.com/product/practical-cloud-native-java-development-with-microprofile/9781801078801"&gt;Packt&lt;/a&gt;. It’s scheduled to release in September, 2021.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Anything else you can tell me about it?&lt;/em&gt; You bet! I plan to post some excerpts from the book on this site in the next few weeks. Stay tuned!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com/gp/product/1801078807/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1801078807&amp;amp;linkCode=as2&amp;amp;tag=andymc12-20&amp;amp;linkId=249c8dd6ca571e60c91c4125ab65b0ee"&gt;&lt;img src="//ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&amp;amp;MarketPlace=US&amp;amp;ASIN=1801078807&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL250_&amp;amp;tag=andymc12-20"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>enterprisejava</category>
      <category>book</category>
      <category>java</category>
      <category>jaxrs</category>
    </item>
    <item>
      <title>Restructuring JSON with JAX-RS ReaderInterceptors and a little bit of JSON-B Magic</title>
      <dc:creator>Andy McCright</dc:creator>
      <pubDate>Wed, 09 Jun 2021 18:50:42 +0000</pubDate>
      <link>https://dev.to/andymc12/restructuring-json-with-jax-rs-readerinterceptors-and-a-little-bit-of-json-b-magic-4hkn</link>
      <guid>https://dev.to/andymc12/restructuring-json-with-jax-rs-readerinterceptors-and-a-little-bit-of-json-b-magic-4hkn</guid>
      <description>&lt;p&gt;Have you ever needed to consume a RESTful service but the data structure of the remote service just didn’t quite match with what you had in mind in your client application?  I ran into this situation earlier this week while exploring some commercial REST APIs. In my case, I had some JSON like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "links":{
    "self":"https://api.myhost.com/services/v2/music?titleSearch=10%2C000"
  },
  "data":[
    {
      "type":"Song",
      "id":"56780987",
      "attributes":{
        "admin":"EMI Christian Music Publishing",
        "author":"Jonas Myrin and Matt Redman",
        "ccli_number":6016351,
        "copyright":
          "2011 Thankyou Music, Said And Done Music, and SHOUT! Publishing",
        "created_at":"2014-11-10T17:31:26Z",
        "hidden":false,
        "last_scheduled_at":"2021-05-30T08:49:00Z",
        "last_scheduled_short_dates":"May 30, 2021",
        "notes":"Vocal Range B - D'",
        "themes":", Adoration, Blessing, Christian Life, Praise",
        "title":"10,000 Reasons (Bless The Lord)"
      },
      "links":{"self":"https://api.myhost.com/services/v2/music/8802060"}
    }
  ],
  "included":[],
  "meta":{
    "total_count":1,
    "count":1,
    "can_order_by":["title","created_at","updated_at","last_scheduled_at"],
    "can_query_by":["author","ccli_number","themes","title"],
    "parent":{
        "id":"132275",
        "type":"Organization"
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This JSON looks like a nicely formed &lt;a href="https://en.wikipedia.org/wiki/HATEOAS"&gt;HATEOAS&lt;/a&gt; response from a RESTful service providing song information. However, there are a few obstacles if we want to simply convert it into a Java object in our application like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Song {
    private String id;
    private String title;
    private String author;
    private LocalDate lastScheduled;
    // ... more fields, and public getters/setters ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first obstacle is that the object returned in the JSON response is not a &lt;code&gt;Song&lt;/code&gt; object – it is a complex object that contains the song data (under the &lt;code&gt;data&lt;/code&gt; field) and other RESTful navigational fields like &lt;code&gt;links&lt;/code&gt; and &lt;code&gt;meta&lt;/code&gt;.  To overcome this obstacle, we could create some sort of &lt;code&gt;MetaSong&lt;/code&gt; object that has fields for &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;links&lt;/code&gt;, etc., but unless we plan to use those other fields that seems like a waste. Fortunately there is a better way!&lt;/p&gt;

&lt;p&gt;Upon receiving the response, we could intercept the JSON data and reformat it before the JAX-RS client or MicroProfile Rest Client interface converts the JSON to a Java object. We do that with a &lt;code&gt;ReaderInterceptor&lt;/code&gt; provider, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DataExtractionReaderInterceptor implements ReaderInterceptor {

    @Override
    public Object aroundReadFrom(ReaderInterceptorContext context)
        throws IOException, WebApplicationException {

        InputStream is = context.getInputStream();
        JsonObject json = Json.createReader(is).readObject();
        JsonValue data = json.get("data");
        is = new ByteArrayInputStream(data.toString().getBytes())
        context.setInputStream(is);
        return context.proceed();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is executed on the client after the response is returned to the client but before the response is converted to a Java object. It uses JSON-P APIs to read the response stream and then extracts the data field, then replaces the response stream with a new stream that only includes that data object.&lt;/p&gt;

&lt;p&gt;The second obstacle is that the song’s JSON fields don’t match the Java object’s fields. The JSON has a field called attributes, and the relevant fields like &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;author&lt;/code&gt;, etc. are all child fields of that.  But in the Java object, these fields are all directly under the &lt;code&gt;Song&lt;/code&gt; class. We can overcome this obstacle with a little JSON-B magic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Song {
    private String id;
    private String title;
    private String author;
    //...

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }

    public void setAttributes(Map&amp;lt;String,Object&amp;gt; attrs) {
        setTitle((String)attrs.get("title"));
        setAuthor((String)attrs.get("author"));
        // ...
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, JSON-B maps the JSON fields to Java fields by calling the appropriate setter method (e.g., JSON &lt;code&gt;id&lt;/code&gt; is a &lt;code&gt;String&lt;/code&gt; and would map to the &lt;code&gt;setId&lt;/code&gt; Java method). However, since we don’t want to create a separate &lt;code&gt;Attributes&lt;/code&gt; Java class to handle the JSON child fields, we instead create a placeholder method, &lt;code&gt;setAttributes&lt;/code&gt; that takes a &lt;code&gt;Map&amp;lt;String, Object&amp;gt;&lt;/code&gt; parameter.  Now, JSON-B will pass in the JSON attributes object as key-value pairs that we can then map to the appropriate fields on our &lt;code&gt;Song&lt;/code&gt; Java object.&lt;/p&gt;

&lt;p&gt;Now all we need to do is invoke the service using either the JAX-RS Client or MicroProfile Rest Client APIs. The full source code including a runnable sample is available at &lt;a href="https://github.com/andymc12/sample-restructure-json-data"&gt;https://github.com/andymc12/sample-restructure-json-data&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for checking in! As always, please let me know if you have any questions or comments.&lt;/p&gt;

</description>
      <category>enterprisejava</category>
      <category>client</category>
      <category>java</category>
      <category>jaxrs</category>
    </item>
    <item>
      <title>What’s Coming in Jakarta REST 3.1?</title>
      <dc:creator>Andy McCright</dc:creator>
      <pubDate>Tue, 04 May 2021 19:19:08 +0000</pubDate>
      <link>https://dev.to/andymc12/what-s-coming-in-jakarta-rest-3-1-ole</link>
      <guid>https://dev.to/andymc12/what-s-coming-in-jakarta-rest-3-1-ole</guid>
      <description>&lt;p&gt;The ink is still drying on Jakarta EE 9 / 9.1 and the Jakarta RESTful Web Services 3.0 specs, but the REST community isn’t slowing down.  While vendors and developers are rapidly adopting EE 9, the Jakarta REST (aka JAX-RS) community is actively preparing for &lt;a href="https://github.com/eclipse-ee4j/jaxrs-api/wiki/Roadmap"&gt;future releases&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;DISCLAIMER: Everything in this post is&lt;/em&gt; planned &lt;em&gt;as of the time of writing, but is subject to change without notice.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Our &lt;a href="https://jakarta.ee/specifications/restful-ws/3.1/"&gt;plans for a standalone 3.1 release&lt;/a&gt; have been approved. What does standalone mean? Just that it won’t be included in a larger Jakarta EE umbrella release. That might hinder adoption for some vendors who are more concerned about only implementing full profiles, like the &lt;a href="https://jakarta.ee/specifications/platform/"&gt;Jakarta EE Platform&lt;/a&gt; or &lt;a href="https://jakarta.ee/specifications/webprofile/"&gt;Web Profile&lt;/a&gt;. Still, I expect many vendors will offer the 3.1 release – either as a standalone product or feature, or as an extension of their EE 9/9.1 implementation.  Other vendors may wait for an EE 10 release, which should include all of the new features from 3.1 as well as newer features from a proposed Jakarta REST 4.0 release.&lt;/p&gt;

&lt;p&gt;Ok, so what should we expect in Jakarta REST 3.1? Here are the proposed new features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java SE Bootstrap API&lt;/li&gt;
&lt;li&gt;Support for sending and receiving multipart/form-data payloads&lt;/li&gt;
&lt;li&gt;Better alignment with JSON-B&lt;/li&gt;
&lt;li&gt;Automatic loading of provider extensions&lt;/li&gt;
&lt;li&gt;Deprecation of @Context in preparation for better alignment with CDI&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Java SE Bootstrap API
&lt;/h2&gt;

&lt;p&gt;The idea here is to make it easier to build and deploy a RESTful service without the need of a full EE container/server/etc. Servers like &lt;a href="https://openliberty.io/"&gt;Open Liberty&lt;/a&gt;, &lt;a href="https://www.ibm.com/cloud/websphere-application-server"&gt;WebSphere Application Server&lt;/a&gt;, and &lt;a href="https://www.wildfly.org/"&gt;Wildfly&lt;/a&gt; are great, but wouldn’t it be nice to be able to launch a RESTful service in Java SE sometimes? The use cases could include setting up a “mock” server to test your client code against, or even a production ready service that might not need all of the bells and whistles that a full server environment might provide.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://github.com/eclipse-ee4j/jaxrs-api/tree/master/examples/src/main/java/jaxrs/examples/bootstrap"&gt;Jakarta REST examples&lt;/a&gt; for how to code it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support for Multipart
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;multipart/form-data&lt;/em&gt; content type has been around for a long time – and is often used to transfer multiple disparate data types from one point to another. For example, you might apply for a job on a site and send your name and address in an HTML form that also includes your resume (DOC or PDF file) and your picture (PNG, JPG, etc.). Under the hood, this is sent as a multipart request.&lt;/p&gt;

&lt;p&gt;Until now, the Jakarta REST spec has not defined how to accept incoming multipart content or how to send it. Vendors have implemented their own approach at providing APIs for sending and receiving multipart content, but the 3.1 spec makes this portable and provides a way for all vendor implementations to provide the same level of functionality.&lt;/p&gt;

&lt;p&gt;There are some examples for how to code it &lt;a href="https://github.com/andymc12/jaxrs-api/tree/eb54a831197a416ac89de18c5f891c34f2ca6cb2/examples/src/main/java/jaxrs/examples/multipart"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  JSON-B Alignment
&lt;/h2&gt;

&lt;p&gt;A few years back, Adam Bien wrote an &lt;a href="https://www.adam-bien.com/roller/abien/entry/jax_rs_json_b_configuration"&gt;excellent blog post&lt;/a&gt; on how to configure JSON-B in a Jakarta REST application. The only trouble is that at that time, the approach only worked with &lt;a href="https://eclipse-ee4j.github.io/jersey/"&gt;Eclipse Jersey&lt;/a&gt;. Since then other implementations (including &lt;a href="https://openliberty.io/"&gt;Open Liberty&lt;/a&gt; via &lt;a href="http://cxf.apache.org/"&gt;Apache CXF&lt;/a&gt;) also enabled this functionality, but it will become a standard in 3.1, enabling more portable usage of JSON-B configuration.&lt;/p&gt;

&lt;p&gt;What does JSON-B configuration really mean? Let’s say that you want your RESTful service to always use a specific naming strategy when converting from Java field names to JSON. This is something you would configure in a &lt;code&gt;JsonbConfig&lt;/code&gt; object. But in order to ensure that your Jakarta REST app uses that configuration, you would need to register a &lt;code&gt;ContextResolver&amp;lt;JsonbConfig&amp;gt;&lt;/code&gt; provider that returns your customized config object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Provider Extensions
&lt;/h2&gt;

&lt;p&gt;Most Jakarta REST applications are self-contained artifacts – usually WARs or fat/thin JARs, etc. But there are times, particularly in cloud environments, where you may want to add extensions to the application for additional qualities of service. For example, maybe you’d like to add some monitoring extensions to collect performance metrics, diagnostic tracing, or audit logging. Using the new provider extension support in Jakarta REST 3.1, these types of extensions could be applied outside of the application packaging. This will allow vendors and other third-party library developers to build extension JARs that can be added to the classpath of the application for quick and easy activation. This is all handled using the &lt;code&gt;ServiceLoader&lt;/code&gt; mechanism.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deprecation of &lt;code&gt;@Context&lt;/code&gt; for better CDI Integration
&lt;/h2&gt;

&lt;p&gt;Historically, JAX-RS and CDI were developed around the same time by two different groups. As such both groups built their own dependency injection mechanism. JAX-RS’s dependency injection mechanism is specific to RESTful services and injects a limited number of object types that are annotated with &lt;code&gt;@Context&lt;/code&gt;. CDI is much more flexible and is intended to be the de facto injection mechanism for all of Jakarta EE – it uses the more common &lt;code&gt;@Inject&lt;/code&gt; annotation. In 3.1, the Jakarta REST community made the decision to replace their component-specific injection mechanism with CDI. In a future release (presumably 4.0), the &lt;code&gt;@Context&lt;/code&gt; annotation will be removed.&lt;br&gt;
This should pave the way for vendors to reduce install footprint by using a single dependency injection mechanism. It also will allow more flexibility beyond just injection in RESTful applications. If you’re not familiar with CDI, you can learn more about it in the &lt;a href="https://openliberty.io/guides/cdi-intro.html"&gt;Open Liberty CDI guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The future of REST in Java certainly looks bright. What new features would you like to see?  Please feel free to leave a comment with your ideas here or &lt;a href="https://github.com/eclipse-ee4j/jaxrs-api/issues"&gt;open an issue&lt;/a&gt; at the &lt;a href="https://github.com/eclipse-ee4j/jaxrs-api"&gt;Jakarta REST GitHub site&lt;/a&gt;. Until then, stay RESTful! 😉&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was originally published on May 3, 2021 at: &lt;a href="https://andymc12.net/2021/05/03/whats-coming-in-jakarta-rest-3-1/"&gt;https://andymc12.net/2021/05/03/whats-coming-in-jakarta-rest-3-1/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rest</category>
      <category>jakarta</category>
      <category>java</category>
      <category>api</category>
    </item>
    <item>
      <title>MicroProfile Rest Client 2.0 – First Look</title>
      <dc:creator>Andy McCright</dc:creator>
      <pubDate>Sun, 02 May 2021 20:41:54 +0000</pubDate>
      <link>https://dev.to/andymc12/microprofile-rest-client-2-0-first-look-1pn3</link>
      <guid>https://dev.to/andymc12/microprofile-rest-client-2-0-first-look-1pn3</guid>
      <description>&lt;p&gt;The latest release of MicroProfile’s type-safe REST client has a lot of new and exciting features. In this post, we’ll take a look at some of the new features and how you can use them in Open Liberty, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using QueryParamStyle to specify how collections of query parameters should be formatted&lt;/li&gt;
&lt;li&gt;Proxy server support&lt;/li&gt;
&lt;li&gt;Automatically following redirects&lt;/li&gt;
&lt;li&gt;Support for Server Sent Events (SSEs)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;The MicroProfile Rest Client 2.0 implementation is new in &lt;a href="https://openliberty.io/blog/2021/03/19/microprofile-4-21003.html"&gt;Open Liberty 21.0.0.3&lt;/a&gt; – so make sure you are using the latest version of Liberty. Next, you will need to add the following &lt;a href="https://openliberty.io/guides/maven-intro.html"&gt;Maven&lt;/a&gt; dependency to your pom.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.eclipse.microprofile.rest.client&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;microprofile-rest-client-api&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.0&amp;lt;/version&amp;gt;
    &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or, if you use &lt;a href="https://openliberty.io//guides/gradle-intro.html"&gt;Gradle&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dependencies {
    compileOnly group: 'org.eclipse.microprofile.rest.client', name: 'microprofile-rest-client-api', version: '2.0'
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, make sure to configure your Liberty server with the &lt;code&gt;mpRestClient-2.0&lt;/code&gt; feature in the server.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;server&amp;gt;
  &amp;lt;featureManager&amp;gt;
    &amp;lt;feature&amp;gt;mpRestClient-2.0&amp;lt;/feature&amp;gt;
    &amp;lt;!-- ... --&amp;gt;
  &amp;lt;/featureManager&amp;gt;
  &amp;lt;!-- ... --&amp;gt;
&amp;lt;/server&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it! Now that we’ve got our development and deployment environments set up, it’s time to code!&lt;/p&gt;

&lt;h2&gt;
  
  
  Using QueryParamStyle to specify how collections of query parameters should be formatted
&lt;/h2&gt;

&lt;p&gt;Rest Client interfaces can specify query parameters using the &lt;code&gt;@QueryParam("paramName")&lt;/code&gt; annotation, but often a server will require that multi-valued query parameters must be formatted in a certain way. For example, suppose we have a client interface like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
@RegisterRestClient
public interface MyClient {
    @GET
    String multiValues(@QueryParam("myParam") List&amp;lt;String&amp;gt; values);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, if a caller invokes the client with &lt;code&gt;multiValues(Arrays.asList("a", "b", "c"))&lt;/code&gt; the MP Rest Client will produce an HTTP request with multiple key/value pairs – something like:&lt;br&gt;
&lt;code&gt;?myParam=a&amp;amp;myParam=b&amp;amp;myParam=c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Although most servers will handle that just fine, some servers might require the HTTP request to be a single key with a comma-separated list of values, like:&lt;br&gt;
&lt;code&gt;?myParam=a,b,c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Still other servers will require array-like syntax, such as:&lt;br&gt;
&lt;code&gt;?myParam[]=a&amp;amp;myParam[]=b&amp;amp;myParam[]=c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to support those other server types, you can now use the &lt;code&gt;QueryParamStyle&lt;/code&gt; enum when building the client instance – for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
MyClient client = RestClientBuilder.newBuilder()
                                   .queryParamStyle(QueryParamStyle.COMMA_SEPARATED)
                                   //...
                                   .build(MyClient.class);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you can declare the query parameter style through &lt;a href="https://www.openliberty.io/guides/microprofile-config-intro.html"&gt;MP Config&lt;/a&gt; by using a property like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;com.mypkg.MyClient/mp-rest/queryParamStyle=ARRAY_PAIRS&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The following table lists the &lt;code&gt;QueryParamStyle&lt;/code&gt; enum values and provides an example of the corresponding output for each value.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Enum Value&lt;/th&gt;
&lt;th&gt;Output Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MULTI_PAIRS (default)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?myParam=a&amp;amp;myParam=b&amp;amp;myParam=c&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;COMMA_SEPARATED&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?myParam=a,b,c&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ARRAY_PAIRS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?myParam[]=a&amp;amp;myParam[]=b&amp;amp;myParam[]=c&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Proxy server support
&lt;/h2&gt;

&lt;p&gt;You might need to use a proxy server to access some RESTful endpoints. MicroProfile Rest Client 2.0 makes it easier and more portable to specify a proxy server with the new &lt;code&gt;proxyAddress(host, port)&lt;/code&gt; method on the &lt;code&gt;RestClientBuilder&lt;/code&gt; class. For example, suppose you need to access an endpoint via a proxy server at &lt;code&gt;myproxy.xyz.com&lt;/code&gt; on port &lt;code&gt;1080&lt;/code&gt;. You could build your rest client instance with code like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
MyClient client = RestClientBuilder.newBuilder()
                                   .proxyAddress("myproxy.xyz.com", 1080)
                                   //...
                                   .build(MyClient.class);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you can specify the proxy address via MP Config with a property like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;com.mypkg.MyClient/mp-rest/proxyAddress=myproxy.xyz.com:1080&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note that for portability, this approach to setting the proxy server host and port is preferred to using vendor-specific properties such as &lt;code&gt;com.ibm.ws.jaxrs.client.proxy.host&lt;/code&gt; and &lt;code&gt;com.ibm.ws.jaxrs.client.proxy.port&lt;/code&gt;, though these properties will still work. For proxy authentication, you can still use the &lt;code&gt;com.ibm.ws.jaxrs.client.proxy.username&lt;/code&gt; and &lt;code&gt;com.ibm.ws.jaxrs.client.proxy.password&lt;/code&gt; properties. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
MyClient client = RestClientBuilder.newBuilder()
                                   .proxyAddress("myproxy.xyz.com", 1080)
                                   .property("com.ibm.ws.jaxrs.client.proxy.username", "andymc12")
                                   .property("com.ibm.ws.jaxrs.client.proxy.password", "12345") //same as my luggage! ![🙂](https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png)
                                   //...
                                   .build(MyClient.class);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Automatically following redirects
&lt;/h2&gt;

&lt;p&gt;If a RESTful resource has been relocated, often the HTTP response code will be in the 300 range and will indicate the new location. Rather than handling the 3XX response and manually issuing a new request, MP Rest Client 2.0 allows rest client instances to automatically follow redirects. You can configure a client to automatically follow redirects either programmatically, when you build the client instance, or via MP Config. Here is an example of configuring auto-redirect via the &lt;code&gt;RestClientBuilder&lt;/code&gt; API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
MyClient client = RestClientBuilder.newBuilder()
                                   .followRedirects(true)
                                   //...
                                   .build(MyClient.class);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is how you would configure it via MP Config:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;com.mypkg.MyClient/mp-rest/followRedirects=true&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Support for Server Sent Events
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://openliberty.io/guides/reactive-messaging-sse.html"&gt;Server Sent Events&lt;/a&gt; (SSE), part of the HTML 5 spec, enable a server to push data to a client asynchronously via events, over HTTP. The JAX-RS 2.1 spec enabled SSE support for both the client and server. Now you can consume SSE events from the type-safe MP Rest Client.&lt;/p&gt;

&lt;p&gt;The MP Rest Client specification uses the &lt;a href="http://www.reactive-streams.org/"&gt;Reactive Streams&lt;/a&gt; APIs to consume events. A client interface capable of consuming SSEs looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
@RegisterRestClient
public interface SseClient {
    @GET
    @Path("/path/sse")
    @Produces(MediaType.SERVER_SENT_EVENTS)
    Publisher&amp;lt;String&amp;gt; getStrings();
    @GET
    @Path("/path/sse2")
    @Produces(MediaType.SERVER_SENT_EVENTS)
    Publisher&amp;lt;InboundSseEvent&amp;gt; getEvents();
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, the method (or interface) must be annotated with &lt;code&gt;@Produces(MediaType.SERVER_SENT_EVENTS)&lt;/code&gt; to indicate that it expects the server to produce SSEs. Next, the method’s return type must be &lt;code&gt;org.reactivestreams.Publisher&lt;/code&gt;. The generic type can be &lt;code&gt;javax.ws.rs.sse.InboundSseEvent&lt;/code&gt; (from JAX-RS), a primitive, a String, or a complex type. Complex types can only be used if:&lt;/p&gt;

&lt;p&gt;1) the server only sends one type of event (e.g. only sends &lt;code&gt;WeatherEvents&lt;/code&gt; – then &lt;code&gt;Publisher&amp;lt;WeatherEvent&amp;gt;&lt;/code&gt; would be applicable)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;and&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;2) there is a registered entity provider capable of converting the events (e.g. &lt;code&gt;MessageBodyReader&amp;lt;WeatherEvent&amp;gt;&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;In most cases, if the remote server sends events using JSON, you can enable the &lt;code&gt;jsonb-1.0&lt;/code&gt; feature in your Liberty server, which will automatically register a JSON-B-based entity provider.&lt;/p&gt;

&lt;p&gt;Once you invoke one of these methods, you can register one or more &lt;code&gt;Subscriber&lt;/code&gt; instances to the &lt;code&gt;Publisher&lt;/code&gt;. Each subscriber will be notified on receipt of a new event or if the connection to the server has been closed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;MicroProfile Rest Client 2.0 has some powerful new features that are useful for building cloud native applications. You can read more about these updates on the &lt;a href="https://github.com/eclipse/microprofile-rest-client/releases/tag/2.0"&gt;MP Rest Client 2.0 release page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;MicroProfile Rest Client 2.0 is part of the larger MicroProfile 4.0 release. If you’d like to learn more about the other technologies in MicroProfile 4.0, check out this &lt;a href="https://openliberty.io/blog/2021/03/19/microprofile40-open-liberty-21003.html"&gt;deep dive blog post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As always, let us know if you have any questions with this new feature. Thanks for checking it out!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally posted on March 24, 2021 at:&lt;br&gt;&lt;br&gt;
&lt;a href="https://openliberty.io/blog/2021/03/24/whats-new-in-MP-Rest-Client2.0.html"&gt;https://openliberty.io/blog/2021/03/24/whats-new-in-MP-Rest-Client2.0.html&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rest</category>
      <category>client</category>
      <category>java</category>
      <category>microprofile</category>
    </item>
    <item>
      <title>Have it your way with MicroProfile GraphQL!</title>
      <dc:creator>Andy McCright</dc:creator>
      <pubDate>Sun, 02 May 2021 20:28:15 +0000</pubDate>
      <link>https://dev.to/andymc12/have-it-your-way-with-microprofile-graphql-c81</link>
      <guid>https://dev.to/andymc12/have-it-your-way-with-microprofile-graphql-c81</guid>
      <description>&lt;p&gt;&lt;a href="https://openliberty.io/blog/2020/06/05/graphql-open-liberty-20006.html"&gt;Open Liberty 20.0.0.6&lt;/a&gt; introduces a new feature, &lt;a href="https://github.com/eclipse/microprofile-graphql"&gt;MicroProfile GraphQL&lt;/a&gt;, which enables developers to quickly and easily write GraphQL applications with MicroProfile.&lt;/p&gt;

&lt;p&gt;If you’re here reading about GraphQL in Open Liberty, then chances are that you already know a bit about GraphQL. In short, GraphQL is a remote data access API that addresses issues like under-fetching and over-fetching that are inherent in most RESTful applications. It allows clients to specify the exact data they want – to “have it their way”. If you would like to learn more about GraphQL, I recommend checking out the &lt;a href="https://graphql.org/learn/"&gt;tutorial at GraphQL.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;GraphQL applications use a schema that acts as a description of the data provided by the server and as a contract between the client and server. Most GraphQL programming models require developers to dual-maintain their schema and the application code that supports it. MicroProfile GraphQL takes a “code first” approach which allows developers to write Java code using annotations to mark GraphQL schema elements, and then the MicroProfile GraphQL implementation generates the schema at runtime.&lt;/p&gt;

&lt;p&gt;The Open Liberty feature Microprofile GraphQL (&lt;code&gt;mpGraphQL-1.0&lt;/code&gt;) implements the &lt;a href="https://github.com/eclipse/microprofile-graphql/releases/tag/1.0.2"&gt;MicroProfile GraphQL 1.0 specification&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll explore how easy it is to create GraphQL applications using this &lt;a href="https://github.com/OpenLiberty/sample-mp-graphql"&gt;sample&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;To set up your Maven environment for developing a MP GraphQL application, you’ll need a dependency like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.eclipse.microprofile.graphql&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;microprofile-graphql-api&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.2&amp;lt;/version&amp;gt;
    &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I recommend using the &lt;a href="https://openliberty.io/guides/maven-intro.html"&gt;Liberty Maven plugin&lt;/a&gt;, but it’s not strictly necessary so long as you generate a Web Archive (WAR) file for deployment.&lt;/p&gt;

&lt;p&gt;When configuring the Liberty server for deployment, make sure that the &lt;code&gt;featureManager&lt;/code&gt; element in the &lt;code&gt;server.xml&lt;/code&gt; file contains the &lt;code&gt;mpGraphQL-1.0&lt;/code&gt; feature. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;server&amp;gt;
  &amp;lt;featureManager&amp;gt;
    &amp;lt;feature&amp;gt;mpGraphQL-1.0&amp;lt;/feature&amp;gt;
    &amp;lt;feature&amp;gt;mpMetrics-2.3&amp;lt;/feature&amp;gt;
  &amp;lt;/featureManager&amp;gt;
  &amp;lt;!-- ... --&amp;gt;
&amp;lt;/server&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;mpMetrics-2.3&lt;/code&gt; feature is not required, but will track the number of GraphQL query/mutation invocations and cumulative time when enabled.&lt;/p&gt;

&lt;p&gt;Now that we’ve got things set up, let’s look at the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding a MicroProfile GraphQL application
&lt;/h2&gt;

&lt;p&gt;A MicroProfile GraphQL application should have at least one root-level query and/or mutation. To create a query or mutation, you start with a public Java class annotated with &lt;code&gt;@GraphQLApi&lt;/code&gt;. Then you add public methods that are annotated with &lt;code&gt;@Query&lt;/code&gt; or &lt;code&gt;@Mutation&lt;/code&gt; for query or mutation, respectively. The query/mutation methods must always return a non-void type. These methods can return simple types like &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;double&lt;/code&gt;, &lt;code&gt;boolean&lt;/code&gt;, etc. which will be mapped to GraphQL scalars such as &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Int&lt;/code&gt;, &lt;code&gt;Float&lt;/code&gt;, &lt;code&gt;Boolean&lt;/code&gt;, etc. Alternatively, these methods could return custom Java types – the types would be mapped to GraphQL types and defined in the generated schema. For more details, see the &lt;a href="https://download.eclipse.org/microprofile/microprofile-graphql-1.0.2/apidocs/"&gt;MicroProfile GraphQL 1.0.2 API Docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example, in the sample application, the &lt;code&gt;currentConditions&lt;/code&gt; query method returns a type called &lt;code&gt;Conditions&lt;/code&gt; – that type has properties such as &lt;code&gt;temperatureF&lt;/code&gt;, &lt;code&gt;temperatureC&lt;/code&gt;, &lt;code&gt;precipitationType&lt;/code&gt;, &lt;code&gt;weatherText&lt;/code&gt;, etc. The following schema is generated from the query and its return value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
type Conditions {
  dayTime: Boolean!
  epochTime: BigInteger!
  hasPrecipitation: Boolean!
  "ISO-8601"
  localObservationDateTime: DateTime
  location: String
  precipitationType: PrecipType
  temperatureC: Float!
  temperatureF: Float!
  weatherText: String
  wetBulbTempF: Float!
}

"Query root"
type Query {
  currentConditions(location: String): Conditions
  currentConditionsList(locations: [String]): [Conditions]
}
...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;currentConditions&lt;/code&gt; query has an argument, called &lt;code&gt;location&lt;/code&gt;. In the Java code, the argument is represented by a method parameter. Like output types, arguments/parameters can be simple Java types (mapping to GraphQL scalars) or custom types, which would be mapped to input types in the generated schema.&lt;/p&gt;

&lt;p&gt;When mapping custom types, it is possible to change the name used in the schema by using the &lt;code&gt;@Name&lt;/code&gt; annotation. For example, if we wanted to change the schema to display &lt;code&gt;tempInFahrenheit&lt;/code&gt; instead of &lt;code&gt;temperatureF&lt;/code&gt;, we could just add &lt;code&gt;@Name("tempInFahrenheit")&lt;/code&gt; to the &lt;code&gt;temperatureF&lt;/code&gt; field in the &lt;code&gt;Conditions&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;If your application uses JSON-B, then &lt;code&gt;@JsonbProperty&lt;/code&gt;, &lt;code&gt;@JsonbDateFormat&lt;/code&gt;, and &lt;code&gt;@JsonbNumberFormat&lt;/code&gt; annotations can be used instead of &lt;code&gt;@Name&lt;/code&gt;, &lt;code&gt;@DateFormat&lt;/code&gt; or &lt;code&gt;@NumberFormat&lt;/code&gt;. When both sets of annotations are used, the annotations from the MicroProfile GraphQL APIs take precedence over the JSON-B APIs when used for schema generation or query/mutation execution.&lt;/p&gt;

&lt;p&gt;Another useful annotation is &lt;code&gt;@Source&lt;/code&gt;. This annotation can be used to add a field to an entity object that might be expensive to look up or calculate, and so you might not want to spend the resources on the server side to compute that field when the client doesn’t want it anyway. Here’s an example from the sample:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
    public double wetBulbTempF(@Source @Name("conditions") Conditions conditions) {
        // TODO: pretend like this is a really expensive operation
        // ...
        return conditions.getTemperatureF() - 3.0;
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example is a little contrived, but it shows us that the &lt;code&gt;wetBulbTempF&lt;/code&gt; field will only be computed if the client requests that field. This method is in a class annotated with &lt;code&gt;@GraphQLApi&lt;/code&gt; (in this example, &lt;code&gt;WeatherService&lt;/code&gt;) and it contains a parameter annotated with &lt;code&gt;@Source&lt;/code&gt; that takes the entity object, &lt;code&gt;Conditions&lt;/code&gt;. When a client issues a query or mutation that would return the &lt;code&gt;Conditions&lt;/code&gt; entity, and that query/mutation specifies the &lt;code&gt;wetBulbTempF&lt;/code&gt; field, the &lt;code&gt;wetBulbTempF(Conditions conditions)&lt;/code&gt; method is invoked by the GraphQL implementation, passing in the &lt;code&gt;Conditions&lt;/code&gt; object that was returned from the query/mutation method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the MicroProfile GraphQL app
&lt;/h2&gt;

&lt;p&gt;To run and test the GraphQL application, you simply need to deploy it as a WAR file. The Liberty Maven Plugin makes it easy to build, deploy, and test using Apache Maven. After you have cloned the sample from GitHub (&lt;code&gt;git clone git@github.com:OpenLiberty/sample-mp-graphql.git&lt;/code&gt;) or downloaded the source ZIP file, just run: &lt;code&gt;mvn clean package liberty:run&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This builds, packages, and deploys the GraphQL application to the latest Open Liberty server runtime and starts the server and app. Then you can use the pre-packaged GraphiQL HTML interface to send queries or mutations at: &lt;code&gt;http://localhost:9080/mpGraphQLSample/graphiql.html&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here are a few sample queries and mutations that you could use to get started – you may see some interesting results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#Temperature (Fahrenheit) for Las Vegas
query LasVegas {
  currentConditions(location: "Las Vegas") {
    temperatureF
  }
}



#Is it really always sunny in Philadelphia?
query SunnyInPhilly {
  currentConditions(location: "Philadelphia") {
    weatherText
  }
}



# Weather conditions for three locations - one roundtrip
query threeLocations {
  atlanta: currentConditions(location: "Atlanta") {
        hasPrecipitation
        temperatureF
        weatherText
        precipitationType
    }
  newyork: currentConditions(location: "New York") {
        hasPrecipitation
        temperatureF
        weatherText
        precipitationType
  }
  chicago: currentConditions(location: "Chicago") {
        hasPrecipitation
        temperatureF
        weatherText
        precipitationType
    }
}



# See partial results when one portion of the query fails
query fourLocations {
  atlanta: currentConditions(location: "Atlanta") {
        hasPrecipitation
        temperatureF
        weatherText
        precipitationType
        wetBulbTempF
    }
  nowhere: currentConditions(location: "Nowhere") {
    hasPrecipitation
        temperatureF
        weatherText
        precipitationType
  }
  newyork: currentConditions(location: "New York") {
        hasPrecipitation
        temperatureF
        weatherText
        precipitationType
  }
  chicago: currentConditions(location: "Chicago") {
        hasPrecipitation
        temperatureF
        weatherText
        precipitationType
        wetBulbTempF
    }
}



# Reset the stored weather conditions
mutation {
  reset
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Authorizing access to certain queries/mutations
&lt;/h2&gt;

&lt;p&gt;It may be necessary to restrict access to certain queries/mutations to certain authenticated users. While it is not part of the MicroProfile GraphQL 1.0 specification (it is under consideration for a future version of the spec), Open Liberty makes authorization checks possible by using the &lt;code&gt;@DenyAll&lt;/code&gt;, &lt;code&gt;@PermitAll&lt;/code&gt;, and &lt;code&gt;@RolesAllowed&lt;/code&gt; annotations. These annotations must be placed on the class or method of classes annotated with &lt;code&gt;@GraphQLApi&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When implementing authorization with MicroProfile GraphQL, you need to enable the &lt;code&gt;appSecurity-3.0&lt;/code&gt; (or &lt;code&gt;appSecurity-2.0&lt;/code&gt;) feature in the server configuration. You also need to set up the user registry and web container metadata for authentication and authorization.&lt;/p&gt;

&lt;p&gt;In the sample, we use the basic user registry which defines two users, one for each of two roles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  &amp;lt;basicRegistry id="basic" realm="sample-mp-graphql"&amp;gt;
     &amp;lt;user name="user1" password="user1pwd" /&amp;gt;
     &amp;lt;user name="user2" password="user2pwd" /&amp;gt;
     &amp;lt;group name="Role1"&amp;gt;
       &amp;lt;member name="user1"/&amp;gt;
     &amp;lt;/group&amp;gt;
     &amp;lt;group name="Role2"&amp;gt;
       &amp;lt;member name="user2"/&amp;gt;
     &amp;lt;/group&amp;gt;
   &amp;lt;/basicRegistry&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that &lt;code&gt;user1&lt;/code&gt; is part of &lt;code&gt;Role1&lt;/code&gt; and &lt;code&gt;user2&lt;/code&gt; is part of &lt;code&gt;Role2&lt;/code&gt;. The &lt;code&gt;web.xml&lt;/code&gt; declares these roles, and also sets up form-based authentication so that, when the Application Security feature is enabled, clients are prompted to log in using a web-based form before accessing the GraphiQL HTML page. It also allows the application to prevent users other than those in &lt;code&gt;Role2&lt;/code&gt; to invoke the &lt;code&gt;reset&lt;/code&gt; mutation method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
    @RolesAllowed("Role2")
    @Mutation
    @Description("Reset the cached conditions so that new queries will return newly randomized weather data." +
                 "Returns number of entries cleared.")
    public int reset() {
        int cleared = currentConditionsMap.size();
        currentConditionsMap.clear();
        return cleared;
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Integration with MicroProfile Metrics
&lt;/h2&gt;

&lt;p&gt;If you enable the &lt;code&gt;mpMetrics-2.3&lt;/code&gt; feature with &lt;code&gt;mpGraphQL-1.0&lt;/code&gt;, Open Liberty tracks the number of times a particular query or mutation method is invoked—​and the cumulative time spent in that method. These metrics can be useful for determining what data is being accessed, how often, and where time is spent in execution.&lt;/p&gt;

&lt;p&gt;Metrics collection and reporting for GraphQL applications is not mentioned in either the MicroProfile GraphQL 1.0 spec or the MicroProfile Metrics 2.3 spec, so the actual stats are collected and reported under the “vendor” category. To see these stats, you can browse to: &lt;code&gt;http://localhost:9080/metrics/vendor&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The stats are prefixed with &lt;code&gt;vendor_mp_graphql_&lt;/code&gt; and should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
# TYPE vendor_mp_graphql_Query_currentConditions_total counter
vendor_mp_graphql_Query_currentConditions_total 27
# TYPE vendor_mp_graphql_Query_currentConditions_elapsedTime_seconds gauge
vendor_mp_graphql_Query_currentConditions_elapsedTime_seconds 0.10273818800000001
# TYPE vendor_mp_graphql_Conditions_wetBulbTempF_total counter
vendor_mp_graphql_Conditions_wetBulbTempF_total 4
# TYPE vendor_mp_graphql_Conditions_wetBulbTempF_elapsedTime_seconds gauge
vendor_mp_graphql_Conditions_wetBulbTempF_elapsedTime_seconds 0.031866015000000004
# TYPE vendor_mp_graphql_Mutation_reset_total counter
vendor_mp_graphql_Mutation_reset_total 3
# TYPE vendor_mp_graphql_Mutation_reset_elapsedTime_seconds gauge
vendor_mp_graphql_Mutation_reset_elapsedTime_seconds 0.007540145000000001

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;GraphQL is a powerful and popular query language for remote data access. MicroProfile GraphQL makes it easy to develop GraphQL applications in Java. And now you use GraphQL in Open Liberty!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally posted on June 10, 2020 at:&lt;br&gt;&lt;br&gt;
&lt;a href="https://openliberty.io/blog/2020/06/10/microprofile-graphql-open-liberty.html"&gt;https://openliberty.io/blog/2020/06/10/microprofile-graphql-open-liberty.html&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>graphql</category>
      <category>microprofile</category>
    </item>
  </channel>
</rss>
