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

Require "at least one of" attributes #10

Open
lr-conrs opened this issue Feb 27, 2020 · 8 comments
Open

Require "at least one of" attributes #10

lr-conrs opened this issue Feb 27, 2020 · 8 comments
Labels
enhancement New feature or request JiraIssueCreated

Comments

@lr-conrs
Copy link

I will explain my need by way of an example. Let's say you have different prices for something, depending on how it is used. For personal use, it is 4 dollars, and for commercial use, it is 4000.

We would like to capture this in a structure. (Apologies for pseudocode, please let me know if it is unclear)

mediaPrice {
    commercial: int 
    personal: int 
}

One option would be to use the result of #9 and ensure the array has a minimum length. But, we actually lose out on some strictness - what happens if there is more than one commercial price in this array? Good design would require that state to be unrepresentable, which means usage of this solution is a compromise.

Thus, let's put some thought into how we could signal different required constraints.

@liveandrew
Copy link

reslang supports anyof through the union keyword

e.g.
union MediaPrice {
commercial: int
personal: int
}

in swagger this also requires a type field, but reslang adds this automagically

please see the reference manual here & ask me to add bits if they are not covered. docs probably need some work: https://github.com/LiveRamp/reslang/blob/master/docs/reference.md

@liveandrew
Copy link

please reopen if this doesn't meet your requirements or you would propose a different approach

@lr-conrs
Copy link
Author

Please correct me if I'm still misinterpreting, but unions would be a good use-case for if we only wanted one of the two possible members - e.g. our price is either commercial, or personal, but we never have both.

The challenge above is capturing the case where we do indeed want to allow both, but also want to make sure at least one is around.

@lr-conrs lr-conrs reopened this Feb 28, 2020
@liveandrew
Copy link

hmm i guess that's the oneof thing in swagger? do you have a business requirement for this or is this a nice to have thing? can you help out by showing your structure - is it the media price thing?

@liveandrew liveandrew added the enhancement New feature or request label Feb 28, 2020
@lr-conrs
Copy link
Author

Sorry, failed to reply here.

Scenario: We are an API for people to buy Segments through. Thus, every Segment in our system has at least one price.

Data:

price { 
  cost_per_click,
  cost_per_mille,
  tv_price,
  rev_share
}

There are different prices for different uses, just as above in the commercial versus personal example. Some Segments have multiple prices, as they can be used on multiple platforms, for example, on Google, we'd use cost_per_mille, but we're also going to go ahead and target these people on tv platforms, which pay the tv_price.

So, we know we need at least one price. However, we can't use the array approach, as nothing would prevent a segment from having more than one tv_price, which doesn't make any sense.

In order to make as unambigous an API as possible, having this would be great. The cost of not having it is client and server will have to manually validate against this case on top of checking against a schema.

@liveandrew
Copy link

fair enough. i'll add it - or you can help me add it per our discussions on wed.

constraints can help here, but there's no constraint language that can do everything. you'll always need to defensively implement server-side logic to check regardless, and that covers a huge number of use cases. you can't express "cost_per_click" must be greater than "cost_per_mille" unless the "tv_price" is set. well actually you can, but that's basically a full expression language like UML/OCL. and we all know how well that ended up ;-P

@liveandrew
Copy link

as an aside, if the server implements defensively, you don't need to have client side logic. that's my view...

@lr-conrs
Copy link
Author

constraints can help here, but there's no constraint language that can do everything.
Absolutely 😂

My thinking on the schemaside is to constrain as much as possible, but worry mostly about structural ambiguities. Sometimes by being clever with structures, you can eliminate situations you'd otherwise have to validate, similar in ways to solving a problem functionally rather than imperatively, or playing with type algebra. It quickly becomes a rabbit hole, though.

I think of the schema like one would think about grammar in English. The code still has to try and understand the meaning - and it might be gibberish - but it can rely on the structure being sound.

as an aside, if the server implements defensively, you don't need to have client side logic.

Yeah, I mean chances are a client won't bother running every response we give them through a schema checker, but they will likely have code/objects they generate based off it which is where they could get kind of silly. If we're saying one thing, but our structure allows another, it just makes it harder for them to write a robust deserializer.

Of course, if they're in a dynamic language, they probably won't do any of the above, but it's nice to leave the door open for people to be as strict as they can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request JiraIssueCreated
Projects
None yet
Development

No branches or pull requests

3 participants