Android Notepad Uri Explanation - sql

In the android Notes demo, it accepts the URI:
sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
Where the difference between notes and notes/# is that notes/# returns the note who's ID matches #.
However, the managedQuery() method that is used to get data from the content provider has the following parameters:
Parameters
uri The URI of the content provider to query.
projection List of columns to return.
selection SQL WHERE clause.
selectionArgs The arguments to selection, if any ?s are pesent
sortOrder SQL ORDER BY clause.
So, is there any particular cause for the design decision of providing a URI for that, rather than just using the selection parameter? Or is it just a matter of taste?
Thank you.

I thinks its so you can do more complex lookups without having to complicate your selections and arguments. For example in my project I have multiple tables but use the same selection and arguments. To filter content. By using the URI I don't have interpret the query, I can just switch on the URI. It.might be personal taste to begin with. But in more complex scenarios you appreciate the URI. You can also use * to match strings in the same.way you can with#.

I think it's mostly a matter of taste. IMHO, putting the id in the Uri is a little cleaner since you can make the id opaque rather than require the client to know that it actually represents a specific row id. For instance, you can pass a lookup key (like in the the Contacts API) rather than a specific row id.

Related

REST API design: param value starts with

I need an REST API endpoint which will return all the records having name starting with ABC.
The SQL query would be something like:
SELECT * FROM MyResource WHERE Name LIKE 'ABC%'
But how should I define the query string in the REST endpoint?
Using equal sign in the query string would not be appropriate, I think.
{Base URL}/myresource?name=ABC
Sofar I found following specification that can be used as base for the definition of the query: https://datatracker.ietf.org/doc/html/draft-ietf-scim-api-12#section-3.2.2.2
Equals is fine provided you use correct naming. For this request you can define i.e. 'namePrefix' parameter that is self-descriptive.
But how should I define the query string in the REST endpoint? Using equal sign in the query string would not be appropriate, I think.
Using an equal sign in the query string is fine -- the world wide web has been catastrophically successful, and you'll find query strings with encoded key/value pairs being used for all sorts of things.
There's no particular reason to assume that the spelling of a resource identifier should necessarily match the internal implementation details -- in fact, the opposite is the case: we're supposed to be able to change how a resource is implemented without necessarily needing to introduce a new identifier.
There's a tremendous advantage to using application/x-www-form-urlencoded data as your query string: that's how HTML GET forms do it, which in turn means that pretty much everyone has access to at least one general purpose library that knows how to construct resource identifiers that use that convention.
But if you would rather forego that advantage in favor of some other concern, that's OK too; REST/HTTP don't care what spelling conventions you use for your resource identifiers, so long as the result is consistent with the production rules described in RFC 3986.

What is the correct way of adding parameter to ignore case for search text in a REST API

I have an API endpoint to retrieve all users. There are 3 query parameters for searching/filtering the results as follows.
GET /users?name=test&age=23&area=abc
Now I want to introduce an option to ignore the case when searching for the name parameter. For example, the above API call should return even if the name equals Test or tesT.
What's the correct way of implementing this option? Adding another query parameter or is there any better way of implementing it?
In this specific case, an easier option could be to define the query parameter value as a regex expression, since regex expression itself allows us to define a string to be case insensitive / sensitive.
In other scenarios, another option would be to incorporate the specification (that the value needs to be case insensitive) into the query param value itself, like
http://localhost:3000?name=case_insensitive(test)
I would realize two new parameters for name, namely: nameIgnoreCase and nameCaseSensitive. In this case the user of the endpoint can and must decide. If this is well documented, the user gets an additional hint that this ‚question’ exists at all.
You can also continue to provide name as the default behavior, which will fall back to either nameIgnoreCase or nameCaseSensitive.

Custom, user-definable "wildcard" constants in SQL database search -- possible?

My client is making database searches using a django webapp that I've written. The query sends a regex search to the database and outputs the results.
Because the regex searches can be pretty long and unintuitive, the client has asked for certain custom "wildcards" to be created for the regex searches. For example.
Ω := [^aeiou] (all non-vowels)
etc.
This could be achieved with a simple permanent string substitution in the query, something like
query = query.replace("Ω", "[^aeiou]")
for all the elements in the substitution list. This seems like it should be safe, but I'm not really sure.
He has also asked that it be possible for the user to define custom wildcards for their searches on the fly. So that there would be some other input box where a user could define
∫ := some other regex
And to store them you might create a model
class RegexWildcard(models.Model):
symbol = ...
replacement = ...
I'm personally a bit wary of this, because it does not seem to add a whole lot of functionality, but does seem to add a lot of complexity and potential problems to the code. Clients can now write their queries to a db. Can they overwrite each other's symbols?
That I haven't seen this done anywhere before also makes me kind of wary of the idea.
Is this possible? Desirable? A great idea? A terrible idea? Resources and any guidance appreciated.
Well, you're getting paid by the hour....
I don't see how involving the Greek alphabet is to anyone's advantage. If the queries are stored anywhere, everyone approaching the system would have to learn the new syntax to understand them. Plus, there's the problem of how to type the special symbols.
If the client creates complex regular expressions they'd like to be able to reuse, that's understandable. Your application could maintain a list of such expressions that the user could add to and choose from. Notionally, the user would "click on" an expression, and it would be inserted into the query.
The saved expressions could have user-defined names, to make them easier to remember and refer to. And you could define a syntax that referenced them, something otherwise invalid in SQL, such as ::name. Before submitting the query to the DBMS, you substitute the regex for the name.
You still have the problem of choosing good names, and training.
To prevent malformed SQL, I imagine you'll want to ensure the regex is valid. You wouldn't want your system to store a ; drop table CUSTOMERS; as a "regular expression"! You'll either have to validate the expression or, if you can, treat the regex as data in a parameterized query.
The real question to me, though, is why you're in the vicinity of standardized regex queries. That need suggests a database design issue: it suggests the column being queried is composed of composite data, and should be represented as multiple columns that can be queried directly, without using regular expressions.

REST based URL for complex resource identifier

I am trying to construct URL for the REST API that needs to use complex resource identifier
e.g. Get specific Course
GET /Courses/{id}
where {id} = {TermId}/{SubjectId}/{SectionID}
Is it acceptable to format it as below or there is a better way?
/Courses/{TermId}/{SubjectId}/{SectionID}
It's rather not acceptable, because it introduces confusion to the clients that use the API you provided. Basically / (slash) indicates a new resource. In this particular case you have Courses resources which has a particular resource with TermId which in turn has SubjectId and so on. This is not readable and not what client expects. I see two possible solutions here:
Use combined key, separated with - or other URI-useable sign:
GET /Courses/{TermId}-{SubjectId}-{SectionID}
Just parse such key on the server side.
Use other URI
GET /Courses/{courseId}/Terms/{termId}/subjects/{subjectId}/sections/{sectionId}
There are also other ideas, the one you suggested doesn't seem useable.
As I see it, you have two reasonable options:
Use a compound key, as #Opal said
Use a surrogate key (an arbitrary key with no relation to your three unique constraints)
The advantage to (1) is that the URI is human-hackable - assuming that the user remembers the order to put the values in and what valid values can be. If a significant use case is going to be students using these URIs to find courses online they might like to skip the search step if they have all the relevant information and just punch those values into the URI. If your response type is HTML, this is not unreasonable.
The advantage to (2) is that it's not human-hackable - REST is about discovery through hypermedia. If the response type is JSON or XML, humans aren't going to be using these URIs directly.
I would suggest supporting the following endpoints:
GET /courses?termId={}&subjectId={}&sectionId={}
// all three parameters are optional. returns all courses that match the
// specified criteria - either a subset of the data or the full course
// data for each result
GET /courses/{courseId}

RESTful API Design OR Predicates

I'm designing a RESTful API and I'm trying to work out how I could represent a predicate with OR an operator when querying for a resource.
For example if I had a resource Foo with a property Name, how would you search for all Foo resources with a name matching "Name1" OR "Name2"?
This is straight forward when it's an AND operator as I could do the following:
http://www.website.com/Foo?Name=Name1&Age=19
The other approach I've seen is to post the search in the body.
You will need to pick your own approach, but I can name few that seem to be pretty logical (although not without disadvantages):
Option 1.: Using | operator:
http://www.website.com/Foo?Name=Name1|Name2
Option 2.: Using modified query param to allow selection by one of the values from the set (list of possible comma-separated values):
http://www.website.com/Foo?Name_in=Name1,Name2
Option 3.: Using PHP-like notation to provide list instead of single string:
http://www.website.com/Foo?Name[]=Name1&Name[]=Name2
All of the above mentioned options have one huge advantage: they do not interfere with other query params.
But as I mentioned, pick your own approach and be consistent about it across your API.
Well one quick way to fixing that is to add an additional parameter that is identifying the relationship between your parameters wether they're an and or an or for example:
http://www.website.com/Foo?Name=Name1&Age=19&or=true
Or for much more complex queries just keep a single parameter and in it include your whole query by making up your own little query language and on the server side you would parse the whole string and extract the information and the statement.