Spring HATEOAS & HAL: Change array name in _embedded
Asked Answered
W

1

13

I'm trying to build a HAL-compliant REST API with Spring HATEOAS.

After some fiddling I managed to get to work mostly like expected. The (sample) output looks like this right now:

{
    "_links": {
        "self": {
            "href": "http://localhost:8080/sybil/configuration/bricks"
        }
    },
    "_embedded": {
        "brickDomainList": [
            {
                "hostname": "localhost",
                "port": 4223,
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/sybil/configuration/bricks/localhost"
                    }
                }
            },
            {
                "hostname": "synerforge001",
                "port": 4223,
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/sybil/configuration/bricks/synerforge001"
                    }
                }
            }
        ]
    }
}

I don't like the "brickDomainList" array's name. It should say "bricks", ideally. How can I change it?

Here's the controller that produces the output:

@RestController
@RequestMapping("/configuration/bricks")
public class ConfigurationBricksController {

    private BrickRepository brickRepository;
    private GraphDatabaseService graphDatabaseService;

    @Autowired
    public ConfigurationBricksController(BrickRepository brickRepository, GraphDatabaseService graphDatabaseService) {

        this.brickRepository = brickRepository;
        this.graphDatabaseService = graphDatabaseService;
    }

    @ResponseBody
    @RequestMapping(method = RequestMethod.GET, produces = "application/hal+json")
    public Resources<BrickResource> bricks() {

        List<BrickDomain> bricks;
        List<BrickResource> resources = new ArrayList<>();
        List<Link> links = new ArrayList<>();

        Link self = linkTo(ConfigurationBricksController.class).withSelfRel();
        links.add(self);

        try(Transaction tx = graphDatabaseService.beginTx()) { // begin transaction

            // get all Bricks from database and cast them into a list so that they're actually fetched
            bricks = new ArrayList<>(IteratorUtil.asCollection(brickRepository.findAll()));

            // end transaction
            tx.success();
        }

        for (BrickDomain brick : bricks) {
            self = linkTo(methodOn(ConfigurationBricksController.class).brick(brick.getHostname())).withSelfRel();

            BrickResource resource = new BrickResource(brick, self);

            resources.add(resource);
        }

        return new Resources<>(resources, links);
    }
}

Is there some Annotation or something I can add to change the array's name?

If you want/need to look at the BrickResource class or the Repositories or something look here: https://github.com/ttheuer/sybil/tree/mvctest/src/main/java/org/synyx/sybil

The BrickResource is in api/resources/, the repository is in database/, and the BrickDomain in domain/.

Thanks!

Westerman answered 3/3, 2015 at 14:49 Comment(0)
B
29

Just use Evo Inflector. If you have a Maven project then add the dependency

<dependency>
  <groupId>org.atteo</groupId>
  <artifactId>evo-inflector</artifactId>
  <version>1.2</version>
</dependency>

Or you can add @Relation(collectionRelation = "bricks") to the BrickDomain class

@Relation(collectionRelation = "bricks")
public class BrickDomain { … }
Billibilliard answered 4/3, 2015 at 11:46 Comment(3)
Excellent, thank you very much, the @Relation annotation is what I was looking for :) I'd upvote your answer, but I don't have enough reputation yet, sorry :(Westerman
Tobold: Upvoted for you. jose_p: you might wanna mention RelProvider provider interface, too. It allows to externalize the calculation of rels in case annotating a domain object with @Relation is not possible or wanted.Plastered
Nah. Put the dependency in my .pom and in the @SpringBootApplication even injected the EvoReflectorBean... nothing happened. Is there some annotation missing??? Find it very frustrating to always see domainClassResource:[...]Onanism

© 2022 - 2024 — McMap. All rights reserved.