odata Taking only the 1st record from an expanded set of child records? - odata

Is there a way to specify that I only want to return the first record (or last) of a expanded set of child records using odata?
http://myurl/odata/ParenTable?$count=true&$filter=(Id eq 123456)&$expand=ChildTable($orderby=AddedTimeStamp desc;$top=1)
This is what I am attempting but it returns the message
The query specified in the URI is not valid

Your URL convention is compliant to OData v4 for the behaviour you are expecting.
11.2.4.2.1 Expand Options
The set of expanded entities can be further refined through the application of expand options, expressed as a semicolon-separated list of system query options, enclosed in parentheses.
Allowed system query options are $filter, $select, $orderby, $skip, $top, $count, $search, $expand, and $levels.
But there are older versions and proprietary implementations that are known to not support all or in some cases any of these options like filtering or limiting ($skip,$top) expressions within the $expand query option.
.Net implementations do not support $search OOTB, the API author must manually implement the query option.
That specific error is generally an indicator that the path component, not the query is invalid as most OData runtimes will return more descriptive error response when the resource or collection was correctly resolved but the query could not be parsed or executed. In this case I suspect you have anonymized the path, so we can only speculate, for instance there is an obvious potential typo in the documented path,
there is a 't' missing have you tried:
http://myurl/odata/ParentTable?$count=true&$filter=(Id eq 123456)&$expand=ChildTable($orderby=AddedTimeStamp desc;$top=1)
or is the resource pluralised:
http://myurl/odata/ParenTables?$count=true&$filter=(Id eq 123456)&$expand=ChildTable($orderby=AddedTimeStamp desc;$top=1)
http://myurl/odata/ParentTables?$count=true&$filter=(Id eq 123456)&$expand=ChildTable($orderby=AddedTimeStamp desc;$top=1)
You should include an example of the URL that does work, try without the $top and without the $orderby clauses within the expansion clause. We need to eliminate the errors related to a bad path, vs a bad query.
If you do this via Postman, you can then update your question and post the entire response content.
Both the current ASP.Net and ASP.Net Core implementations do support this, if you are the author of the API please include your controller implementation and the version of the framework you are using so we can assist in greater detail.
An Alternative
If your API does not support this, then given that you are limiting to the $top=1 you could invert the request and use the Child collection resource instead:
Assuming that ~/ChildTable is the route to the ChildTable referred to in your example expansion
http://myurl/odata/ChildTable?$filter=ParentTable/Id eq 123456&$orderby=AddedTimeStamp desc&$top=1&$expand=ParentTable

Related

$apply not working in OData v4 Northwind API

While trying to access the above odatav4 link with $apply query it shows an error as
"The query parameter '$apply' begins with a system-reserved '$' character but is not recognized."
but works if (apply) used instead of ("$apply")
https://services.odata.org/V4/Northwind/Northwind.svc/Products/?$apply=groupby((UnitsInStock))&$count=true&$top=1000
service link
I can't find the reason why the $apply is not working, since it was working previously
That service is an older implementation of WCF Services that is only partially compliant with OData v4 query syntax and as such does not support $apply.
but works if (apply) used instead of ("$apply")
You will notice that although there is no error, the query is returning the same results as if you had not included the $apply query option at all.
Your query syntax should work on a properly compliant API though, for instance you can use the TripPin service:
this query itself is not very useful, but it demonstrates the syntax
https://services.odata.org/TripPinRESTierService/People?$apply=groupby((LastName))

Microsoft.OData.Client: is there a way to turn on the URI Literal suffixes for numeric types?

There was a change "3.2.10 Pruned: URI Literal suffixes for numeric types" in OData v4 specification. Now OData.Client for OData v4 sends double literals without these sfuffixes, but we need them for our proejct to work correctly. I can't find a legal way to turn back this OData v3 behaviour, except brancing OData.Client. Does anybody know a way to change this behaviour using the generated T4 client proxies or something?
It can't fallback to old numeric format (with suffix) . You may consider hooking up DataServiceContext's SendingRequest2 event, modify the request URL to meet the server side's expectation.
However, the server side should have numeric value's type information (either in model or in CLR types) just like client has for building the request, so theoretically, suffix is unnecessary.

Using Breeze query not invoking action

I am developing single page application using HotTowel.
My question is that, When I am writing a Breeze query with string parameter whose length is greater than 1600 characters then action is not invoking.
Please let me know the reason.
Thanks in advance.
as stated in:
What is the maximum length of a URL in different browsers?
there is a limit for the length of urls
check parametrized queries as a possible workaround:
How to properly send action parameter along with query in BreezeJs
The answer from #fops is correct. Using .withParameters, you may be able to create some methods on your server that allow you to use some shorthand on the client instead of very large queries.
If your queries are really big, and even .withParameters blows up your URL, you may need to use POST instead of GET.
Breeze doesn't support POST for queries directly, but there's an (unsupported) add-on in Breeze Labs called breeze.ajaxpost.js that will let you use POST for .withParameters queries.

Resolve prefix programmatically, Jena

I have to parse through xml which contain URI links to dbpedia.org. I have to extract rdf triples from those URI based on a given Ontology using Jena library. How do I resolve the Prefix programmatically in Java based on the ontology given.
The given ontology says that triples can be extracted by querying dbpedia.org. For all such triples the corresponding dbpedia resource is available to start writing the query. But the problem is how do I write the query with only its resource available. I have the properties to query. But I don't have the PREFIX for those properties
Although this may not answer the question directly, I had a whole load of URIs, some prefixed some not and I wanted them all unprefixed (i.e. written out in full with their prefixes resolved). Searching Google the most useful thing I came across was this question (first) and the JavaDoc so I thought I'd add my experience to this question to help anyone else who might be searching for the same thing.
Jena's PrefixMap interface (which Model implements) has expandPrefix and qnameFor methods. The expandPrefix method is the one which helped me (qnameFor does the reverse i.e. it applies a prefix from a PrefixMap to a string and returns null if no such mapping can be found).
Hence for any resource, to ensure that you have a fully expanded URI you can do
myRes.getModel().expandPrefix(myRes.getURI());
Hope this helps someone.
Your question is not very clear, so if this answer doesn't address your issue please edit your question to say more clearly what your problem is. However, based on what you've asked, once you've read an RDF file into a Jena model, in XML or any other encoding, the prefixes used are available through the methods in the interface com.hp.hpl.jena.shared.PrefixMapping (see javadoc). A Model object implements that interface. To automatically expand prefix "foo", use the method getNsPrefixURI().
Edit
OK, given your revised question, there's a number of things you can do to turn a simple property name into a property URI that you can use in a SPARQL query:
use the prefix.cc service to look at possible expansions of prefixes and prefix names (e.g. if you are given dbpedia:elevation, you can look it up on prefix.cc (i.e: http://prefix.cc/dbpedia:elevation) to see that one of the possible expansions is http://dbpedia.org/ontology/elevation
issue a SPARQL describe query on the resource URI to see which properties are returned in the RDF description, then match those to the un-prefixed property names you've been given
ask your data provider to give you full property names, or otherwise provide the prefix expansions, in order to save you from having to reverse engineer which properties he or she meant in the first place.
Personally I'd advocate the third option if that's at all possible.

Is a url query parameter valid if it has no value?

Is a url like http://example.com/foo?bar valid?
I'm looking for a link to something official that says one way or the other. A simple yes/no answer or anecdotal evidence won't cut it.
Valid to the URI RFC
Likely acceptable to your server-side framework/code
The URI RFC doesn't mandate a format for the query string. Although it is recognized that the query string will often carry name-value pairs, it is not required to (e.g. it will often contain another URI).
3.4. Query
The query component contains non-hierarchical data that, along with
data in the path component (Section 3.3), serves to identify a
resource within the scope of the URI's scheme and naming authority
(if any). ...
... However, as query components
are often used to carry identifying information in the form of
"key=value" pairs and one frequently used value is a reference to
another URI, ...
HTML establishes that a form submitted via HTTP GET should encode the form values as name-value pairs in the form "?key1=value1&key2=value2..." (properly encoded). Parsing of the query string is up to the server-side code (e.g. Java servlet engine).
You don't identify what server-side framework you use, if any, but it is possible that your server-side framework may assume the query string will always be in name-value pairs and it may choke on a query string that is not in that format (e.g. ?bar). If its your own custom code parsing the query string, you simply have to ensure you handle that query string format. If its a framework, you'll need to consult your documentation or simply test it to see how it is handled.
They're perfectly valid. You could consider them to be the equivalent of the big muscled guy standing silently behind the mob messenger. The guy doesn't have a name and doesn't speak, but his mere presence conveys information.
"The "http" scheme is used to locate network resources via the HTTP protocol. This section defines the scheme-specific syntax and semantics for http URLs." http://www.w3.org/Protocols/rfc2616/rfc2616.html
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
So yes, anything is valid after a question mark. Your server may interpret differently, but anecdotally, you can see some languages treat that as a boolean value which is true if listed.
Yes, it is valid.
If one simply want to check if the parameter exists or not, this is one way to do so.
URI Spec
The only relevant part of the URI spec is to know everything between the first ? and the first # fits the spec's definition of a query. It can include any characters such as [:/.?]. This means that a query string such as ?bar, or ?ten+green+apples is valid.
Find the RFC 3986 here
HTML Spec
isindex is not meaningfully HTML5.
It's provided deprecated for use as the first element in a form only, and submits without a name.
If the entry's name is "isindex", its type is "text", and this is the first entry in the form data set, then append the value to result and skip the rest of the substeps for this entry, moving on to the next entry, if any, or the next step in the overall algorithm otherwise.
The isindex flag is for legacy use only. Forms in conforming HTML documents will not generate payloads that need to be decoded with this flag set.
The last time isindex was supported was HTML3. It's use in HTML5 is to provide easier backwards compatibility.
Support in libraries
Support in libraries for this format of URI varies however some libraries do provide legacy support to ease use of isindex.
Perl URI.pm (special support)
Some libraries like Perl's URI provide methods of parsing these kind of structures
$uri->query_keywords
$uri->query_keywords( $keywords, ... )
$uri->query_keywords( \#keywords )
Sets and returns query components that use the keywords separated by "+" format.
Node.js url (no special support)
As another far more frequent example, node.js takes the normal route and eases parsing as either
A string
or, an object of keys and values (using parseQueryString)
Most other URI-parsing APIs following something similar to this.
PHP parse_url, follows as similar implementation but only returns the string for the query. Parsing into an object of k=>v requires parse_string()
It is valid: see Wikipedia, RFC 1738 (3.3. HTTP), RFC 3986 (3. Syntax Components).
isindex deprecated magic name from HTML5
This deprecated feature allows a form submission to generate such an URL, providing further evidence that it is valid for HTML. E.g.:
<form action="#isindex" class="border" id="isindex" method="get">
<input type="text" name="isindex" value="bar"/>
<button type="submit">Submit</button>
</form>
generates an URL of type:
?bar
Standard: https://www.w3.org/TR/html5/forms.html#naming-form-controls:-the-name-attribute
isindex is however deprecated as mentioned at: https://stackoverflow.com/a/41689431/895245
As all other answers described, it's perfectly valid for checking, specially for boolean kind stuff
Here is a simple function to get the query string by name:
function getParameterByName(name, url) {
if (!url) {
url = window.location.href;
}
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
and now you want to check if the query string you are looking for exists or not, you may do a simple thing like:
var exampleQueryString = (getParameterByName('exampleQueryString') != null);
the exampleQueryString will be false if the function can't find the query string, otherwise will be true.
The correct resource to look for this is RFC6570. Please refer to section 3.2.9 where in examples empty parameter is presented as below.
Example Template Expansion
{&x,y,empty} &x=1024&y=768&empty=

Resources