Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OOP approach to resource #25

Open
luvarqpp opened this issue Jun 21, 2019 · 5 comments
Open

OOP approach to resource #25

luvarqpp opened this issue Jun 21, 2019 · 5 comments

Comments

@luvarqpp
Copy link

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.

@gregturn
Copy link
Contributor

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

@luvarqpp
Copy link
Author

luvarqpp commented Apr 14, 2020

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?

@gregturn
Copy link
Contributor

gregturn commented Apr 17, 2020

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.

@luvarqpp
Copy link
Author

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.

@gregturn
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants