You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#891 - Overhauled reference documentation on EntityLinks.
Added new paragraphs on EntityLinks, ControllerEntityLinks, TypedEntityLinks and using EntityLinks as SPI.
Polished Javadoc of ControllerEntityLinks and its unit tests.
== [[fundamentals.obtaining-links.entity-links]] Using the `EntityLinks` interface
202
+
== [[fundamentals.obtaining-links.entity-links]] Using the EntityLinks interface
203
203
204
-
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.
204
+
So far, we have created links by pointing to the web-framework implementations (that is, the Spring MVC controllers) and inspected the mapping.
205
+
In many cases, these classes essentially read and write representations backed by a model class.
205
206
206
-
The `EntityLinks` interface now exposes an API to look up a `Link` or `LinkBuilder` based on the model types. The methods essentially return links that point either to the collection resource (such as `/people`) or to a single resource (such as `/people/1`).
207
+
The `EntityLinks` interface now exposes an API to look up a `Link` or `LinkBuilder` based on the model types.
208
+
The methods essentially return links that point either to the collection resource (such as `/people`) or to an item resource (such as `/people/1`).
207
209
The following example shows how to use `EntityLinks`:
208
210
209
211
====
@@ -215,25 +217,46 @@ Link link = links.linkToItemResource(Customer.class, 1L);
215
217
----
216
218
====
217
219
218
-
`EntityLinks` is available for dependency injection by activating either `@EnableHypermediaSupprt` or `@EnableEntityLinks` in your Spring MVC configuration. Activating this 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 follow the URI mapping convention of a class level base mapping and assume that you have controller methods handling an appended `/{id}`. The following example shows an implementation of an `EntityLinks`-capable controller:
220
+
`EntityLinks` is available via dependency injection by activating either `@EnableHypermediaSupprt` or `@EnableEntityLinks` in your Spring MVC configuration.
221
+
This will cause a variety of default implementations of `EntityLinks` being registered.
222
+
The most fundamental one is `ControllerEntityLinks` that inspects SpringMVC and Spring WebFlux controller classes.
223
+
If you want to register your own implementation of `EntityLinks`, check out <<server.entity-links.spi, this section>>.
224
+
225
+
[[server.entity-links.controller]]
226
+
=== EntityLinks based on Spring MVC and WebFlux controllers
227
+
228
+
Activating entity links functionality causes all the Spring MVC and WebFlux controllers available in the current `ApplicationContext` to be inspected for the `@ExposesResourceFor(…)` annotation.
229
+
The annotation exposes which model type the controller manages.
230
+
Beyond that, we assume that you adhere to following the URI mapping setup and conventions:
231
+
232
+
* A type level `@ExposesResourceFor(…)` declaring which entity type the controller exposes collection and item resources for.
233
+
* A class level base mapping that represents the collection resource.
234
+
* An additional method level mapping that extends the mapping to append an identifier as additional path segment.
235
+
236
+
The following example shows an implementation of an `EntityLinks`-capable controller:
<1> The controller indicates it's exposing collection and item resources for the entity `Order`.
254
+
<2> Its collection resource is exposed under `/orders`
255
+
<3> That collection resource can handle `GET` requests. Add more methods for other HTTP methods at your convenience.
256
+
<4> An additional controller method to handle a subordinate resource taking a path variable to expose an item resource, i.e. a single `Order`.
234
257
====
235
258
236
-
The controller exposes that it manages `Order` instances and exposes handler methods that are mapped to our convention. When youy enable `EntityLinks` through `@EnableEntityLinks` in your Spring MVC configuration, you can create links to the controller, as follows:
259
+
With this in place, when youy enable `EntityLinks` through `@EnableEntityLinks` or `@EnableHypermediaSupport` in your Spring MVC configuration, you can create links to the controller, as follows:
237
260
238
261
====
239
262
[source, java]
@@ -243,22 +266,112 @@ class PaymentController {
243
266
244
267
private final EntityLinks entityLinks;
245
268
246
-
PaymentController(EntityLinks entityLinks) {
269
+
PaymentController(EntityLinks entityLinks) { <1>
247
270
this.entityLinks = entityLinks;
248
271
}
249
272
250
273
@PutMapping(…)
251
274
ResponseEntity payment(@PathVariable Long orderId) {
252
275
253
-
Link link = entityLinks.linkToItemResource(Order.class, orderId);
276
+
Link link = entityLinks.linkToItemResource(Order.class, orderId); <2>
254
277
…
255
278
}
256
279
}
257
280
----
281
+
<1> Inject `EntityLinks` made available by `@EnableEntityLinks` or `@EnableHypermediaSupport` in you configuration.
282
+
<2> Use the APIs to build links by using the entity types instead of controller classes.
258
283
====
259
284
260
-
You can then refer to the `Order` instances without referring to the `OrderController`.
285
+
As you can see, you can refer to resources managing `Order` instances without referring to `OrderController` explicitly.
286
+
287
+
[[server.entity-links.api]]
288
+
=== EntityLinks API in detail
289
+
290
+
Fundamentally, `EntityLinks` allows to build ``LinkBuilder``s and `Link` instances to collection and item resources of a entity type.
291
+
Methods starting with `linkFor…` will produce `LinkBuilder` instances for you to extend and augment with additional path segments, parameters, etc.
292
+
Methods starting with `linkTo` produce fully prepared `Link` instances.
293
+
294
+
While for collection resources providing an entity type is sufficient, links to item resources will need an identifier provided.
If you find yourself repeating those method calls the identifier extraction step can be pulled out into a reusable `Function` to be reused throughout different invocations:
<1> The identifier extraction is externalized so that it can be held in a field or constant.
315
+
<2> The link lookup using the extractor.
316
+
====
317
+
318
+
[[server.entity-links.api.typed]]
319
+
==== TypedEntityLinks
320
+
321
+
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.
322
+
We can centralize the identifier extraction logic even more by obtaining a `TypedEntityLinks` instance poviding the extractor once, so that the actually lookups don't have to deal with the extraction anymore at all.
<2> Indicate you're going to look up `Order` instances with a certain identifier extractor function.
347
+
<3> Lookup item resource links based on a sole `Order` instance.
348
+
====
349
+
350
+
[[server.entity-links.spi]]
351
+
=== EntityLinks as SPI
352
+
353
+
The `EntityLinks` instance created by `@EnableEntityLinks` / `@EnableHypermediaSupport` is of type `DelegatingEntityLinks` which will in turn pick up all other `EntityLinks` implementations available as beans in the `ApplicationContext`.
354
+
It's registered as primary bean so that it's always the sole injection candidate when you inject `EntityLinks` in general.
355
+
`ControllerEntityLinks` is the default implementation that will be included in the setup, but users are free to implement and register their own implementations.
356
+
Making those available to the `EntityLinks` instance available for injection is a matter of registering your implementation as Spring bean.
357
+
358
+
.Declaring a custom EntityLinks implementation
359
+
====
360
+
[source, java]
361
+
----
362
+
class CustomEntityLinksConfiguration {
363
+
364
+
@Bean
365
+
MyEntityLinks myEntityLinks(…) {
366
+
return new MyEntityLinks(…);
367
+
}
368
+
}
369
+
----
370
+
====
261
371
372
+
An example for the extensibility of this mechanism is Spring Data REST's https://github.com/spring-projects/spring-data-rest/blob/3a0cba94a2cc8739375ecf24086da2f7c3bbf038/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java[`RepositoryEntityLinks`], which uses the repository mapping information to create links pointing to resources backed by Spring Data repositories.
373
+
At the same time, it even exposes additional lookup methods for other types of resources.
374
+
If you want to make use of these, simply inject `RepositoryEntityLinks` explicitly.
262
375
263
376
[[server.representation-model-assembler]]
264
377
== [[fundamentals.resource-assembler]] Representation model assembler
0 commit comments