Target url placeholders missing after upgrading from spring-hateoas 1.3.5 to 2.1.2

46 views Asked by At

Background

We are currently upgrading our spring boot application from spring boot 2.7.10 -> 3.1.5. This pulls in a newer version of spring-hateoas which we'd like to move too as well (1.3.5 -> 2.1.2).

Problem

We noticed that a bunch of our unit tests have broken as a result because the way hal-forms affordances are now rendered. In short, the output no longer includes the request parameter placeholders that used to appear in curly brackets ({placeholder}).

Here are the relevant snippets. More complete example below.

Previous output

    "moveItemsToStartOfList": {
      "method": "POST",
      "properties": [],
      "target": "<snip>/items/:moveItemsToStartOfList?ids={ids}"
    },

New output

The difference can be seen at the end of the target uri.

    "moveItemsToStartOfList": {
      "method": "POST",
      "properties": [],
      "target": "<snip>/items/:moveItemsToStartOfList?ids="
    },

Code

RestController method signature

@PostMapping("/:moveItemsToStartOfList")
public ResponseEntity<?> moveItemsToStartOfList(
        @NotNull @PathVariable UUID userId,
        @NotNull @PathVariable UUID shoppingListId,
        @NotNull @RequestParam List<UUID> ids
) {

Assembler that creates the affordance

selfLink
    .andAffordance(
            afford(
                    methodOn(getControllerClass())
                            .createShoppingListItem(
                                siteUserId,
                                shoppingListId,
                                null <-- this used to be emitted with a placeholder
    )))

Questions

Q1) Is this an intentional change or a regression error?

Q2) As far as I can tell the code that is responsible for this change is in HalFormsTemplateBuilder where it now 'expands' the Link like this

String target = it.getLink().expand().getHref();

The older code used to do just

String target = it.getLink().getHref();

I think the expand is intended to populate template variables with values and at the moment when it doesn't find one it just outputs "" for that variable. I think it might be related to the type of the TemplateVariable in question. When I debug this stuff the TemplateVariable in question has a type of VariableType.SIMPLE when it seems like it should be a VariableType.REQUEST_PARAM. Is this the right track for investigating this more?

Sample output

{
  "_embedded": {
    "items": [
    ...
    ]
  },
  "_links": {
    "self": {
      "href": "http://localhost/community/users/e933d876-da9a-44ad-b3db-82c03c2e5677/shopping-lists/b0fdc0c7-7b86-41b2-bb32-26e7b63ca0f4/items?productId=b59e1721-69d0-4b5d-8fec-dc854adcbd1d"
    }
  },
  "_templates": {
    ...
    "moveItemsToStartOfList": {
      "method": "POST",
      "properties": [],
      "target": "http://localhost/community/users/e933d876-da9a-44ad-b3db-82c03c2e5677/shopping-lists/b0fdc0c7-7b86-41b2-bb32-26e7b63ca0f4/items/:moveItemsToStartOfList?ids={ids}"
    },
    ...
  },
  "page": {
    "number": 0,
    "size": 1,
    "totalPages": 1,
    "totalElements": 1
  }
}
0

There are 0 answers