A brief overview of the new features of JPA-RS in 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
Комментарии
Отправить комментарий