spring-hateoas-examples icon indicating copy to clipboard operation
spring-hateoas-examples copied to clipboard

OOP approach to resource

Open luvarqpp opened this issue 5 years ago • 5 comments

I would like to see some example, where I can use HATEOAS approach for creating rest api services on some real objects. Is this approach good way?

I mean something like this:

@Data
public class Invoice {
  // ... some fields/attributes and other things
  public Receipt claimPaid(PaymentInfo paymentInfo) {
    // ....
  }

  public boolean isCancellable() {
    // .... Return if invoice can be canceled (from business point of view) 
  }
  
  public void cancel() {
    // .... Actually cancel invoice and possibly delete it
  }
}

I would like to see relations in rest api resource for "claimPaid" method (always) and for "cancel" method, if applicable.

Is hateoas usable (without much coding) in a such way?

I know that using spring-data there is extremely easy to have HAL working on entities (no controller class is needed for example. Just entity and "empty" repository interface with RepositoryRestResource annotation).

Please provide some "real life" example in repository, or at least some info how we should use it in such application.

luvarqpp avatar Jun 21 '19 16:06 luvarqpp

Are you talking about a more ActiveRecord-based approach, and building links to the actions in the domain object?

gregturn avatar Apr 13 '20 15:04 gregturn

I am not deeply familiar with ActiveRecord. I would like to have my entity objects truly be objects with business logic and data at one place. I try to avoid anemic model here.

Some use-cases:

  1. Currently I can make reference from entity Invoice to Receipt ant it will be rendered always as link (when I have ReceiptRepository interface). It is nice in default cases, but what if I would like to include this relation based on some business logic? Like in my isCancelable() and cancel() case?
  2. Perhaps (going further), if there is no Receipt associated with some Invoice, I would not like to render receipt relation at all. It is association endpoint and it would return 404 (nothing associated). As user is prohibited to associate any Receipt resource by posting to given endpoint (it is done by server upon invoice being paid), I would like to not send user just confusing associate link in case there is nothing associated.

Generally I would like to know mechanism of including relations of two types (associative endpoints and "action" endpoint) based upon entity state. In case of action endpoint, I know that using RepresentationModelProcessor<EntityModel<Invoice>> bean, this is possible and easy. But how about inclusion of relations with associative endpoints?

luvarqpp avatar Apr 14 '20 06:04 luvarqpp

ActiveRecord was a pattern where a domain object can save itself to the database. The concept is that who should know better than the object?

You’d see more of this on Rails type stuff.

To use Spring Data, it would mean injecting a repository into every domain object.

As for lining that up with the relevant controller, things get even more confusing.

Spring HATEOAS is built on the idea of turning Spring controller web endpoints into links as part of the domain object JSON you serve users from the controllers. The idea being, if you can build backward compatible links you can reduce the friction as your API evolves.

Having one controller reference another gets really tangled which is why using a RepresentstionModelProcessor provides a nice, last stop to adding necessary links before serialization occurs.

And to be clear, most of these examples are pure Spring HATEOAS, no Spring Data REST. Spring Data REST comes with a different set of assumptions.

gregturn avatar Apr 17 '20 00:04 gregturn

I try to distillate my question post to easier one. Is it possible to remove relations using business logic according state of the object? I mean remove relation to other referenced resource.

I have tried to do it in RepresentstionModelProcessor and (If I remember correctly), given relations was ther, but removing them from list of relations had no effect, as given list was just copy passed to method and actual list was not exposed outside of HATEOAS library.

luvarqpp avatar Apr 17 '20 09:04 luvarqpp

I need to check because you should be able to replace the entire list of links if desired.

gregturn avatar Apr 17 '20 12:04 gregturn