📜 ⬆️ ⬇️

Overview of JPA-RS New Features in EclipseLink

EclipseLink is an open source ORM framework developed by the Eclipse Foundation. At the end of the year, the release of version 2.6.0 is planned. project. In anticipation of this, I want to introduce you to some of the new features of the JPA-RS service, which is part of EclipseLink.
JPA-RS allows you to automatically generate RESTful services based on the model provided by the user JPA. At the same time, practically no additional work is required from the user.


Service version in URL


From version to version it is possible to change the semantics of the data transfer protocol. JSON-scheme of resources in version 2.0 of the service is different from the JSON-scheme used in the previous version. For compatibility, JPA-RS can return data using old formats. For this version of the protocol rendered in the URL.

The base URL looks like this:
http(s)://{server:port}/{app}/persistence/{version}/{persistent-unit}/... 

Where:

The service version may be skipped, in this case the value “v1.0” is used.
')
Examples:

A request for a Car object with a primary key of 1 from the persistent car-pu unit using protocol semantics version 1.0:
 http(s)://localhost:8080/jpars-test/persistence/car-pu/entity/Car/1 

Same:
 http(s)://localhost:8080/jpars-test/persistence/v1.0/car-pu/entity/Car/1 

Request the same data, but using the semantics of service version 2.0:
 http(s)://localhost:8080/jpars-test/persistence/v2.0/car-pu/entity/Car/1 

Since the latest version is currently 2.0, the following query will return the same as the previous one:
 http(s)://localhost:8080/jpars-test/persistence/latest/car-pu/entity/Car/1 

Further, solely for readability, I will designate http (s): // localhost: 8080 / jpars-test / persistence / v2.0 as {root} .

Paginated output


JPARS allows you to paginate long lists and return only the page selected by the user. This works for queries (Named Query) and for fields of type Collection.
Paging is the only JPA-RS function that requires configuration. This is done using annotations.

Consider the following example:
 @Entity @Table(name = "CAR") @NamedQueries({ @NamedQuery( name = "Car.findAll", query = "SELECT c FROM Car c ORDER BY c.name"), @NamedQuery( name = "Car.findAllPageable", query = "SELECT c FROM Car c ORDER BY c.name"), }) @RestPageableQueries({ @RestPageableQuery(queryName = "Car.findAllPageable", limit = 20) }) public class Car { @Id @Column(name = "CAR_ID") private Integer id; @Column(name = "CAR_NAME") private String name; @Column(name = "CAR_SHORT_DESCR") private String shortDescr; @Column(name = "CAR_LONG_DESCR") private String longDescr; // Getters and setters are skipped } 


This is the standard entity class with two JPARS annotations.
 @RestPageableQueries({ @RestPageableQuery(queryName = "Car.findAllPageable", limit = 20) }) 

This piece of code says that the Car.findAllPageable request should be issued through a RESTful service page by page with a page size of 20 entries.
To configure paginal output, the call uses two parameters:

For example, the following queries are similar:
 GET <root>/query/Car.findAllPageable GET <root>/query/Car.findAllPageable?limit=20&offset=0 

and return the following JSON:
 { "items": [ { "id": 1, "name": "Mazda MX-5", ... }, ... < 19 > ... ], "hasMore": true, "limit": 20, "offset": 0, "count": 20, "links": [ { "rel": "self", "href": "{root}/query/Car.findAllPageable" } { "rel": "canonical", "href": "{root}/query/Car.findAllPageable" } { "rel": "next", "href": "{root}/query/Car.findAllPageable?offset=20" } ] } 

The server response also contains additional information:

Second page:
 {root}/query/Car.findAllPageable?offset=20 

or
 {root]/query/Car.findAllPageable?limit=20&offset=20 

The third page of 10 entries:
 {root}/query/Car.findAllPageable?limit=10&offset=20 

7 entries since the third:
 {root}/query/Car.findAllPageable?limit=7&offset=3 


The server always uses the minimum limit specified in the request and used in the annotation. I.e
 {root}/query/Car.findAllPageable?limit=100 

returns only 20 entries. The limit value in the server response will be 20, as in the example above.

Filtering fields


When requesting data, sometimes it is necessary to return not the entire record, but only some fields. For example, the Car class longDescr field contains an impressively sized text that we do not want to transmit over the network. For this is the filtering of fields.

Filtering is configured by two parameters:

For example:
 GET {root}/entity/Car/1?fields=id,name,shortDescr 

Return only the id , name and shortDescr fields of the Car class:
 { "id": 1, "name": "Mazda MX-5", "shortDescr": " ", ... } 

The same query will return the same:
 GET {root}/entity/Car/1?excludeFields=longDescr 

If you try to use both the fields and excludeFields parameters in one request, the server will return an error.

Metadata


Metadata contains additional information about the resource. In our case, this is a link to the JSON resource scheme and the base URL.

For example, the metadata for our Car class look like this:
 { "name": "Car", "links": [ { "rel": "alternate", "href": "<root>/metadata-catalog/entity/Car", "mediaType": "application/schema+json" }, { "rel": "canonical", "href": "<root>/metadata-catalog/entity/Car", "mediaType": "application/json" }, { "rel": "describes", "href": "{root}/entity/Car" } ] } 

You can get metadata for the Car class like this:
 {root}/metadata-catalog/entity/Car 

For the Car.findAll query like this:
 {root}/metadata-catalog/query/Car.findAll 

Another way to get metadata is to call the OPTIONS method on the base URL of the resource.
 OPTIONS <root>/entity/Basket 

The server will return the link to the metadata in the Link header c rel = "describedby"
 Link: <root/metadata-catalog/entity/Basket>; rel="describedby" 


Resource catalog


The resource catalog, like the book's table of contents, contains metadata for all available resources. This is the right place to start working with an unfamiliar service. Here you can always see the available objects and requests.

The resource catalog is available at the following address:
 GET <root>/metadata-catalog 

Server response:
 { "items": [ { "name": "Car", ... }, { "name": "Car.findAll", ... }, { "name": "Car.findAllPageable", ... } ], "links": [ { "rel": "canonical", "href": "<root>/metadata-catalog" } ] } 

I trimmed the server response solely for readability. Metadata for all resources also looks as indicated at the beginning of the chapter.

JSON resource schema


Although the JSON schema is not yet an approved standard and the work on the specification has not yet been completed, the JPS-RS already partially supports draft 4 specifications. This concerns the output format of objects and the list of objects.

The resource metadata URL can also be used to get its (resource) JSON schema. To do this, perform an HTTP GET request using the media type “application / schema + json”. That is, by setting the value of “application / schema + json” in the HTTP header “accept”.

Getting the schema for the Car class:
 GET <root>/metadata-catalog/entity/Car HTTP/1.1 Accept-Encoding: gzip,deflate accept: application/schema+json Host: <host:port> Proxy-Connection: Keep-Alive User-Agent: Apache-HttpClient/4.1.1 (java 1.5) 

Server response:
 { "$schema": "<root>/metadata-catalog/entity/Car#", "allOf": [ { "$ref": "rest-schemas/#/singularResource" } ], "title": "Car", "properties": { "id": { "type": "number" }, "name": { "type": "string" }, "shortDescr": { "type": "string" }, "longDescr": { "type": "string" }, }, "links": [ { "rel": "describedby", "href": "<root>/entity/Car" }, { "rel": "find", "href": "{root}/entity/Car/{primaryKey}", "method": "GET" }, { "rel": "create", "href": "{root}/entity/Car", "method": "PUT" }, { "rel": "update", "href": "{root}/entity/Car", "method": "POST" }, { "rel": "delete", "href": "{root}/entity/Car/{primaryKey}", "method": "DELETE" } ] } 

That's all. Hope you enjoyed the review.

Nightly builds EclipseLink can be downloaded here:
www.eclipse.org/eclipselink/downloads/nightly.php

Source: https://habr.com/ru/post/240769/


All Articles