I would like to ask a question about the dss.
I'm creating queries to expose services rest by retrieving data from a db postrgresql.
I would like to expose a service that, based on an incoming parameter (table name), retrieves all of that table. But I have a problem.
I do not know a priori the number and the name of the columns in this table. So I wonder how I can map the output (maybe in a generic object)? It's possible to do it? Or do I need to know the name of the columns absolutely?
Thanks a lot
The DSS requires you to define what the response will look like beforehand. It is not dynamic like that.
Related
I have a REST syntaxe question:
what url do you give to an endpoint to extract data similar to the record which from the id passed?
By exemple : I have a class Record:
Record {id:12, phoneNumber:"+336746563"}
I want a endpoint who will return all the records who share the same phoneNumber than the record with the id 12
which url respect the most the REST protocol ?
EDIT IMPORTANT : the client DON't know the phone number when he call the url. only the 12 id.
what url do you give to an endpoint to extract data similar to the record which from the id passed?
Anything you want -- the machines don't care what spelling you use for your resource identifiers.
I want a endpoint who will return all the records who share the same phoneNumber than the record with the id 12
/all-records-with-same-phone-number-as?id=12
/all-records-with-same-phone-number-as?12
/all-records-with-same-phone-number-as/12
All of these examples are fine. They have different trade offs -- the first one is really easy to generate using an HTML form. The last once allows you do interesting things with relative references and dot-segments.
/record/12/all-records-with-same-phone-number
similar to the above, we've just juggled the order of the path segments a little bit. Might be useful if we want to have relative references to other resources under the same /record/12 stem.
If you are expecting to need to paginate, then you might want to think about how the paging parameters fit with everything else. Again, the machines don't care, but some spellings are easier to work with than others.
I am not sure if I understand the question but let me try.
You can do this in various ways which is best suited for you w.r.t. your programming language. For example, domain.com/api/records/123456 can be the end-point. 123456 is a parameter and your code will return all the records having phoneNumber=123456.
Alternatively, the end-point can be domain.com/api/records?phoneNumber=12345.
Or Even, domain.com/api/records/123456/phonenumber.
The other option is to have the request data in the body and the domain would just look like domain.com/api/records with request as {"PhoneNumber":"123456"}
AFAIK, all these URLs respect REST protocol.
I would use something like
/service/records/{id}/similar
where the service would define similarity. It depends on the usecases for when Record becomes more complex and the client should able to specify fields.
This would sooner or later result in queries that would not be based on an existing record and my look like
/service/records?foo=1&bar=2
I could also think of
/service/records/phone-number/12345
because you are really interested in records with the same phoneNumber, not similarity?
But again, as things get more complex you will be better off with a query I think.
Let's take the following resource in my REST API:
GET `http://api/v1/user/users/{id}`
In normal circumstances I would use this like so:
GET `http://api/v1/user/users/aabc`
Where aabc is the user id.
There are times, however, when I have had to design my REST API in a way that some extra information is passed with the ID. For example:
GET `http://api/v1/user/users/customer:1`
Where customer:1 denotes I am using an id from the customer domain to lookup the user and that id is 1.
I now have a scenario where the identifier is more than one key (a composite key). For example:
GET `http://api/v1/user/users/customer:1;type:agent`
My question: in the above URL, what should I use as the separator between customer:1 and type:agent?
According to https://www.ietf.org/rfc/rfc3986.txt I believe that the semi-colon is not allowed.
You should either:
Use parameters:
GET http://api/v1/user/users?customer=1
Or use a new URL:
GET http://api/v1/user/users/customer/1
But use Standards like this
("Paths tend to be cached, parameters tend to not be, as a general rule.")
Instead of trying to create a general structure for accessing records via multiple keys at once, I would suggest trying to think of this on more of a case-by-case basis.
To take your example, one way to interpret it is that you have multiple customers, and those customers each may have multiple user accounts. A natural hierarchy for this would be:
/customer/x/user/y
Often an elegant decision like this can be made, that not only solves the problem but also documents your data-model in a way that someone can easily see that users belong to customers via a 1-to-many relationship.
I'm rewriting an API to be more RESTful, but I'm struggling with a design issue. I'll explain the situation first and then my question.
SITUATION:
I have two sets resources users and items. Each user has a list of item, so the resource path would like something like this:
api/v1/users/{userId}/items
Also each user has an isPrimary property, but only one user can be primary at a time. This means that if I want to get the primary user you'd do something like this:
api/v1/users?isPrimary=true
This should return a single "primary" user.
I have client of my API that wants to get the items of the primary user, but can't make two API calls (one to get the primary user and the second to get the items of the user, using the userId). Instead the client would like to make a single API call.
QUESTION:
How should I got about designing an API that fetches the items of a single user in only one API call when all the client has is the isPrimary query parameter for the user?
MY THOUGHTS:
I think I have a some options:
Option 1) api/v1/users?isPrimary=true will return the list of items along with the user data.
I don't like this one, because I have other API clients that call api/v1/users or api/v1/users?isPrimary=true to only get and parse through user data NOT item data. A user can have thousands of items, so returning those items every time would be taxing on both the client and the service.
Option 2) api/v1/users/items?isPrimary=true
I also don't like this because it's ugly and not really RESTful since there is not {userId} in the path and isPrimary isn't a property of items.
Option 3) api/v1/users?isPrimary=true&isShowingItems=true
This is like the first one, but I use another query parameter to flag whether or not to show the items belonging to the user in the response. The problem is that the query parameter is misleading because there is no isShowingItems property associated with a user.
Any help that you all could provide will be greatly appreciated. Thanks in advance.
There's no real standard solution for this, and all of your solutions are in my mind valid. So my answer will be a bit subjective.
Have you looked at HAL for your API format? HAL has a standard way to embed data from one resources into another (using _embedded) and it sounds like a pretty valid use-case for this.
The server can decide whether to embed the items based on a number of criteria, but one cheap solution might be to just add a query parameter like ?embed=items
Even if you don't use HAL, conceptually you could still copy this behavior similarly. Or maybe you only use _embedded. At least it's re-using an existing idea over building something new.
Aside from that practical solution, there is nothing in un-RESTful about exposing data at multiple endpoints. So if you created a resource like:
/v1/primary-user-with-items
Then this might be ugly and inconsistent with the rest of your API, but not inherently
'not RESTful' (sorry for the double negative).
You could include a List<User.Fieldset> parameter called fieldsets, and then include things if they are specified in fieldsets. This has the benefit that you can reuse the pattern by adding fieldsets onto any object in your API that has fields you might wish to include.
api/v1/users?isPrimary=true&fieldsets=items
I am developing a generic REST API for my projects and I'm wondering what to do when I have a table/resource with 2 or more primary keys.
For example, lets suppose I have a table named "question" with two primary keys (date and type) and I need to create the resource REST URI. What is the best way to do it following the standard schema api/{resource}/{id}?
Maybe something like: api/question/{:date},{:type}? What is the best way to do it?
Thank you.
I think that what you call multiple primary keys is a composite key. Right?
You have some options.
Use api/questions/dates/:date/types/:type
Maybe, the best alternative for you is:
api/questions/dates/{:date}/types/{:type}
This is more natural to read as a http resource for your case, even if don't make sense have a api/question/dates/{:date} in your application.
Use api/questions/:date/:type/
Another alternative is:
api/questions/:date/:type/
Use query parameter
If it's no a problem for you, instead of return a single object question you can return an array of questions as response using a filter query, like:
api/questions?date=2022-10-27&type=XYZ
Both are not mandatory, but if the user send both, the return will be always an array with a single element. Also this bring some flexibility to your API, because the user can inform just one of them and have some results. You need to check if this behavior it's valid for your case.
You're on the right path, I think you definitely should include both the date and the type in the resource url if that's the only way you can uniquely identify it
api/question/{date}_{type}
This is a good example of when to use a slug. This answer to What is a slug provides a good idea of how you can use your composite primary key in your api design.
with that, you have a few options at your disposal. Which is the best would be a matter of opinion and what suits your needs.
api/question/{:date}/{:type} or api/question/{:key1}/{:key2}/.../{:keyn}
The same pattern could also be applied to the following.
api/question/{:date}_{:type}
api/question/{:date}-{:type}
I do not find it a good idea of having two primary keys for a resource. REST heavily depends on resources and it's representations.
If you are struck into situation where you are ending up with two identifiers for a resource - then redesign your application (may be by creating another key in backend after mapping it to other identifiers) and add these multiple keys as attributes in resource.
Idea is - "keep it simple" if you want to create truly world class REST APIs.
Bonus: You don't need to teach few extra things to clients/developers about something fancy you did with your APIs.
I am new to Cassandra and I am having some difficulties fetching data.
I looked into the function:
list<KeySlice> get_range_slices(column_parent, predicate, range, consistency_level)
But, I do not understand what the column_parent is supposed to be.
Anybody any idea?=
Thanx,
Granit
column_parent is basicly used for indicator of ColumnFamily(but in rare cases it can indicate a supercolumn). In java you would put : new ColumnParent("Posts") there. but there should be one more parameter for namespace in get_range_slices query, I guess you are not using thrift but a client api. then you should check your client's documentation.
Edit:
the definition of ColumnParent in cassandra api :
The ColumnParent is the path to the
parent of a particular set of Columns.
It is used when selecting groups of
columns from the same ColumnFamily. In
directory structure terms, imagine
ColumnParent as ColumnPath + '/../'.
Frail is correct, but the real answer is "don't use raw Thrift, use one of the clients from http://wiki.apache.org/cassandra/ClientOptions instead."