From 0c7974465874fed75d1a61659343f2fcbdcf10ef Mon Sep 17 00:00:00 2001 From: ZhangKai Date: Mon, 7 Mar 2022 21:31:04 +0800 Subject: [PATCH] #25 spring hateoas --- docs/en/spring-hateoas/spring-hateoas.md | 112 +++++++++++------------ 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/docs/en/spring-hateoas/spring-hateoas.md b/docs/en/spring-hateoas/spring-hateoas.md index 82d028f..f5d0849 100644 --- a/docs/en/spring-hateoas/spring-hateoas.md +++ b/docs/en/spring-hateoas/spring-hateoas.md @@ -1,13 +1,13 @@ # Spring HATEOAS - Reference Documentation -## [](#preface)1. Preface +## 1. Preface -### [](#migrate-to-1.0)1.1. Migrating to Spring HATEOAS 1.0 +### 1.1. Migrating to Spring HATEOAS 1.0 For 1.0 we took the chance to re-evaluate some of the design and package structure choices we had made for the 0.x branch. There had been an incredible amount of feedback on it and the major version bump seemed to be the most natural place to refactor those. -#### [](#migrate-to-1.0.changes)1.1.1. The changes +#### 1.1.1. The changes The biggest changes in package structure were driven by the introduction of a hypermedia type registration API to support additional media types in Spring HATEOAS. This lead to the clear separation of client and server APIs (packages named respectively) as well as media type implementations in the package `mediatype`. @@ -15,7 +15,7 @@ This lead to the clear separation of client and server APIs (packages named resp The easiest way to get your code base upgraded to the new API is by using the [migration script](#migrate-to-1.0.script). Before we jump to that, here are the changes at a quick glance. -##### [](#migrate-to-1.0.changes.representation-models)Representation models +##### Representation models The `ResourceSupport`/`Resource`/`Resources`/`PagedResources` group of classes never really felt appropriately named. After all, these types do not actually manifest resources but rather representation models that can be enriched with hypermedia information and affordances. @@ -45,7 +45,7 @@ Also the name changes have been reflected in the classes contained in `TypeRefer * `VndError` has been moved to the `mediatype.vnderror` package. -#### [](#migrate-to-1.0.script)1.1.2. The migration script +#### 1.1.2. The migration script You can find [a script](https://github.com/spring-projects/spring-hateoas/tree/master/etc) to run from your application root that will update all import statements and static method references to Spring HATEOAS types that moved in our source code repository. Simply download that, run it from your project root. @@ -69,7 +69,7 @@ Note that the script will not necessarily be able to entirely fix all changes, b Now verify the changes made to the files in your favorite Git client and commit as appropriate. In case you find method or type references unmigrated, please open a ticket in out issue tracker. -#### [](#migration.1-0-M3-to-1-0-RC1)1.1.3. Migrating from 1.0 M3 to 1.0 RC1 +#### 1.1.3. Migrating from 1.0 M3 to 1.0 RC1 * `Link.andAffordance(…)` taking Affordance details have been moved to `Affordances`. To manually build up `Affordance` instances now use `Affordances.of(link).afford(…)`. Also note the new `AffordanceBuilder` type exposed from `Affordances` for fluent usage. See [Affordances](#server.affordances) for details. @@ -78,11 +78,11 @@ In case you find method or type references unmigrated, please open a ticket in o * HAL Forms now does not render property attributes if their value adheres to what’s defined as default in the spec. I.e. if previously `required` was explicitly set to `false`, we now just omit the entry for `required`. We also now only force them to be non-required for templates that use `PATCH` as the HTTP method. -## [](#fundamentals)2. Fundamentals +## 2. Fundamentals This section covers the basics of Spring HATEOAS and its fundamental domain abstractions. -### [](#fundamentals.links)2.1. Links +### 2.1. Links The fundamental idea of hypermedia is to enrich the representation of a resource with hypermedia elements. The simplest form of that are links. @@ -121,7 +121,7 @@ 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 [ Building links in Spring MVC](#server.link-builder.webmvc) and [Building links in Spring WebFlux](#server.link-builder.webflux). -### [](#fundamentals.uri-templates)2.2. URI templates +### 2.2. URI templates For a Spring HATEOAS `Link`, the hypertext reference can not only be a URI, but also a URI template according to [RFC-6570](https://tools.ietf.org/html/rfc6570). A URI template contains so-called template variables and allows expansion of these parameters. @@ -158,12 +158,12 @@ UriTemplate template = UriTemplate.of("/{segment}/something") assertThat(template.toString()).isEqualTo("/{segment}/something{?parameter}"); ``` -### [](#fundamentals.link-relations)2.3. Link relations +### 2.3. Link relations To indicate the relationship of the target resource to the current one so-called link relations are used. Spring HATEOAS provides a `LinkRelation` type to easily create `String`-based instances of it. -#### [](#fundamentals.link-relations.iana)2.3.1. IANA link relations +#### 2.3.1. IANA link relations The Internet Assigned Numbers Authority contains a set of [predefined link relations](https://www.iana.org/assignments/link-relations/link-relations.xhtml). They can be referred to via `IanaLinkRelations`. @@ -177,7 +177,7 @@ assertThat(link.getRel()).isEqualTo(LinkRelation.of("next")); assertThat(IanaLinkRelation.isIanaRel(link.getRel())).isTrue(); ``` -### [](#fundamentals.representation-models)2.4. []() Representation models +### Representation models 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. @@ -227,7 +227,7 @@ Example 10. The HAL representation generated for the person representation model } ``` -#### [](#fundamentals.entity-model)2.4.1. Item resource representation model +#### 2.4.1. Item resource representation model For a resource that’s backed by a singular object or concept, a convenience `EntityModel` type exists. Instead of creating a custom model type for each concept, you can just reuse an already existing type and wrap instances of it into the `EntityModel`. @@ -251,9 +251,9 @@ Collection people = Collections.singleton(new Person("Dave", "Matthews") CollectionModel model = CollectionModel.of(people); ``` -## [](#server)3. Server-side support +## 3. Server-side support -### [](#server.link-builder.webmvc)3.1. []() []() Building links in Spring MVC +### Building links in Spring MVC Now we have the domain vocabulary in place, but the main challenge remains: how to create the actual URIs to be wrapped into `Link` instances in a less fragile way. Right now, we would have to duplicate URI strings all over the place. Doing so is brittle and unmaintainable. @@ -309,7 +309,7 @@ headers.setLocation(linkTo(PersonController.class).slash(person).toUri()); return new ResponseEntity(headers, HttpStatus.CREATED); ``` -#### [](#fundamentals.obtaining-links.builder.methods)3.1.1. Building links that point to methods +#### 3.1.1. 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`. @@ -337,11 +337,11 @@ assertThat(link.getHref()).endsWith("/people/2"); * The parameters handed into the methods are generally neglected (except the ones referred to through `@PathVariable`, because they make up the URI). -### [](#server.link-builder.webflux)3.2. Building links in Spring WebFlux +### 3.2. Building links in Spring WebFlux TODO -### [](#server.affordances)3.3. Affordances +### 3.3. Affordances > > @@ -409,7 +409,7 @@ public ResponseEntity partiallyUpdateEmployee( // Pointing to those methods using the `afford(…)` methods will cause Spring HATEOAS to analyze the request body and response types and capture metadata to allow different media type implementations to use that information to translate that into descriptions of the input and outputs. -#### [](#server.affordances.api)3.3.1. Building affordances manually +#### 3.3.1. Building affordances manually While the primary way to register affordances for a link, it might be necessary to build some of them manually. This can be achieved by using the `Affordances` API: @@ -443,7 +443,7 @@ var link = Affordances.of(linkTo(methodInvocation).withSelfRel()) (1) Affordances are backed by media type specific affordance models that translate the general affordance metadata into specific representations. Please make sure to check the section on affordances in the [Media types](#mediatypes) section to find more details about how to control the exposure of that metadata. -### [](#server.link-builder.forwarded-headers)3.4. Forwarded header handling +### 3.4. Forwarded header handling [RFC-7239 forwarding headers](https://tools.ietf.org/html/rfc7239) 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. @@ -526,7 +526,7 @@ Example 20. The corresponding response with the links generated to consider thos } ``` -### [](#server.entity-links)3.5. []() Using the EntityLinks interface +### Using the EntityLinks interface | |`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.| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -549,7 +549,7 @@ This will cause a variety of default implementations of `EntityLinks` being regi The most fundamental one is `ControllerEntityLinks` that inspects SpringMVC controller classes. If you want to register your own implementation of `EntityLinks`, check out [this section](#server.entity-links.spi). -#### [](#server.entity-links.controller)3.5.1. EntityLinks based on Spring MVC controllers +#### 3.5.1. EntityLinks based on Spring MVC controllers 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. @@ -610,7 +610,7 @@ class PaymentController { As you can see, you can refer to resources managing `Order` instances without referring to `OrderController` explicitly. -#### [](#server.entity-links.api)3.5.2. EntityLinks API in detail +#### 3.5.2. EntityLinks API in detail 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. @@ -637,7 +637,7 @@ entityLinks.linkToItemResource(order, idExtractor); (2) |-----|----------------------------------------------------------------------------------------| |**2**| The link lookup using the extractor. | -##### [](#server.entity-links.api.typed)TypedEntityLinks +##### TypedEntityLinks As controller implementations are often grouped around entity types, you’ll very often find yourself using the same extractor function (see [EntityLinks API in detail](#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 actual lookups don’t have to deal with the extraction anymore at all. @@ -668,7 +668,7 @@ class OrderController { |**2**|Indicate you’re going to look up `Order` instances with a certain identifier extractor function.| |**3**| Look up item resource links based on a sole `Order` instance. | -#### [](#server.entity-links.spi)3.5.3. EntityLinks as SPI +#### 3.5.3. EntityLinks as SPI The `EntityLinks` instance created by `@EnableHypermediaSupport` is of type `DelegatingEntityLinks` which will in turn pick up all other `EntityLinks` implementations available as beans in the `ApplicationContext`. It’s registered as primary bean so that it’s always the sole injection candidate when you inject `EntityLinks` in general.`ControllerEntityLinks` is the default implementation that will be included in the setup, but users are free to implement and register their own implementations. @@ -691,7 +691,7 @@ An example for the extensibility of this mechanism is Spring Data REST’s [`Rep At the same time, it even exposes additional lookup methods for other types of resources. If you want to make use of these, simply inject `RepositoryEntityLinks` explicitly. -### [](#server.representation-model-assembler)3.6. []() Representation model assembler +### Representation model assembler As the mapping from an entity to a representation model must be used in multiple places, it makes sense to create a dedicated class responsible for doing so. The conversion contains very custom steps but also a few boilerplate steps: @@ -740,7 +740,7 @@ PersonModel model = assembler.toModel(person); CollectionModel model = assembler.toCollectionModel(people); ``` -### [](#server.processors)3.7. Representation Model Processors +### 3.7. Representation Model Processors Sometimes you need to tweak and adjust hypermedia representations after they have been [assembled](#server.representation-model-assembler). @@ -829,7 +829,7 @@ This example is quite simple, but you can easily: Also, in this example, the `PaymentProcessor` alters the provided `EntityModel`. You also have the power to*replace* it with another object. Just be advised the API requires the return type to equal the input type. -### [](#server.rel-provider)3.8. []() Using the `LinkRelationProvider` API +### Using the `LinkRelationProvider` API When building links, you usually need to determine the relation type to be used for the link. In most cases, the relation type is directly associated with a (domain) type. We encapsulate the detailed algorithm to look up the relation types behind a `LinkRelationProvider` API that lets you determine the relation types for single and collection resources. The algorithm for looking up the relation type follows: @@ -843,16 +843,16 @@ When building links, you usually need to determine the relation type to be used A `LinkRelationProvider` is automatically exposed as a Spring bean when you use `@EnableHypermediaSupport`. You can plug in custom providers by implementing the interface and exposing them as Spring beans in turn. -## [](#mediatypes)4. Media types +## 4. Media types -### [](#mediatypes.hal)4.1. HAL – Hypertext Application Language +### 4.1. HAL – Hypertext Application Language [JSON Hypertext Application Language](https://tools.ietf.org/html/draft-kelly-json-hal-08) 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 HATEOAS. -#### [](#mediatypes.hal.models)4.1.1. Building HAL representation models +#### 4.1.1. Building HAL representation models As of Spring HATEOAS 1.1, we ship a dedicated `HalModelBuilder` that allows to create `RepresentationModel` instances through a HAL-idiomatic API. These are its fundamental assumptions: @@ -960,7 +960,7 @@ will create the following, more explicit representation. } ``` -#### [](#mediatypes.hal.configuration)4.1.2. Configuring link rendering +#### 4.1.2. Configuring link rendering In HAL, the `_links` entry is a JSON object. The property names are [link relations](#fundamentals.link-relations) and each value is either [a link object or an array of link objects](https://tools.ietf.org/html/draft-kelly-json-hal-07#section-4.1.1). @@ -1067,7 +1067,7 @@ public HalConfiguration patternBasedPolicy() { All of these `HalConfiguration` withers can be combined to form one comprehensive policy. Be sure to test your API extensively to avoid surprises. -#### [](#mediatypes.hal.i18n)4.1.3. Link title internationalization +#### 4.1.3. Link title internationalization HAL defines a `title` attribute for its link objects. These titles can be populated by using Spring’s resource bundle abstraction and a resource bundle named `rest-messages` so that clients can use them in their UIs directly. @@ -1101,7 +1101,7 @@ Example 31. A sample HAL document with link titles defined } ``` -#### [](#mediatypes.hal.curie-provider)4.1.4. []() Using the `CurieProvider` API +#### Using the `CurieProvider` API The [Web Linking RFC](https://tools.ietf.org/html/rfc8288#section-2.1) describes registered and extension link relation types. Registered rels are well-known strings registered with the [IANA registry of link relation types](https://www.iana.org/assignments/link-relations/link-relations.xhtml). Extension `rel` URIs can be used by applications that do not wish to register a relation type. Each one is a URI that uniquely identifies the relation type. The `rel` URI can be serialized as a compact URI or [Curie](https://www.w3.org/TR/curie). For example, a curie of `ex:persons` stands for the link relation type `[example.com/rels/persons](https://example.com/rels/persons)` if `ex` is defined as `[example.com/rels/{rel}](https://example.com/rels/{rel})`. If curies are used, the base URI must be present in the response scope. @@ -1147,7 +1147,7 @@ The following example shows how to do so: Since the purpose of the `CurieProvider` API is to allow for automatic curie creation, you can define only one `CurieProvider` bean per application scope. -### [](#mediatypes.hal-forms)4.2. HAL-FORMS +### 4.2. HAL-FORMS [HAL-FORMS](https://rwcbook.github.io/hal-forms/) is designed to add runtime FORM support to the [HAL media type](#mediatypes.hal). @@ -1231,7 +1231,7 @@ Read about the [Affordances API](#server.affordances) to augment your controller As for single-item (`EntityModel`) and aggregate root collections (`CollectionModel`), Spring HATEOAS renders them identically to [HAL documents](#mediatypes.hal). -#### [](#mediatypes.hal-forms.metadata)4.2.1. Defining HAL-FORMS metadata +#### 4.2.1. Defining HAL-FORMS metadata HAL-FORMS allows to describe criterias for each form field. Spring HATEOAS allows to customize those by shaping the model type for the input and output types and using annotations on them. @@ -1259,7 +1259,7 @@ class CustomConfiguration { This setup will cause the HAL-FORMS template properties for representation model properties of type `CreditCardNumber` to declare a `regex` field with value `[0-9]{16}`. -#### [](#mediatypes.hal-forms.i18n)4.2.2. Internationalization of form attributes +#### 4.2.2. Internationalization of form attributes HAL-FORMS contains attributes that are intended for human interpretation, like a template’s title or property prompts. These can be defined and internationalized using Spring’s resource bundle support and the `rest-messages` resource bundle configured by Spring HATEOAS by default. @@ -1335,7 +1335,7 @@ Example 36. A sample HAL-FORMS document with internationalized template titles a } ``` -### [](#mediatypes.http-problem)4.3. HTTP Problem Details +### 4.3. HTTP Problem Details [Problem Details for HTTP APIs](https://tools.ietf.org/html/rfc7807) is a media type to carry machine-readable details of errors in a HTTP response to avoid the need to define new error response formats for HTTP APIs. @@ -1420,7 +1420,7 @@ A sample HTTP Problem Details response } ``` -### [](#mediatypes.collection-json)4.4. Collection+JSON +### 4.4. Collection+JSON [Collection+JSON](http://amundsen.com/media-types/collection/format/) is a JSON spec registered with IANA-approved media type `application/vnd.collection+json`. @@ -1534,7 +1534,7 @@ Spring HATEOAS more specifically will: * Each item-level `links` will contain all other links for each entry from `CollectionModel.content`. -### [](#mediatypes.uber)4.5. UBER - Uniform Basis for Exchanging Representations +### 4.5. UBER - Uniform Basis for Exchanging Representations [UBER](https://rawgit.com/uber-hypermedia/specification/master/uber-hypermedia.html) is an experimental JSON spec @@ -1595,7 +1595,7 @@ This media type is still under development as is the spec itself. Feel free to[o | |**UBER media type** is not associated in any way with **Uber Technologies Inc.**, the ride sharing company.| |---|-----------------------------------------------------------------------------------------------------------| -### [](#mediatypes.alps)4.6. ALPS - Application-Level Profile Semantics +### 4.6. ALPS - Application-Level Profile Semantics [ALPS](https://tools.ietf.org/html/draft-amundsen-richardson-foster-alps-01) is a media type for providing profile-based metadata about another resource. @@ -1705,11 +1705,11 @@ Instead of linking each field "automatically" to a domain object’s fields, you to use Spring Framework’s message bundles and the `MessageSource` interface. This gives you the ability to delegate these values to locale-specific message bundles and even internationalize the metadata. -### [](#mediatypes.community)4.7. Community-based media types +### 4.7. Community-based media types Thanks to the [ability to create your own media type](#mediatypes.custom), there are several community-led efforts to build additional media types. -#### [](#mediatypes.community.json:api)4.7.1. JSON:API +#### 4.7.1. JSON:API * [Specification](https://jsonapi.org) @@ -1749,7 +1749,7 @@ implementation 'com.toedter:spring-hateoas-jsonapi:{see project page for current Visit the project page for more details if you want snapshot releases. -#### [](#mediatypes.community.siren)4.7.2. Siren +#### 4.7.2. Siren * [Specification](https://github.com/kevinswiber/siren) @@ -1780,7 +1780,7 @@ Gradle coordinates implementation 'de.ingogriebsch.hateoas:spring-hateoas-siren:{see project page for current version}' ``` -### [](#mediatypes.custom)4.8. Registering a custom media type +### 4.8. Registering a custom media type Spring HATEOAS allows you to integrate custom media types through an SPI. The building blocks of such an implementation are: @@ -1791,7 +1791,7 @@ The building blocks of such an implementation are: 3. A small bit of infrastructure configuration that will allow Spring HATEOAS to find the custom implementation and pick it up. -#### [](#mediatypes.custom.configuration)4.8.1. Custom media type configuration +#### 4.8.1. Custom media type configuration Custom media type implementations are picked up by Spring HATEOAS by scanning the application context for any implementations of the `HypermediaMappingInformation` interface. Each media type must implement this interface in order to: @@ -1834,7 +1834,7 @@ In case you need further customization of the Jackson `ObjectMapper` (like a cus | |Prior versions of reference documentation has mentioned implementing the `MediaTypeConfigurationProvider` interface and registering it with `spring.factories`.
This is NOT necessary.
This SPI is ONLY used for out-of-the-box media types provided by Spring HATEOAS.
Merely implementing the `HypermediaMappingInformation` interface and registering it as a Spring bean is all that’s needed.| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -#### [](#mediatypes.custom.recommendation)4.8.2. Recommendations +#### 4.8.2. 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. @@ -1844,11 +1844,11 @@ So it’s worth studying the implementations in [the `mediatype` package](https: Note, that the built in media type implementations keep their configuration classes package private, as they’re activated via `@EnableHypermediaSupport`. Custom implementations should probably make those public instead to make sure, users can import those configuration classes from their application packages. -## [](#configuration)5. Configuration +## 5. Configuration This section describes how to configure Spring HATEOAS. -### [](#configuration.at-enable)5.1. Using `@EnableHypermediaSupport` +### 5.1. Using `@EnableHypermediaSupport` 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 [HAL](https://tools.ietf.org/html/draft-kelly-json-hal) as well as a default rendering. Using the annotation triggers the following: @@ -1860,7 +1860,7 @@ To let the `RepresentationModel` subtypes be rendered according to the specifica * It automatically picks up all `RelProvider` implementations in the `ApplicationContext` and bundles them into a `DelegatingRelProvider` that you can autowire. It registers providers to consider `@Relation` on domain types as well as Spring MVC controllers. If the [EVO inflector](https://github.com/atteo/evo-inflector) is on the classpath, collection `rel` values are derived by using the pluralizing algorithm implemented in the library (see [[spis.rel-provider]](#spis.rel-provider)). -#### [](#configuration.at-enable.stacks)5.1.1. Explicitly enabling support for dedicated web stacks +#### 5.1.1. Explicitly enabling support for dedicated web stacks 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. @@ -1873,11 +1873,11 @@ Example 43. Explicitly activating hypermedia support for a particular web stack class MyHypermediaConfiguration { … } ``` -## [](#client)6. Client-side Support +## 6. Client-side Support This section describes Spring HATEOAS’s support for clients. -### [](#client.traverson)6.1. Traverson +### 6.1. Traverson Spring HATEOAS provides an API for client-side service traversal. It is inspired by the [Traverson JavaScript library](https://blog.codecentric.de/en/2013/11/traverson/). The following example shows how to use it: @@ -1947,7 +1947,7 @@ CollectionModel itemResource = traverson.// Instead of fetching a single resource, this one deserializes a collection into `CollectionModel`. -### [](#client.link-discoverer)6.2. Using `LinkDiscoverer` Instances +### 6.2. Using `LinkDiscoverer` Instances When working with hypermedia enabled representations, a common task is to find a link with a particular relation type in it. Spring HATEOAS provides [JSONPath](https://code.google.com/p/json-path)-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. @@ -1962,7 +1962,7 @@ assertThat(link.getRel(), is("foo")); assertThat(link.getHref(), is("/foo/bar")); ``` -### [](#client.web-client)6.3. Configuring WebClient instances +### 6.3. Configuring WebClient instances If you need configure a `WebClient` to speak hypermedia, it’s easy. Get a hold of the `HypermediaWebClientConfigurer` as shown below: @@ -2004,7 +2004,7 @@ WebClientCustomizer hypermediaWebClientCustomizer(HypermediaWebClientConfigurer At this stage, whenever you need a concrete `WebClient`, simply inject `WebClient.Builder` into your code, and use `build()`. The `WebClient` instance will be able to interact using hypermedia. -### [](#client.web-test-client)6.4. Configuring `WebTestClient` Instances +### 6.4. Configuring `WebTestClient` Instances When working with hypermedia-enabled representations, a common task is to run various tests by using `WebTestClient`. @@ -2088,7 +2088,7 @@ Again, you can use similar assertions as the earlier example. There are many other ways to fashion test cases. `WebTestClient` can be bound to controllers, functions, and URLs. This section isn’t meant to show all that. Instead, this gives you some examples to get started. The important thing is that by applying `HypermediaWebTestClientConfigurer`, any instance of `WebTestClient` can be altered to handle hypermedia. -### [](#client.rest-template)6.5. Configuring RestTemplate instances +### 6.5. Configuring RestTemplate instances If you want to create your own copy of `RestTemplate`, configured to speak hypermedia, you can use the `HypermediaRestTemplateConfigurer`: -- GitLab