移除REST资源集合中的_embedded及REST端点链接规范咨询
Great questions! Let's break this down step by step based on HAL specifications and Spring HATEOAS behavior:
1. Removing the
_embedded Tag & HAL Compliance - First, why is
_embeddedpresent? This is a core requirement of the HAL (Hypertext Application Language) specification. HAL uses_embeddedto wrap collection items, clearly separating the resource's core data from metadata like links (stored in_links). Your current response is fully compliant with HAL standards. - Can you remove it? Yes—but doing so means your response will no longer be valid HAL. If your client doesn't rely on HAL's structure (e.g., it's a custom client you control), you can adjust your controller to return a plain list of resources instead of wrapping them in
Resources<>.
Here's how to modify your controller to skip the _embedded wrapper:
@GetMapping public ResponseEntity<List<Resource<CharacterDescription>>> getAllCharacterDescriptions() { List<Resource<CharacterDescription>> characters = repository.findAll() .stream() .map(character -> { Link characterLink = linkTo(methodOn(CharacterDescriptionController.class) .getCharacterDescription(character.getCharacterId())) .withSelfRel(); return new Resource<>(character, characterLink); }) .collect(Collectors.toList()); // Note: This returns a plain array without top-level _links.self // If you still need the top-level self link, create a custom DTO to hold both the list and link return ResponseEntity.ok(characters); }
This will output a direct JSON array of character resources, but keep in mind: HAL-aware clients will fail to parse this correctly, as it deviates from the standard.
2. Links for Single Resource Endpoints (
/characters/1) - Self link is mandatory per HAL: Every resource (single or collection) must include a
selflink pointing to its own URL. Your current single-resource responses already do this, which is correct. - Parent link to
/charactersis optional: HAL doesn't require this, but it's a common practice to improve API discoverability. Adding it lets clients easily navigate back to the full collection if needed.
Here's an example of adding a parent link to your single-resource endpoint:
@GetMapping("/{id}") public ResponseEntity<Resource<CharacterDescription>> getCharacterDescription(@PathVariable Long id) { CharacterDescription character = repository.findById(id) .orElseThrow(() -> new NotFoundException("Character not found")); Link selfLink = linkTo(methodOn(CharacterDescriptionController.class) .getCharacterDescription(id)) .withSelfRel(); // Add a link to the parent collection Link collectionLink = linkTo(methodOn(CharacterDescriptionController.class) .getAllCharacterDescriptions()) .withRel("characters"); // Use a consistent rel name (e.g., "collection" or "parent" also work) Resource<CharacterDescription> resource = new Resource<>(character, selfLink, collectionLink); return ResponseEntity.ok(resource); }
If you don't need this navigability, omitting the parent link is still fully compliant with HAL.
内容的提问来源于stack exchange,提问作者LiamRyan
相关产品推荐
相关产品推荐

