Skip to content

Allow to define HAL FORMS options based on the representation model's state #1695

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

Open
Ickbinet opened this issue Oct 22, 2021 · 5 comments
Open

Comments

@Ickbinet
Copy link

At the moment options can only be added via HalFormsConfiguration for certain input classes' properties.
It would be more flexible when PropertyMetadata would support it too, because there are use cases where a class and property based approach is not sufficient:

  • Dependent on a certain state only a subset of options are allowed: order amount > 1000 $ -> shipping only via UPS, not via FedEx
  • List/Array types: property or Parameter of type List
@odrotbohm
Copy link
Member

There are two challenges to that:

  1. Options are a HAL FORMS specific concept. Affordances don't know about that and unfortunately can't as we cannot expect every hypermedia type to support that concept, especially all details around the way HAL FORMS models them.
  2. The HalFormsOptions creation currently doesn't see the RepresentationModel – i.e. the state of the resource – at all. This is primarily driven by the idea that affordances are subject to a different lifecycle and everything state-specific would rather end up in the definition which affordance is added to the model in the first place.

I can see that the second point is a limitation and that we should improve on that. That said, I wonder what kind of API you'd like to see to apply representation model-specific rules to the options? We could allow users to post-process the statically computed options, but that would require us to expose API to inspect the inline and remote options. Also, we'd have to make the API work based on RepresentationModel but that doesn't even know about any kind of payload. So, to be explicit about the actual type (model + payload) you're interested in, we need to expose API to capture that, which usually doesn't look very elegant but yeah.

@Ickbinet
Copy link
Author

Ickbinet commented Nov 1, 2021

OK, understood.

But why every media type has to support every affordance property? Other types than HAL-FORMS could easily ignore this property? Maybe it is already the case? I do not know how UBER oder CollectionJson, which are currently supported, handle all these possible attributes on PropertyMetadata.

But maybe I am to focused on HAL-FORMS because this is the only type I am working with.

@odrotbohm
Copy link
Member

It doesn't have to. But we can't simply add everything we see in HAL FORMS to the general affordance abstraction, as that would just create a kitchen sink of everything that every hypermedia type in the world would expose. That doesn't lead to usable APIs (in terms of Spring HATEOAS APIs) and – even more problematic – is not resulting in software reasonably maintainable.

But maybe I am to focused on HAL-FORMS because this is the only type I am working with.

That seems to be the case indeed. Rest assured that quite a lot of thinking went into the current arrangement to carefully balance the need of individual media types and finding decent abstractions for the source metadata. It might be worth studying the package arrangement to realize that everything specific to hypermedia types is located in the individual sub-packages of mediatypes. All of them are usually implemented by registering an AffordanceModelFactory from a ConfiguredAffordance. Media type-specific serializers for RepresentationModel then access the AffordanceModel and prepare the actual DTOs to be rendered by Jackson according to the media type-specification. That has worked quite well so far for a variety of media types.

In 2, we have identified a fundamental limitation of the design of the HAL FORMS options implementation, which we can definitely work on to get resolved. Let's stick with that for this ticket. Any kind of input for the API design challenges appreciated.

@odrotbohm odrotbohm changed the title Add options attribute to AffordanceModel.PropertyMetadata Allow to define HAL FORMS options based on the representation model's state Nov 1, 2021
@Ickbinet
Copy link
Author

Ickbinet commented Nov 3, 2021

Now it is like this:
org.springframework.hateoas.mediatype.hal.forms.HalFormsPropertyFactory.createProperties(HalFormsAffordanceModel model)

Could be:
org.springframework.hateoas.mediatype.hal.forms.HalFormsPropertyFactory.createProperties(HalFormsAffordanceModel model, RepresentationModel<?> resource)

Then the HalFormsOptionsFactory could offer a new withOptions method which accepts also the resource as a parameter and a HalFormsOptions creator could use the resource state to create the options.

@reda-alaoui
Copy link
Contributor

@odrotbohm ,

Could we, as a first step, provide the affordance link to HalFormsOptionsFactory#getOptions? That would unlock some dynamic cases where a PathVariable constrains the allowed options.

Maybe it could be an additional argument to this call?

HalFormsOptions options = optionsFactory.getOptions(payload, metadata);

Or maybe it could be added to InputPayloadMetadata ?

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

3 participants