Subresource and path variable conflicts in REST? - rest

Is it considered bad practice to design a REST API that may have an ambiguity in the path resolution? For example:
GET /animals/{id} // Returns the animal with the given ID
GET /animals/dogs // Returns all animals of type dog
Ok, that's contrived, because you would actually just do GET /dogs, but hopefully it illustrates what I mean. From a path resolution standpoint, it seems like you wouldn't know whether you were looking for an animal with id="dogs" or just all the dogs
Specifically, I'm interested in whether Jersey would have any trouble resolving this. What if you knew the id to be an integer?

"Specifically, I'm interested in whether Jersey would have any trouble resolving this"
No this would not be a problem. If you look at the JAX-RS spec § 3.7.2, you'll see the algorithm for matching requests to resource methods.
[E is the set of matching methods]...
Sort E using the number of literal characters in each member as the primary key (descending order), the number of capturing groups as a secondary key (descending order) and the number of capturing groups with non-default regular expressions (i.e. not ‘([^ /]+?)’) as the tertiary key (descending order)
So basically it's saying that the number of literal characters is the primary key of which to sort by (note that it is short circuiting; you win the primary, you win). So for example if a request goes to /animals/cat, #Path("/animals/dogs") would obviously not be in the set, so we don't need to worry about it. But if the request is to /animals/dogs, then both methods would be in the set. The set is then sorted by the number of literal characters. Since #Path("/animals/dogs") has more literal characters than #Path("/animals/"), the former wins. The capturing group {id} doesn't count towards literal characters.
"What if you knew the id to be an integer?"
The capture group allows for regex. So you can use #Path("/animals/{id: \\d+}"). Anything not numbers will not pass and lead to a 404, unless of course it is /animals/dogs.

Related

ASN.1 sequence with missing tag/length field

I'm implementing a specification that, as the outermost data type, specifies a sequence
LogMessage ::= SEQUENCE {
version INTEGER (4),
...
}
When encoded, I would expect the messages to always start with 30, but this is not the case. Indeed what I see when I look at the messages is that the inner part of the SEQUENCE is encoded, but the outer definition (30 and length field of payload) is omitted.
I cannot find why this is happening (the ASN.1 looks just "normal"). Is there a special mode in which this behavior can be seen? Of course I can "manually" trucate that leading data, but I would like to build a robust solution and if this is somehow defined in ASN.1, I'm sure my library (pyasn1) would have an option to set it.

Is empty string value generally allowed by the FIX protocol?

When I look at the definition of a String type in the FIX protocol (e.g. here or here), I don't see a minimum length specified. Is it allowed to use empty strings? One online decoder seems to accept an empty string value (see tag 320), an other complains that it's invalid.
The FIX 4.4 specification states the following (emphasis in the original text):
Each message is constructed of a stream of <tag>=<value> fields with a
field delimiter between fields in the stream. Tags are of data type
TagNum. All tags must have a value specified. Optional fields without
values should simply not be specified in the FIX message. A Reject
message is the appropriate response to a tag with no value.
That strongly suggests (but does not unambiguously state) to me that the use of an empty value for a string is invalid. It is unsurprising to me that different FIX implementations might treat this edge case in different ways. So, I think the best approach is to avoid using empty values for strings.
+1 for Ciaran's and Grant's answer/comments. Just want to add something.
I generally suggest to look up things like this in the most current specification since they usually have been refined/reworded/clarified to eliminate unclear or ambiguous statements from older specs.
The answer is on the very page you link to in your question (emphasis mine, search for "Well-formed field"): https://www.fixtrading.org/standards/tagvalue-online/#field-syntax
A well-formed field has the form:
tag=value<SOH>
A field shall be considered malformed if any of the following occurs as a result of encoding:
the tag is empty
the tag delimiter is missing
the value is empty
the value contains an <SOH> character and the datatype of the field is not data or XMLdata
the datatype of the field is data and the field is not immediately preceded by its associated Length field.

Is it legal to repeat the same value in a MULTIPLECHARVALUE or MULTIPLESTRINGVALUE field?

Let's assume a FIX field is of type MULTIPLECHARVALUE or MULTIPLESTRINGVALUE, and the enumerated values defined for the field are A, B, C and D. I know that "A C D" is a legal value for this field, but is it legal for a value to be repeated in the field? For example, is "A C C D" legal? If so, what are its semantics?
I can think of three possibilities:
"A C C D" is an invalid value because C is repeated.
"A C C D" is valid and semantically the same as "A C D". In other words, set semantics are intended.
"A C C D" is valid and has multiset/bag semantics.
Unfortunately, I cannot find any clear definition of the intended semantics of MULTIPLECHARVALUE and MULTIPLESTRINGVALUE in FIX specification documents.
The FIX50SP2 spec does not answer your question, so I can only conclude that any of the three interpretations could be considered valid.
Like so may questions with FIX, the true answer is dependent upon the counterparty you are communicating with.
So my answer is:
if you are client app, ask your counterparty what they want (or check their docs).
if you are the server app, you get to decide. Your docs should tell your clients how to act.
If it helps, the QuickFIX/n engine treats MultipleCharValue/MultipleStringValue fields as strings, and leaves it to the application code to parse out the individual values. Thus, it's easy for a developer to support any of the interpretations, or even different interpretations for different fields. (I suspect the other QuickFIX language implementations are the same.)
The definition of MultipleValueString field is a string field containing one or more space delimited values. I haven't got the official spec, but there are few locations where this definition can be found:
https://www.onixs.biz/fix-dictionary/4.2/index.html#MultipleValueString (I know onixs.biz to be very faithful to the standard specification)
String field (see definition of "String" above) containing one or more space delimited values.
https://aj-sometechnicalitiesoflife.blogspot.com/2010/04/fix-protocol-interview-questions.html
12. What is MultipleValueString data type? [...]
String field containing one or more space delimited values.
This leaves it up to a specific field of this type whether multiples are allowed or not, though I suspect only a few if any would need to have multiples allowed. As far as I can tell, the FIX specification deliberately leaves this open.
E.g. for ExecInst<18> it would be silly to specify the same instruction multiple times. I would also suspect each and every implementation to behave differently (for instance one ignoring duplicates, another balking with an error/rejection).

RESTful query string convention for "value is present"

Say we have a URL like:
http://example.org/resources/?property=1
This will return every resource where the value of property is 1, pretty straightforward. But what if property is nullable, and we want to search for all resources with a non-null query string? I can think of a couple of ideas:
http://example.org/resources/?property
http://example.org/resources/?property=present
But the first one requires treating "" as a special value (and distinguishing it from http://example.org/resources/, where property isn't even in the URL -- which isn't necessarily straightforward in some frameworks), and the second requires declaring and documenting that present is a special value, which goes against the general principle that good API URLs ought to be obvious and unsurprising. And what if property is a free-text field that can't have any reserved words? Is there a well-accepted way of doing this?

Can anyone explain the below code please

`where client.name.ToLower().Contains(name.ToLower())
Now it's clearer. It's a (badly done) case insensitive search for the name in the client.name. True if name is contained in client.name. Badly done because using international letters (clearly "international letters" don't exist. I mean letters from a culture different from you own. The classical example is the Turkish culture. Read this: http://www.i18nguy.com/unicode/turkish-i18n.html , the part titled Turkish Has An Important Difference), you can break it. The "right" way to do it is: client.name.IndexOf(name, StringComparison.CurrentCultureIgnoreCase) != -1. Instead of StringComparison.CurrentCultureIgnoreCase you can use StringComparison.InvariantCultureIgnoreCase. If you have to use tricks like the ToLower, it has been suggested that it's better to ToUpper both sides of the comparison (but it's MUCH better to use StringComparison.*)
Looks like LINQ to me.
I'm not really up-to-date on .NET these days, but I'd read that as looking for client objects whose name property is a case-insensitive match with the ToString property of the client variable, while allowing additional characters before or after, much like WHERE foo is like '%:some_value%' in SQL. If I'm right, btw, client is a terrible variable name in this instance.
This is a strange piece of code. It would be good to know a bit more about the client object. Essentially it is checking if the case insensitive name value on the client object contains the case insensitive value of the client object (as a string). So if the client name contains the string name of the class itself essentially.
.ToLower() returns the same string you call it on in all lowercase letters. Basically, this statement returns true if name.ToLower() is embedded anywhere within client.name.ToLower().
//If:<br/>
client.name = "nick, bob, jason";
name = "nick";
//Then:<br/>
client.name.ToLower().Contains(name.ToLower());
//would return true