Time |
S |
Nick |
Message |
00:35 |
|
|
fuzzyhorns joined #rest |
01:30 |
|
|
philbot joined #rest |
01:30 |
|
|
Topic for #rest is now #rest REpresentational State Transfer | logs: http://irclog.greptilian.com/rest/today | http://tech.groups.yahoo.com/group/rest-discuss | http://code.google.com/p/implementing-rest/ | http://en.wikipedia.org/wiki/Representational_State_Transfer |
02:01 |
|
|
fuzzyhorns joined #rest |
02:52 |
|
|
fuzzyhorns joined #rest |
06:18 |
|
|
Left_Turn joined #rest |
08:15 |
|
|
graste joined #rest |
08:18 |
|
|
jgornick joined #rest |
09:06 |
|
|
quimrstorres joined #rest |
09:07 |
|
|
rincewind666 joined #rest |
09:17 |
|
|
quimrstorres joined #rest |
09:18 |
|
|
rincewind_ joined #rest |
11:02 |
|
|
quimrstorres joined #rest |
11:08 |
|
|
Coldblackice_ joined #rest |
11:20 |
|
|
interop_madness joined #rest |
11:32 |
|
|
quimrsto_ joined #rest |
11:51 |
|
|
vanHoesel joined #rest |
13:42 |
|
|
fuzzyhorns joined #rest |
13:49 |
|
|
kevinswiber joined #rest |
13:51 |
|
|
quimrstorres joined #rest |
15:52 |
|
|
baweaver joined #rest |
17:55 |
|
|
kevinswiber joined #rest |
19:21 |
|
|
graste joined #rest |
19:47 |
|
|
Coldblackice joined #rest |
19:49 |
|
|
jcromartie joined #rest |
20:04 |
|
|
ModusPwnens joined #rest |
20:09 |
|
ModusPwnens |
Let's say you have the following resources: http://pastie.org/10222237. Let's also say that you want to search all your foo resources and get a list of all bar resources belonging to a foo resource with a state=open. How would this look from a restful URI perspective? |
20:11 |
|
ModusPwnens |
I've been reading about various query params that are used when doing resource searches, so what I was thinking was something like this: GET /foos?state=open&include=bar&expand=bar. Does that seem sensible? |
20:13 |
|
sfisque |
if the bar's "belong" to the foo, wouldnt they be children? e.g. /foos/foo_id_1234/bars?state=open |
20:13 |
|
sfisque |
not saying your example is incorrect, but wouldnt it be clearer to consumers if the parent/child relationship be reflected in the uri |
20:14 |
|
ModusPwnens |
They don't quite 'belong' to the foo. They are just associated with it. |
20:14 |
|
sfisque |
ah, gotcha |
20:14 |
|
ModusPwnens |
Or is that wrong? |
20:14 |
|
sfisque |
so more graphlike, than tree like? |
20:15 |
|
ModusPwnens |
We have one API in charge of Foos and another in charge of Bars |
20:15 |
|
ModusPwnens |
because they can exist outside of each other |
20:15 |
|
sfisque |
hrm. that really depends on how your system wants to expose the relationship. |
20:16 |
|
ModusPwnens |
if bar was a subresource of foo, I would be far more confident in the URI that I suggested |
20:16 |
|
ModusPwnens |
but maybe this means that there should be a "Search" resource |
20:16 |
|
sfisque |
if they are merely "linked" then cross querying could be ok, as long as you can bi-directionally resolve the linkage i guess |
20:16 |
|
fumanchu_ |
personally, I'd use GET /bars/open/ |
20:16 |
|
ModusPwnens |
that is in charge of complex searches involving multiple resources? |
20:16 |
|
fumanchu_ |
I find complex search params to be an antipattern |
20:16 |
|
sfisque |
unless "open" is not unique |
20:17 |
|
ModusPwnens |
fumanchu_: that is something a teammate proposed. But then I thought that didn't make sense because 'state' is not an attribute of a bar |
20:17 |
|
sfisque |
the problem is if you have multiple attribute that can resolve to the same value |
20:17 |
|
sfisque |
then /open/ becomes muddy |
20:17 |
|
fumanchu_ |
ModusPwnens: it doesn't have to be an attribute of bar. It's just the name of a more complex filter. |
20:18 |
|
sfisque |
ah i see what you're saying |
20:18 |
|
fumanchu_ |
GET /bars/whose_foo_is_open would be just as well (but too long) |
20:18 |
|
fumanchu_ |
use whatever term is meaningful to what the client is trying to accomplish |
20:18 |
|
ModusPwnens |
Is that really okay? It seems odd to perform a search on a top level resource using an attribute filter for a totally different resource |
20:19 |
|
fumanchu_ |
sure |
20:19 |
|
fumanchu_ |
no odder than the other direction |
20:19 |
|
sfisque |
depends on what the client is supposed to report. remember that "representation" is not necessarily what is housed "underneath" |
20:20 |
|
sfisque |
what could appear as a "top level attribute" could in fact be the result of a table join or a link to a nosql node |
20:21 |
|
fumanchu_ |
right. the whole point of the RESTful interface is to hide such implementation concerns |
20:21 |
|
sfisque |
^^^ |
20:22 |
|
ModusPwnens |
Right, and I'm not trying to show those. The client is totally unaware of how all that stuff is implemented |
20:23 |
|
ModusPwnens |
but the client does know what top level resources belong to what. They know that a foo has a state attr and a bar does not. So is it reasonable to expect them to know they can filter bar resources by attributes of foo resources? |
20:24 |
|
sfisque |
does client "know" of the linkage between foo<->bar? |
20:24 |
|
sfisque |
if so, then the query makes sense from a "follow the edges of the graph" manner |
20:24 |
|
ModusPwnens |
Well the client knows of the linkage because when they GET a foo, they see it has a reference to a bart |
20:25 |
|
ModusPwnens |
bar* |
20:27 |
|
fumanchu_ |
discoverability is a valid point, but I find it equally awkward to expect a GET of /foos?...include&expand to give me bar info |
20:27 |
|
ModusPwnens |
isn't that the point of the includes and expands query params? |
20:27 |
|
sfisque |
aye. i would offer that it's probably more meaningful to get a list of foo's and those foo's may/may-not have links to bar's |
20:27 |
|
fumanchu_ |
I'm saying they're not any more "discoverable" |
20:28 |
|
fumanchu_ |
"knowable" |
20:28 |
|
sfisque |
and conversely a list of bar's which may/may not have linked foo's |
20:28 |
|
sfisque |
but like fu says, querying for foo's and expecting bar's is arguably counter to rest |
20:29 |
|
ModusPwnens |
I am sort of working from this doc that I found on resource expansion/autoloading: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#autoloading |
20:29 |
|
sfisque |
and unclear as far as api design is concerned |
20:30 |
|
fumanchu_ |
"best practices"..."against some RESTful principles" nice :P |
20:30 |
|
* sfisque |
smirks |
20:31 |
|
fumanchu_ |
I find caching is greatly complicated by duplicating the same data across multiple resources, and embedding/including is perhaps the worst offender |
20:32 |
|
|
vanHoesel joined #rest |
20:32 |
|
fumanchu_ |
what you're looking to expose in any search is essentially a "secondary index" in DB speak |
20:32 |
|
ModusPwnens |
Apparently embedding/linking is not good..http://stackoverflow.com/questions/19991232/include-embed-vs-link-in-restful-apis |
20:34 |
|
fumanchu_ |
it's in your interest to keep what's in that index to a minimum; just links to the canonical bar resources if you can |
20:35 |
|
fumanchu_ |
(but sometimes you need enough for a human to decide which one to follow) |
20:36 |
|
fumanchu_ |
AYROCFEWNEDSWUR |
20:37 |
|
ModusPwnens |
so does that mean you should just force clients to follow URLs and make the requests themselves? |
20:38 |
|
ModusPwnens |
e.g. search foos for state=open and then iterate over the list of foos and fetch the bars with the returned ids |
20:38 |
|
fumanchu_ |
not blindly; you need to strike a balance, mostly for efficiency reasons |
20:39 |
|
fumanchu_ |
there are very few endpoints where clients actually want all data for a ton of resources |
20:39 |
|
fumanchu_ |
they either want an aggregate, or they want to navigate to one of them |
20:39 |
|
ModusPwnens |
yeah...this is mainly just a way of doing the cross resource seraching/filterig i was talking about earlier |
20:46 |
|
ModusPwnens |
fumanchu_: Also, there are very few endpoints where clients want all data, but wouldn't that be handled by a query param that indicates that? |
20:47 |
|
fumanchu_ |
it has been countless times. but in my experience it leads to APIs easily open to abuse with the "wrong" params |
20:48 |
|
|
fuzzyhorns joined #rest |
20:48 |
|
fumanchu_ |
client devs then get horrible performance and fight to go back to RPC |
20:48 |
|
fumanchu_ |
rather than provide an API with a billion combinations, find the handful clients need, name them uniquely, and expose just those |
20:49 |
|
fuzzyhorns |
mamund: is an embedded link in siren what you mean by LE in H-factor definition? see: https://github.com/kevinswiber/siren#embedded-link |
20:49 |
|
fuzzyhorns |
im a little fuzzy on what an LE would be outside of image transclusion |
22:04 |
|
|
fuzzyhor_ joined #rest |
22:11 |
|
|
fumanchu joined #rest |
22:59 |
|
|
Rotaerk joined #rest |
23:29 |
|
Rotaerk |
ran across a comment from Roy that convinces me that when he said "standard" media types, he did have in mind for there to be few, registered, global ones, rather than app-specific custom ones |
23:29 |
|
Rotaerk |
but that leaves me with an apparent contradiction... |
23:32 |
|
Rotaerk |
if all a client should know is 1) the entry-point URI, 2) the documentation for media types it wants to handle, and 3) the valid link relation types... |
23:32 |
|
Rotaerk |
then how do you convey app-specific information with only generic media types |
23:33 |
|
sfisque |
rotaerk you still have the onus of commiting business logic in the client OR delivering it to the client (as a lib or rules packet) |
23:34 |
|
Rotaerk |
you have to do business logic in the client *but* you can only do it in terms of the above information |
23:34 |
|
sfisque |
you cannot expect a client to just infer that it is supposed to consume a link a certain way. a stock ticker app is not a cms app |
23:34 |
|
sfisque |
that is outside what rest requires |
23:35 |
|
Rotaerk |
if for instance there is a service with a customer resource, with a Name field and a Phone Number field, but you're returning it merely with the standard xml media type... how can the client know to expect these fields |
23:35 |
|
sfisque |
because the developer coded it to do that |
23:35 |
|
sfisque |
and it either reports an error or handles the exception gracefully |
23:36 |
|
Rotaerk |
but the developer is relying on out-of-band information to do that; information that's not documented for a media type |
23:36 |
|
Rotaerk |
i.e. there is no *media type* which has a <Person> element containing a <Name> and <PhoneNumber> |
23:36 |
|
sfisque |
once again, i think you are confusing "media type" with context |
23:36 |
|
Rotaerk |
context? |
23:37 |
|
Rotaerk |
isn't any context outside of those 3 points... "out of band"? |
23:37 |
|
sfisque |
i write a client to consume a particular data context (stock records) and i expect that data to adhere to the published rules/schema/etc. |
23:37 |
|
Rotaerk |
yea but those rules/schema should, according to the REST principles, be encapsulated in the documentation for a media type |
23:37 |
|
Rotaerk |
not in something *on top of* a media type |
23:37 |
|
sfisque |
negative |
23:37 |
|
sfisque |
where does it explain that |
23:38 |
|
Rotaerk |
"A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience" |
23:38 |
|
Rotaerk |
"A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. Any effort spent describing what methods to use on what URIs of interest should be entirely defined within the scope of the processing rules for a media type (and, in most |
23:38 |
|
Rotaerk |
cases, already defined by existing media types)." |
23:39 |
|
Rotaerk |
it doesn't say that the REST API should spend its descriptive effort defining schemas on top of the media types |
23:39 |
|
Rotaerk |
it says it should be describing media types themselves |
23:40 |
|
sfisque |
ok, so where in this discussion does it require the client being able to infer the internals of a media type? |
23:40 |
|
Rotaerk |
it doesn't; the media type *definition* tells the client what those internals are |
23:41 |
|
sfisque |
negative |
23:41 |
|
sfisque |
it tells the client what the data is. period |
23:41 |
|
sfisque |
text |
23:41 |
|
sfisque |
image |
23:41 |
|
sfisque |
binary stream |
23:41 |
|
sfisque |
audio |
23:41 |
|
sfisque |
excel spreadsheet |
23:41 |
|
Rotaerk |
person |
23:41 |
|
Rotaerk |
client |
23:41 |
|
Rotaerk |
customer :P |
23:41 |
|
sfisque |
then you have to define those |
23:41 |
|
sfisque |
x-person |
23:41 |
|
sfisque |
and you have to document it |
23:41 |
|
Rotaerk |
right, except x-* is verboten |
23:42 |
|
sfisque |
according to whom? |
23:42 |
|
Rotaerk |
it's deprecated even |
23:42 |
|
Rotaerk |
RFC 6648 |
23:42 |
|
sfisque |
ive not read that one but by the numbering appears fairly recent |
23:42 |
|
Rotaerk |
also Roy himself seemed to say that media types should be *standard* |
23:42 |
|
sfisque |
standard for "most cases" |
23:43 |
|
Rotaerk |
seems to me that it would be custom for most cases |
23:43 |
|
sfisque |
so if you need standard media for those entities, use x509 or hl7 or x12 |
23:43 |
|
Rotaerk |
except services intended to be consumed by browsers, which don't need domain-specific knowledge about the data |
23:43 |
|
sfisque |
they exist, you just have not discovered them yet |
23:43 |
|
fumanchu |
that's what mobile code is for |
23:43 |
|
sfisque |
aye that was the other option, you ship the code to the client |
23:44 |
|
sfisque |
or tie to the data (a la opendoc or similar) |
23:44 |
|
ModusPwnens |
I'm back with more questions. How do you support a flexible restful search api when you are indexing your resources based on certain fields and you only want to search by indexable things? |
23:44 |
|
fumanchu |
be less flexible |
23:45 |
|
Rotaerk |
hrm, how is x509 or hl7 or x12 going to express the particular data schema of my entities? |
23:45 |
|
ModusPwnens |
fumanchu: So the answer is basically that you can't and your search API is forced to be rigid? |
23:46 |
|
fumanchu |
that's what it sounded like your stated constraints were saying? |
23:46 |
|
fumanchu |
perhaps I misunderstood |
23:46 |
|
ModusPwnens |
fumanchu: That's the conclusion I had too, but I was hoping it was wrong :( |
23:47 |
|
Rotaerk |
sfisque, it seems unlikely for two services to have the same data model for its entities |
23:47 |
|
Rotaerk |
so it seems like MOST would need custom media types for each of their entities |
23:47 |
|
Rotaerk |
customer, product, purchase, etc |
23:47 |
|
Rotaerk |
x-customer, x-product, x-purchase |
23:48 |
|
Rotaerk |
maybe with a +xml after each, if they're encoded in XML |
23:48 |
|
ModusPwnens |
fumanchu: The result of this is that we are going to add a URI called /resource/query/{queryId}, where the queryId is the name of an SQL satement stored on our server that executes a specific sql statement to perform the search the user wants. And that makes me a sad panda |
23:48 |
|
Rotaerk |
the only time it makes sense to use a generic media type, like xml or html or whatever, is if the client isn't going to be making any decisions based on the data |
23:48 |
|
Rotaerk |
if it's simply transforming that data blindly, like a browser does |
23:49 |
|
Rotaerk |
transforming/rendering |
23:49 |
|
Rotaerk |
and letting the user be the center of logic |
23:49 |
|
fumanchu |
ModusPwnens: that should make you ecstatic if it's spelled /resource/name_meaningful_to_the_client instead of a number |
23:50 |
|
Rotaerk |
I mean, each of those entities could *also* have generic representations |
23:50 |
|
fumanchu |
if queryId 123 gives the client a set of foos where status == "closed", then /foo/closed/ is perfect. that's exactly what the literature means when it says the server "maps the URI to a handler" |
23:51 |
|
Rotaerk |
each person could be fetched as an x-person *or* as generic xml/html, for browsers and such |
23:51 |
|
Rotaerk |
the former would be for things that need to actually parse the information about a person |
23:52 |
|
ModusPwnens |
fumanchu: I'd actually be OK with that. I just don't like the /query/{nameOfQuery} URI |
23:53 |
|
fumanchu |
yes, that's a bit ugly |
23:53 |
|
|
rosstuck joined #rest |
23:54 |
|
fumanchu |
better hope you never reappropriate ids if you cache heavily ;) |
23:54 |
|
sfisque |
Rotaerk trust me, your "problem" has been solved many times. check out x509, HL7, X12, etc. |
23:54 |
|
sfisque |
there are many "standard" encodings for a "person", "contract", "contact", etc. that exist over many domains |
23:55 |
|
sfisque |
every domain has consortiums who "solve" data interchange. has been on-going since computers appeared on the scene about 60 years ago |
23:56 |
|
Rotaerk |
hmm I don't see "509" in the list of registered media types |
23:57 |
|
pdurbin |
sfisque: yeah, metadata in scholarly publishing for example has many standards, plenty of disagreement :) |
23:58 |
|
Rotaerk |
X.509 comes up via google, but that doesn't appear to be relevant |
23:58 |
|
Rotaerk |
some kind of certificate |
23:59 |
|
Rotaerk |
the others don't show up as media types either |