A brief overview of the new features of JPA-RS in EclipseLink

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


the

version of the service in the URL


From version to version it is possible to change the semantics of the data transfer Protocol. JSON schema resources in version 2.0 of the service differs from the JSON schema used in the previous version. For compatibility with JPA-RS is able to return data using the old formats. For this version of the Protocol passed in the URL.

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

Where:
the

    server:port — address and port of the server.

    app is the name of your application (context root).

    persistence — the entry Point to JPA-RS application. Constant.

    version — Not required. The version of JPA-RS. Currently supported values are "v1.0" (previous version) "v2.0" (new version), and "latest" (latest version).

    persistent-unit is the Name of the persistent unit as specified in persistence.xml.


The version of the service may be omitted, in this case, the value is "v1.0".

Examples:

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

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

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

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

Next, purely for readability purposes, I will set http(s)://localhost:8080/jpars-test/persistence/v2.0 {root}.

the

pagination


JPARS that allows you to create pages with long lists and return only the user-selected page. It works for query (Named Query) and for fields of type Collection.
Pagination is only a function of the JPA-RS that require configuration. This is done using annotations.

Consider the following example:
the
@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 a standard entity class with two JPARS annotations.
the
@RestPageableQueries({
@RestPageableQuery(queryName = "Car.findAllPageable", limit = 20)
})

This piece of code says that the request is Car.findAllPageable must be issued through RESTful services page by page with page size 20 records.
For the configuration of pagination when the call uses two parameters:
the

    limit — page size. Can not be higher than the limit values specified in the annotation @RestPageableQuery. It is also the default value.

    offset is the offset from the beginning of the list. The sequence number of the first returned record. Default value is 0.


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

and will return the following JSON:
the
{
"items": [
{
"id": 1,
"name": "Mazda MX-5",
...
},
... <19 records> ...
],
"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",

}
]
}

The server's response also provides additional information:
the

    hasMore — true if this page is not the last.

    limit — the page size used by the server.

    offset are used as an offset.

    count — number of records per page.

    link to next — the URL of the next page (if available)

    link to prev — the URL of the previous page (if available)


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

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

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

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


The server always uses a minimum limit of Aksenovo in the query and ispolzuemnogo in annotatsii. That is
the
{root}/query/Car.findAllPageable?limit=100

will return only 20 records. The limit value in the response from the server 20, as in the example above.

the

Filter fields


When you request data it is sometimes necessary to return the entire record, but only some of the fields. For example, longDescr field of the Car class contains a text of considerable size, which we don't want to stream over the network. For this is filtering fields.

Filtering is configured in two parameters:
the

    fields — list of fields returned by the server. Fields are separated by commas.

    excludeFields — list of fields that are not returned by the server.


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

Will return only the fields id, name and shortDescr Car class:
the
{
"id": 1,
"name": "Mazda MX-5",
"shortDescr": "double Roadster",
...
}

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

If you attempt to use both parameters and excludeFields fields in a single query, the server will return an error.

the

Metadata


Metadata contain additional information about the resource. In our case, is a reference to a JSON schema and base resource URL.

For example, the metadata for our Car class look like this:
the
{
"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"
}
]
}

Get metadata for a class of Car like:
the
{root}/metadata-catalog/entity/Car

To request a Car.findAll:
the
{root}/metadata-catalog/query/Car.findAll

Another way of getting metadata — call the OPTIONS method on the base URL of the resource.
the
OPTIONS <root>/entity/Basket

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


the

resources Directory


Catalogue of resources as the table of contents contains metadata for all available resources. This is the right place to start working with unfamiliar service. Here you can always see the available object, and queries.

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

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

I cut the server's response is solely for readability. Medalonnye for all resources look the same as stated in the beginning of the Chapter.

the

JSON schema resources


Although JSON schema while not an approved standard and the work on the specification is still not finished, JPS-RS already partially supports draft 4 specification. This applies to the output format of objects and list of objects.

URL resource metadata can be used to make it (the resource) for JSON schemas. To do this, run the HTTP GET request using the media type "application/schema+json". That is, by setting the HTTP accept header set to "application/schema+json".
Receiving a schema for the class Car:
the
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)

The server response was:
the
{
"$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 about it. Hope you liked the review.

EclipseLink Nightly builds can be downloaded here:
www.eclipse.org/eclipselink/downloads/nightly.php
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Templates ESKD and GOST 7.32 for Lyx 1.6.x

Monitoring PostgreSQL + php-fpm + nginx + disk using Zabbix

Custom table in MODx Revolution