Skip to content

added regex, quoting #638

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

Merged
merged 2 commits into from
Apr 14, 2016
Merged

added regex, quoting #638

merged 2 commits into from
Apr 14, 2016

Conversation

fehguy
Copy link
Contributor

@fehguy fehguy commented Apr 8, 2016

Fixes #516

@IvanGoncharov
Copy link
Contributor

@fehguy It hard to represent RegExp in UI. It very common situation when you present developer with list of possible errors.
I think using RegExp is overkill and why not use X as placeholder for any digit. Soo it would be like 2XX or 4XX or even XXX for all errors.
And it's very easy to convert it into RegExp to do matching:

var regExp = new RegExp('^' + responsesCode.replace(/X/, '\d') + '$');

@fehguy
Copy link
Contributor Author

fehguy commented Apr 8, 2016

I agree, but that's a tooling concern. The spec, however, I feel is best suited by this flexibility. How else would you say "anything other than a 200" should map here?

@IvanGoncharov
Copy link
Contributor

How else would you say "anything other than a 200" should map here?

@fehguy very simple, define 200 and XXX.

@fehguy
Copy link
Contributor Author

fehguy commented Apr 8, 2016

but then it's not simple, it's no longer a "match" statement. It's an "if/else".

@IvanGoncharov
Copy link
Contributor

@fehguy RegExp is very tricky to do right.
For example in your example you use ^2[\d]{2} because you don't put $ at the end, it will also match 2000.

@IvanGoncharov
Copy link
Contributor

but then it's not simple, it's no longer a "match" statement. It's an "if/else".

@fehguy It's what I would normally expect. Try to write to write regex for not 200 in this case.
It would be something really ugly.

@IvanGoncharov
Copy link
Contributor

@fehguy Moreover during SDK generation you need to generate exception classes with some unique names what string you would use for this purpose?
Next problem: to return proper structure/object I need to do RegExp matching directly in SDK code.
I don't think it's possible for languages without RegExp support in standard lib.

It also impossible to validate if the user supplied two RegExp that overlaps.
So it's up to an implementation to choose which RegExp to try first.

It's all tooling issues but as I showed above it's UI, code-generation and validation.

This is easy to resolve in if/else scenario when X allowed only in the end of a string.
That mean XXX, 2XX, 20X is valid but X00 isn't.
In that case, no ambiguity is possible since patterns will never overlap.
And it's easy and fast to implement in any SDK for example 2XX became:
if (code >= 200 && code < 300) {

@fehguy
Copy link
Contributor Author

fehguy commented Apr 8, 2016

@IvanGoncharov we have regexes in the spec, and there's no escaping that. Pattern Properties are, in fact, part of JSON schema. Do you recommend we get rid of those?

@IvanGoncharov
Copy link
Contributor

@fehguy Do you mean patternProperties from JSON Schema?
Or pattern property?

If last one, pattern used only for validation and don't affect data representation.
So, clients/SDK could completely ignore it without any consequences.
So it's nice to validate request before sending but not mandatory.

In any case, I understand that there are no other ways to validate arbitrary string except RexExp.
But HTTP code is always 3 digits and that's all. And in the majority of the cases, people care only about 2XX, 4XX and 5XX. I don't understand why we need to pay a high price in tooling for future flexibility without any particular user scenario.

Moreover 2XX is commonly used for describing APIs and anyone can understand this notation.
If some tool prefers to use regexes for matching it's only one additional line of code as I showed above.

@ePaul
Copy link
Contributor

ePaul commented Apr 8, 2016

Independent of the syntax (regex vs. x), I guess we need some fallback logic here allowing an exact match to override an regex match, allowing 200 to match 200 and \d{3} to match the rest.

The "everything else than 200" otherwise becomes e.g. ([^2]\d{2})|2[^0]\d|20[^0]. (While regular expressions are closed under complements, the closure is not "nice".)

@IvanGoncharov
Copy link
Contributor

@ePaul with x rule could be very simple, just sort all codes(with all digit preceding x) and the first match will be most specialised one.
So priority order would be like that 200 => 20X => 2XX => XXX.
Without such rule, you would have the same conflict between more and less specialized RegExps.

([^2]\d{2})|2[^0]\d|20[^0]

You forget anchors so it should be ^(([^2]\d{2})|2[^0]\d|20[^0])$ 😜

@darrelmiller
Copy link
Member

Because of the way that RFC 7231 defines how status codes should be handled I would be in favor of supporting 2XX, 3XX, 4XX, 5XX as explicit values in addition to regular 3 digit values. I don't see any practical value to patterns like 20X or more flexible regex patterns as there is no logical grouping of status codes beyond the first digit.

@ePaul
Copy link
Contributor

ePaul commented Apr 9, 2016

@IvanGoncharov as we are matching only HTTP status codes (i.e. 3-digit strings), no anchoring is necessary. (Yes, my regex matches many other non-status code strings too, but that doesn't matter.)

@IvanGoncharov
Copy link
Contributor

@darrelmiller Your solution is solving the absolute majority of use cases and also super simple to implement. And it's very easy to validate using JSON Schema, so no problems with confused users.

@webron
Copy link
Member

webron commented Apr 11, 2016

Agreeing with @darrelmiller and the rest. Seems simpler, and actually covers the use case in the original issue.

I don't really see anyone wanted to capture a different range, as the status codes don't have a logical grouping, afaik, other than the hundred-level grouping.

What we may want to consider is allowing for grouping in the key with comma-separated values, so "401,404,5XX" can all be attributed to a single definition. That would be more difficult to parse (or define in the JSON Schema), potentially.

@fehguy
Copy link
Contributor Author

fehguy commented Apr 11, 2016

Updated to replace regex with a X as wildcard. That means this:

2XX, 20X, XXX are all legal. In addition, XXX and default are functionally equivalent.

@fehguy
Copy link
Contributor Author

fehguy commented Apr 11, 2016

@OAI/tdc please approve or reject

@webron
Copy link
Member

webron commented Apr 12, 2016

👍

I'd suggest we drop default then and replace it with XXX. Easy migration.

@DavidBiesack
Copy link
Contributor

👍 but allow x as well as X - For example, I find 2xx more readable than 2XX

@ePaul
Copy link
Contributor

ePaul commented Apr 12, 2016

I would even go as far as allowing only the lowercase version (2xx).

@IvanGoncharov
Copy link
Contributor

I think having aliases is bad practice and should be used only for backward compatibility.
I am totally ok with 2xx and xxx instead of 2XX and default.
But it should be only one set of names.

I also think this feature should be limited to practical set.
At the time of my initial proposal, I was trying to produce an alternative for RegExp.
But now, I totally agree with @darrelmiller:

Because of the way that RFC 7231 defines how status codes should be handled I would be in favor of supporting 2XX, 3XX, 4XX, 5XX as explicit values in addition to regular 3 digit values. I don't see any practical value to patterns like 20X or more flexible regex patterns as there is no logical grouping of status codes beyond the first digit.

So 2xx, 3xx, 4xx, 5xx and xxx should be defined as fixed fields. Because current wording allows for something like 5x1.

@ePaul
Copy link
Contributor

ePaul commented Apr 12, 2016

Just to make sure ... there is no point in documenting an 1xx response, right? These are only intermediate responses on protocol level, which will be followed by a "real" one, or protocol switching stuff (not HTTP anymore). (So the fixed set proposed by @IvanGoncharov, in addition to the numeric ones, would be enough.)

@darrelmiller
Copy link
Member

@ePaul In theory it might be useful to document the 100 status code. Knowing if a server supports the Expect: 100 Continue dance and what is the maximum payload size allowed could be useful.

Regarding the letter casing, as I understand it, most of the OpenAPI properties are case sensitive, so it would seem prudent to keep this convention. Also, most of OpenAPI tends towards lower case letters and RFC 7231 uses 1xx, 2xx,3xx, etc so that would seem like the obvious choice.

@jharmn
Copy link
Contributor

jharmn commented Apr 13, 2016

@fehguy Some potential ambiguity:

  • Would 40x mean "between 400 and 409"?
  • Shouldn't we make it clear that XXX is an effective replacement for default?
  • Are x and X equivalent? i.e. is it case sensitive? (FWIW I think both should work)

@fehguy
Copy link
Contributor Author

fehguy commented Apr 14, 2016

thanks for the feedback--i suggest that we go with ^\d(\d|x){2}$. We support the lower-case x and stick with default. Frankly xxx looks like something that doesn't belong in a spec, and default is used in other places (that can change).

If there are strong objections to this, let's reopen the issue again.

@fehguy fehguy merged commit c86e43b into OpenAPI.next Apr 14, 2016
@earth2marsh
Copy link
Member

👍

@ePaul
Copy link
Contributor

ePaul commented Apr 14, 2016

@fehguy What you've just merged is not actually what you've proposed in the last comment.

@fehguy
Copy link
Contributor Author

fehguy commented Apr 14, 2016

@ePaul i'm saying that's the rule. We are not supporting regex. I've just explained the idea in a regex. And as I said, we can reopen if we have an issue.

So:

1xx <= 101, 112, etc
10x <= 101, 102, etc
100 === 100
xxx is not allowed
default _is_ allowed

@darrelmiller
Copy link
Member

@fehguy Any chance you would consider this regex ^\d(\d\d|xx)$ as the rule? I can't think of any scenario where grouping by the last digit makes sense.

@DavidBiesack
Copy link
Contributor

The commit uses uppercase X, not lowercase x which I think had the consensus above.

... may contain the uppercase character, X to designate a wildcard, such as 2XX to represent all response codes between [200-299].

This language also allows 5X1 or X01 which as noted above seems too flexible. ^\d(\d\d|xx)$ is also too broad as it would allow 001 or 9xx.

^(default|[12345](\d\d|xx))$ is probably the sweet spot.

There is also the suggestion to allow comma-separated list, such as 4xx,5xx, that is also not captured by the commit.

@fehguy
Copy link
Contributor Author

fehguy commented Apr 14, 2016

I will fix the upper-case, i did in the sample regex but not the doc. I don't agree with the comma-separated list so I didn't add that. Will make sure docs are updated.

@fehguy
Copy link
Contributor Author

fehguy commented Apr 15, 2016

this needs to be updated to lower case, skipping the change for xxx for now.

@fehguy fehguy deleted the issue-516 branch October 20, 2016 17:12
handrews added a commit to handrews/OpenAPI-Specification that referenced this pull request Oct 11, 2024
added regex, quoting

[Manually poted merge]

Co-authored-by: Tony Tam <[email protected]>
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

Successfully merging this pull request may close these issues.

8 participants