#1190 - Fix typos, document links, and grammatical errors.
Unfinished sentences were marked with ellipsis….
This commit is contained in:
committed by
Oliver Drotbohm
parent
09c1baecc9
commit
d922d6f74c
@@ -77,7 +77,7 @@ Instead of fetching a single resource, this one deserializes a collection into `
|
||||
|
||||
When working with hypermedia enabled representations, a common task is to find a link with a particular relation type in it. Spring HATEOAS provides https://code.google.com/p/json-path[JSONPath]-based implementations of the `LinkDiscoverer` interface for either the default representation rendering or HAL out of the box. When using `@EnableHypermediaSupport`, we automatically expose an instance supporting the configured hypermedia type as a Spring bean.
|
||||
|
||||
Alternatively, you can setup and use an instance as follows:
|
||||
Alternatively, you can set up and use an instance as follows:
|
||||
|
||||
====
|
||||
[source, java]
|
||||
|
||||
@@ -6,7 +6,7 @@ This section describes how to configure Spring HATEOAS.
|
||||
[[configuration.at-enable]]
|
||||
== Using `@EnableHypermediaSupport`
|
||||
|
||||
To let the `RepresentationModel` subtypes be rendered according to the specification of various hypermedia representations types, you can activate support for a particular hypermedia representation format through `@EnableHypermediaSupport`. The annotation takes a `HypermediaType` enumeration as its argument. Currently, we support https://tools.ietf.org/html/draft-kelly-json-hal[HAL] as well as a default rendering. Using the annotation triggers the following:
|
||||
To let the `RepresentationModel` subtypes be rendered according to the specification of various hypermedia representation types, you can activate support for a particular hypermedia representation format through `@EnableHypermediaSupport`. The annotation takes a `HypermediaType` enumeration as its argument. Currently, we support https://tools.ietf.org/html/draft-kelly-json-hal[HAL] as well as a default rendering. Using the annotation triggers the following:
|
||||
|
||||
* It registers necessary Jackson modules to render `EntityModel` and `CollectionModel` in the hypermedia specific format.
|
||||
* If JSONPath is on the classpath, it automatically registers a `LinkDiscoverer` instance to look up links by their `rel` in plain JSON representations (see <<client.link-discoverer>>).
|
||||
@@ -18,7 +18,7 @@ To let the `RepresentationModel` subtypes be rendered according to the specifica
|
||||
|
||||
By default, `@EnableHypermediaSupport` will reflectively detect the web application stack you're using and hook into the Spring components registered for those to enable support for hypermedia representations.
|
||||
However, there are situations in which you'd only explicitly want to activate support for a particular stack.
|
||||
E.g. if your Spring WebMVC based application uses WebFlux' `WebClient` to make outgoing requests and that one is not supposed to work with hypermedia elements, you can restrict the functionality to be enabled by explicitly declaring WebMvc in the configuration:
|
||||
E.g. if your Spring WebMVC based application uses WebFlux' `WebClient` to make outgoing requests and that one is not supposed to work with hypermedia elements, you can restrict the functionality to be enabled by explicitly declaring WebMVC in the configuration:
|
||||
|
||||
.Explicitly activating hypermedia support for a particular web stack
|
||||
====
|
||||
|
||||
@@ -42,7 +42,7 @@ include::{code-dir}/FundamentalsTest.java[tags=links]
|
||||
`Link` exposes other attributes as defined in https://tools.ietf.org/html/rfc5988[RFC-5988].
|
||||
You can set them by calling the corresponding wither method on a `Link` instance.
|
||||
|
||||
Find more information on how to create links pointing to Spring MVC and Spring WebFlux controllers in <<server.link-builder>>.
|
||||
Find more information on how to create links pointing to Spring MVC and Spring WebFlux controllers in <<server.link-builder.webmvc>> and <<server.link-builder.webflux>>.
|
||||
|
||||
[[fundamentals.uri-templates]]
|
||||
== URI templates
|
||||
@@ -105,7 +105,7 @@ assertThat(IanaLinkRelation.isIanaRel(link.getRel())).isTrue();
|
||||
To easily create hypermedia enriched representations, Spring HATEOAS provides a set of classes with `RepresentationModel` at their root.
|
||||
It's basically a container for a collection of ``Link``s and has convenient methods to add those to the model.
|
||||
The models can later be rendered into various media type formats that will define how the hypermedia elements look in the representation.
|
||||
For more information on this, have a look at <<mediatypes>>
|
||||
For more information on this, have a look at <<mediatypes>>.
|
||||
|
||||
.The `RepresentationModel` class hierarchy
|
||||
====
|
||||
@@ -187,7 +187,7 @@ EntityModel<Person> model = new EntityModel<>(person);
|
||||
For resources that are conceptually collections, a `CollectionModel` is available.
|
||||
Its elements can either be simple objects or `RepresentationModel` instances in turn.
|
||||
|
||||
.Using `EntityModel` to wrap existing objects
|
||||
.Using `CollectionModel` to wrap a collection of existing objects
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
https://tools.ietf.org/html/draft-kelly-json-hal-08[JSON Hypertext Application Language] or HAL is one of the simplest
|
||||
and most widely adopted hypermedia media types adopted when not discussing specific web stacks.
|
||||
|
||||
It was the first spec-based media type adopted by Spring HATEAOS.
|
||||
It was the first spec-based media type adopted by Spring HATEOAS.
|
||||
|
||||
[[mediatypes.hal.configuration]]
|
||||
=== Configuring link rendering
|
||||
@@ -30,7 +30,7 @@ include::{resource-dir}/docs/mediatype/hal/hal-multiple-entry-link-relation.json
|
||||
====
|
||||
|
||||
But if there is only one link for a given relation, the spec is ambiguous. You could render that as either a single object
|
||||
or as 1-item array.
|
||||
or as a single-item array.
|
||||
|
||||
By default, Spring HATEOAS uses the most terse approach and renders a single-link relation like this:
|
||||
|
||||
@@ -77,7 +77,7 @@ include::{code-dir}/SampleAppConfiguration.java[tag=2]
|
||||
<2> Render `prev` link relations as an object when there is only one link.
|
||||
====
|
||||
|
||||
If neither of these match your needs, you can use an Ant-style path patterns:
|
||||
If neither of these match your needs, you can use an Ant-style path pattern:
|
||||
|
||||
.Pattern-based HAL single-link rendering policy
|
||||
====
|
||||
@@ -200,7 +200,7 @@ include::{resource-dir}/docs/mediatype/hal/forms/hal-forms-sample.json[]
|
||||
----
|
||||
====
|
||||
|
||||
Checkout the https://rwcbook.github.io/hal-forms/[HAL-FORMS spec] to understand the details of the *_templates* attribute.
|
||||
Check out the https://rwcbook.github.io/hal-forms/[HAL-FORMS spec] to understand the details of the *_templates* attribute.
|
||||
Read about the <<server.affordances,Affordances API>> to augment your controllers with this extra metadata.
|
||||
|
||||
As for single-item (`EntityModel`) and aggregate root collections (`CollectionModel`), Spring HATEOAS renders them
|
||||
@@ -216,7 +216,7 @@ Spring HATEOAS allows to customize those by shaping the model type for the input
|
||||
|Attribute|Description
|
||||
|`readOnly`| Set to `true` if there's no setter method for the property. If that is present, use Jackson's `@JsonProperty(Access.READ_ONLY)` on the accessors or field explicitly. Not rendered by default, thus defaulting to `false`.
|
||||
|`regex`| Can be customized by using JSR-303's `@Pattern` annotation either on the field or a type. In case of the latter the pattern will be used for every property declared as that particular type. Not rendered by default.
|
||||
|`required`| Can be customized by using JSR-303's `@NotNull`. Not rendered by default and thus defaulting to `false`. Templates using `PATCH` as method will automatically have set all properties to not required.
|
||||
|`required`| Can be customized by using JSR-303's `@NotNull`. Not rendered by default and thus defaulting to `false`. Templates using `PATCH` as method will automatically have all properties set to not required.
|
||||
|===============
|
||||
|
||||
For types that you cannot annotate manually, you can register a custom pattern via a `HalFormsConfiguration` bean present in the application context.
|
||||
@@ -243,7 +243,7 @@ HAL-FORMS contains attributes that are intended for human interpretation, like a
|
||||
These can be defined and internationalized using Spring's resource bundle support and the `rest-messages` resource bundle configured by Spring HATEOAS by default.
|
||||
|
||||
==== Template titles
|
||||
To define a template title use the following pattern: `_templates.$affordanceName.title`. Note, that in HAL-FORMS, the name of a template is `default` if it is the only one.
|
||||
To define a template title use the following pattern: `_templates.$affordanceName.title`. Note that in HAL-FORMS, the name of a template is `default` if it is the only one.
|
||||
This means that you'll usually have to qualify the key with the local or fully qualified input type name that affordance describes.
|
||||
|
||||
.Defining HAL-FORMS template titles
|
||||
@@ -275,7 +275,7 @@ firstName._prompt=Firstname <1>
|
||||
Employee.firstName._prompt=Firstname <2>
|
||||
com.acme.Employee.firstName._prompt=Firstname <3>
|
||||
----
|
||||
<1> All properties named `email` will get "Firstname" rendered, independent of the type they're declared in.
|
||||
<1> All properties named `firstName` will get "Firstname" rendered, independent of the type they're declared in.
|
||||
<2> The `firstName` property in types named `Employee` will be prompted "Firstname".
|
||||
<3> The `firstName` property of `com.acme.Employee` will get a prompt of "Firstname" assigned.
|
||||
====
|
||||
@@ -358,7 +358,7 @@ The previous fragment was lifted from the spec. When Spring HATEOAS renders an `
|
||||
|
||||
* Put the `self` link into both the document's `href` attribute and the item-level `href` attribute.
|
||||
* Put the rest of the model's links into both the top-level `links` as well as the item-level `links`.
|
||||
* Extract the properties from the `EntityModel` and turn them into
|
||||
* Extract the properties from the `EntityModel` and turn them into ...
|
||||
====
|
||||
|
||||
When rendering a collection of resources, the document is almost the same, except there will be multiple entries inside
|
||||
@@ -493,10 +493,10 @@ locale-specific message bundles and even internationalize the metadata.
|
||||
== Registering a custom media type
|
||||
|
||||
Spring HATEOAS allows to integrate support for custom media types through a set of SPIs, that third parties can implement.
|
||||
The building blocks of an such an implementations are:
|
||||
The building blocks of an such an implementation are:
|
||||
|
||||
1. Some form of Jackson ObjectMapper customization. In its most simple case that's a Jackson `Module` implementation.
|
||||
2. A `LinkDiscoverer` implementation so that the client side support is able to detect links in representations generated.
|
||||
2. A `LinkDiscoverer` implementation so that the client-side support is able to detect links in representations generated.
|
||||
3. Some configuration infrastructure that will allow Spring HATEOAS to find the custom implementation and pick up its configuration.
|
||||
|
||||
[[mediatypes.custom.configuration]]
|
||||
@@ -535,7 +535,7 @@ class MyMediaTypeConfigurationProvider
|
||||
The configuration class needs to have a default constructor and expose two methods:
|
||||
|
||||
<1> A method returning a Spring configuration class that will be included in the application bootstrap when Spring HATEOAS is activated (either implicitly via Spring Boot auto-configuration or via `@EnableHypermediaSupport`).
|
||||
<2> A callback method that will get the application selected media types to activate passed. This allows the media type implementation to control, when it it will be activated.
|
||||
<2> A callback method that will get passed the application selected media types to activate. This allows the media type implementation to control, when it will be activated.
|
||||
====
|
||||
|
||||
The configuration class has to implement `HypermediaMappingInformation`. It could look as simple as this:
|
||||
@@ -564,7 +564,7 @@ class MyMediaTypeConfiguration implements HypermediaMappingInformation {
|
||||
----
|
||||
<1> The configuration class returns the media type it wants to get Spring MVC / Spring WebFlux support set up.
|
||||
<2> It overrides `getJacksonModule()` to provide custom serializers to create the media type specific representations.
|
||||
<3> It also declares a custom `LinkDiscoverer` implementation for client side support.
|
||||
<3> It also declares a custom `LinkDiscoverer` implementation for client-side support.
|
||||
====
|
||||
|
||||
The Jackson module usually declares `Serializer` and `Deserializer` implementations for the representation model types `RepresentationModel`, `EntityModel`, `CollectionModel` and `PagedModel`.
|
||||
@@ -574,7 +574,7 @@ In case you need further customization of the Jackson `ObjectMapper` (like a cus
|
||||
=== Recommendations
|
||||
|
||||
The preferred way to implement media type representations is by providing a type hierarchy that matches the expected format and can be serialized by Jackson as is.
|
||||
In the `Serializer` and `Deserializer` implementations registered for `RepresentationModel`, convert the instances into the media type specific model types and then lookup the Jackson serializer for those.
|
||||
In the `Serializer` and `Deserializer` implementations registered for `RepresentationModel`, convert the instances into the media type-specific model types and then lookup the Jackson serializer for those.
|
||||
|
||||
The media types supported by default use the same configuration mechanism as third party implementations would.
|
||||
The media types supported by default use the same configuration mechanism as third-party implementations would do.
|
||||
So it's worth studying the implementations in https://github.com/spring-projects/spring-hateoas/tree/master/src/main/java/org/springframework/hateoas/mediatype[the `mediatype` package].
|
||||
|
||||
@@ -33,7 +33,7 @@ Also the name changes have been reflected in the classes contained in `TypeRefer
|
||||
* The `LinkDiscoverer` API has been moved to the `client` package.
|
||||
* The `LinkBuilder` and `EntityLinks` APIs have been moved to the `server` package.
|
||||
* `ControllerLinkBuilder` has been moved into `server.mvc` and deprecated to be replaced by `WebMvcLinkBuilder`.
|
||||
* `RelProvider` has been renamed to `LinkRelationProvider` and returns `LinkRelation` instances instead of `String`s.
|
||||
* `RelProvider` has been renamed to `LinkRelationProvider` and returns `LinkRelation` instances instead of ``String``s.
|
||||
* `VndError` has been moved to the `mediatype.vnderror` package.
|
||||
|
||||
[[migrate-to-1.0.script]]
|
||||
|
||||
@@ -25,7 +25,7 @@ class PersonController {
|
||||
----
|
||||
====
|
||||
|
||||
We see two conventions here. The first is a collection resource that is exposed through `@GetMapping` annotation of the controller method, with individual elements of that collection exposed as direct sub resources. The collection resource might be exposed at a simple URI (as just shown) or more complex ones (such as `/people/{id}/addresses`). Suppose you would like to link to the collection resource of all people. Following the approach from up above would cause two problems:
|
||||
We see two conventions here. The first is a collection resource that is exposed through `@GetMapping` annotation of the controller method, with individual elements of that collection exposed as direct sub resources. The collection resource might be exposed at a simple URI (as just shown) or more complex ones (such as `/people/{id}/addresses`). Suppose you would like to link to the collection resource of all people. Following the approach from above would cause two problems:
|
||||
|
||||
* To create an absolute URI, you would need to look up the protocol, hostname, port, servlet base, and other values. This is cumbersome and requires ugly manual string concatenation code.
|
||||
* You probably do not want to concatenate the `/people` on top of your base URI, because you would then have to maintain the information in multiple places. If you change the mapping, you then have to change all the clients pointing to it.
|
||||
@@ -45,7 +45,7 @@ assertThat(link.getHref()).endsWith("/people");
|
||||
----
|
||||
====
|
||||
|
||||
The `WebMvcLinkBuilder` uses Spring's `ServletUriComponentsBuilder` under the hood to obtain the basic URI information from the current request. Assuming your application runs at `http://localhost:8080/your-app`, this is exactly the URI on top of which you are constructing additional parts. The builder now inspects the given controller class for its root mapping and, thus, ends up with `http://localhost:8080/your-app/people`. You can also build more nested links as well.
|
||||
The `WebMvcLinkBuilder` uses Spring's `ServletUriComponentsBuilder` under the hood to obtain the basic URI information from the current request. Assuming your application runs at `http://localhost:8080/your-app`, this is exactly the URI on top of which you are constructing additional parts. The builder now inspects the given controller class for its root mapping and thus ends up with `http://localhost:8080/your-app/people`. You can also build more nested links as well.
|
||||
The following example shows how to do so:
|
||||
|
||||
====
|
||||
@@ -72,7 +72,7 @@ return new ResponseEntity<PersonModel>(headers, HttpStatus.CREATED);
|
||||
====
|
||||
|
||||
[[fundamentals.obtaining-links.builder.methods]]
|
||||
==== Building Links that Point to Methods
|
||||
==== Building links that point to methods
|
||||
|
||||
You can even build links that point to methods or create dummy controller method invocations.
|
||||
The first approach is to hand a `Method` instance to the `WebMvcLinkBuilder`.
|
||||
@@ -88,7 +88,7 @@ assertThat(link.getHref()).endsWith("/people/2"));
|
||||
----
|
||||
====
|
||||
|
||||
This is still a bit dissatisfying, as we have to first get a `Method` instance, which throws an exception and is generally quite cumbersome. At least we do not repeat the mapping. An even better approach is to have a dummy method invocation of the target method on a controller proxy, which we can create byi using the `methodOn(…)` helper.
|
||||
This is still a bit dissatisfying, as we have to first get a `Method` instance, which throws an exception and is generally quite cumbersome. At least we do not repeat the mapping. An even better approach is to have a dummy method invocation of the target method on a controller proxy, which we can create by using the `methodOn(…)` helper.
|
||||
The following example shows how to do so:
|
||||
|
||||
====
|
||||
@@ -100,7 +100,7 @@ assertThat(link.getHref()).endsWith("/people/2");
|
||||
----
|
||||
====
|
||||
|
||||
`methodOn(…)` creates a proxy of the controller class that records the method invocation and exposes it in a proxy created for the return type of the method. This allows the fluent expression of the method for which we want to obtain the mapping. However, there are a few constraints on the methods that can be obtained byusing this technique:
|
||||
`methodOn(…)` creates a proxy of the controller class that records the method invocation and exposes it in a proxy created for the return type of the method. This allows the fluent expression of the method for which we want to obtain the mapping. However, there are a few constraints on the methods that can be obtained by using this technique:
|
||||
|
||||
* The return type has to be capable of proxying, as we need to expose the method invocation on it.
|
||||
* The parameters handed into the methods are generally neglected (except the ones referred to through `@PathVariable`, because they make up the URI).
|
||||
@@ -121,7 +121,8 @@ ____
|
||||
REST-based resources provide not just data but controls.
|
||||
The last ingredient to form a flexible service are detailed *affordances* on how to use the various controls.
|
||||
Because affordances are associated with links, Spring HATEOAS provides an API to attach as many related methods as needed to a link.
|
||||
Just as you can create links by pointing to Spring MVC controller methods (see <<server.link-builder.webmvc>> for details) you
|
||||
Just as you can create links by pointing to Spring MVC controller methods (see <<server.link-builder.webmvc>> for details) you ...
|
||||
|
||||
The following code shows how to take a *self* link and associate two more affordances:
|
||||
|
||||
.Connecting affordances to `GET /employees/{id}`
|
||||
@@ -136,7 +137,7 @@ include::{code-dir}/EmployeeController.java[tag=get]
|
||||
====
|
||||
|
||||
Using `.andAffordance(afford(...))`, you can use the controller's methods to connect a `PUT` and a `PATCH` operation to a `GET` operation.
|
||||
Imagine that the related methods *afforded* above looking like this:
|
||||
Imagine that the related methods *afforded* above look like this:
|
||||
|
||||
.`updateEmpoyee` method that responds to `PUT /employees/{id}`
|
||||
====
|
||||
@@ -182,7 +183,7 @@ Please make sure to check the section on affordances in the <<mediatypes>> secti
|
||||
https://tools.ietf.org/html/rfc7239[RFC-7239 forwarding headers] are most commonly used when your application is behind a proxy, behind a load balancer, or in the cloud.
|
||||
The node that actually receives the web request is part of the infrastructure, and _forwards_ the request to your application.
|
||||
|
||||
Your application may be running on `localhost:8080`, but to the outside world, you're expected to be at `reallycoolsite.com` (and on web's standart port 80).
|
||||
Your application may be running on `localhost:8080`, but to the outside world you're expected to be at `reallycoolsite.com` (and on the web's standard port 80).
|
||||
By having the proxy include extra headers (which many already do), Spring HATEOAS can generate links properly as it uses Spring Framework functionality to obtain the base URI of the original request.
|
||||
|
||||
IMPORTANT: Anything that can change the root URI based on external inputs must be properly guarded.
|
||||
@@ -267,11 +268,11 @@ curl -v localhost:8080/employees \
|
||||
[[server.entity-links]]
|
||||
== [[fundamentals.obtaining-links.entity-links]] Using the EntityLinks interface
|
||||
|
||||
IMPORTANT: `EntityLinks` and it's various implementations are NOT currently provided out-of-the-box for Spring WebFlux applications.
|
||||
IMPORTANT: `EntityLinks` and its various implementations are NOT currently provided out-of-the-box for Spring WebFlux applications.
|
||||
The contract defined in the `EntityLinks` SPI was originally aimed at Spring Web MVC and doesn't consider Reactor types.
|
||||
Developing a comparable contract that supports reactive programming is still in progress.
|
||||
|
||||
So far, we have created links by pointing to the web-framework implementations (that is, the Spring MVC controllers) and inspected the mapping.
|
||||
So far, we have created links by pointing to the web framework implementations (that is, the Spring MVC controllers) and inspected the mapping.
|
||||
In many cases, these classes essentially read and write representations backed by a model class.
|
||||
|
||||
The `EntityLinks` interface now exposes an API to look up a `Link` or `LinkBuilder` based on the model types.
|
||||
@@ -297,7 +298,7 @@ If you want to register your own implementation of `EntityLinks`, check out <<se
|
||||
|
||||
Activating entity links functionality causes all the Spring MVC controllers available in the current `ApplicationContext` to be inspected for the `@ExposesResourceFor(…)` annotation.
|
||||
The annotation exposes which model type the controller manages.
|
||||
Beyond that, we assume that you adhere to following the URI mapping setup and conventions:
|
||||
Beyond that, we assume that you adhere to the following URI mapping setup and conventions:
|
||||
|
||||
* A type level `@ExposesResourceFor(…)` declaring which entity type the controller exposes collection and item resources for.
|
||||
* A class level base mapping that represents the collection resource.
|
||||
@@ -326,7 +327,7 @@ class OrderController {
|
||||
<4> An additional controller method to handle a subordinate resource taking a path variable to expose an item resource, i.e. a single `Order`.
|
||||
====
|
||||
|
||||
With this in place, when you enable `EntityLinks` `@EnableHypermediaSupport` in your Spring MVC configuration, you can create links to the controller, as follows:
|
||||
With this in place, when you enable `EntityLinks` `@EnableHypermediaSupport` in your Spring MVC configuration, you can create links to the controller as follows:
|
||||
|
||||
====
|
||||
[source, java]
|
||||
@@ -348,7 +349,7 @@ class PaymentController {
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> Inject `EntityLinks` made available by `@EnableHypermediaSupport` in you configuration.
|
||||
<1> Inject `EntityLinks` made available by `@EnableHypermediaSupport` in your configuration.
|
||||
<2> Use the APIs to build links by using the entity types instead of controller classes.
|
||||
====
|
||||
|
||||
@@ -357,12 +358,12 @@ As you can see, you can refer to resources managing `Order` instances without re
|
||||
[[server.entity-links.api]]
|
||||
=== EntityLinks API in detail
|
||||
|
||||
Fundamentally, `EntityLinks` allows to build ``LinkBuilder``s and `Link` instances to collection and item resources of a entity type.
|
||||
Fundamentally, `EntityLinks` allows to build ``LinkBuilder``s and `Link` instances to collection and item resources of an entity type.
|
||||
Methods starting with `linkFor…` will produce `LinkBuilder` instances for you to extend and augment with additional path segments, parameters, etc.
|
||||
Methods starting with `linkTo` produce fully prepared `Link` instances.
|
||||
|
||||
While for collection resources providing an entity type is sufficient, links to item resources will need an identifier provided.
|
||||
This usually looks like this
|
||||
This usually looks like this:
|
||||
|
||||
.Obtaining a link to an item resource
|
||||
====
|
||||
@@ -389,7 +390,7 @@ entityLinks.linkToItemResource(order, idExtractor); <2>
|
||||
==== TypedEntityLinks
|
||||
|
||||
As controller implementations are often grouped around entity types, you'll very often find yourself using the same extractor function (see <<server.entity-links.api>> for details) all over the controller class.
|
||||
We can centralize the identifier extraction logic even more by obtaining a `TypedEntityLinks` instance providing the extractor once, so that the actually lookups don't have to deal with the extraction anymore at all.
|
||||
We can centralize the identifier extraction logic even more by obtaining a `TypedEntityLinks` instance providing the extractor once, so that the actual lookups don't have to deal with the extraction anymore at all.
|
||||
|
||||
.Using TypedEntityLinks
|
||||
====
|
||||
@@ -414,7 +415,7 @@ class OrderController {
|
||||
----
|
||||
<1> Inject an `EntityLinks` instance.
|
||||
<2> Indicate you're going to look up `Order` instances with a certain identifier extractor function.
|
||||
<3> Lookup item resource links based on a sole `Order` instance.
|
||||
<3> Look up item resource links based on a sole `Order` instance.
|
||||
====
|
||||
|
||||
[[server.entity-links.spi]]
|
||||
|
||||
Reference in New Issue
Block a user