Time |
S |
Nick |
Message |
00:13 |
|
|
scflode__ joined #rest |
00:16 |
|
|
sulky joined #rest |
00:17 |
|
|
DrCode joined #rest |
00:21 |
|
|
shrink0r_ joined #rest |
00:23 |
|
|
shrink0r joined #rest |
01:35 |
|
|
shrink0r_ joined #rest |
01:58 |
|
|
PalyaPix joined #rest |
02:34 |
|
|
PalyaPix joined #rest |
03:10 |
|
|
shrink0r joined #rest |
03:17 |
|
|
shrink0r_ joined #rest |
03:24 |
|
|
Davey joined #rest |
03:28 |
|
|
Davey joined #rest |
03:30 |
|
|
tr3onlin_ joined #rest |
03:40 |
|
|
rincewind666 joined #rest |
04:03 |
|
|
lemur joined #rest |
04:46 |
|
|
tr3online joined #rest |
05:12 |
|
|
shrink0r joined #rest |
05:27 |
|
|
rue joined #rest |
05:28 |
|
|
rue_ joined #rest |
05:34 |
|
|
rue joined #rest |
05:39 |
|
|
rue_XIV joined #rest |
05:42 |
|
|
rue_ joined #rest |
05:46 |
|
|
rue joined #rest |
05:52 |
|
|
rue_XIV joined #rest |
05:58 |
|
|
rue joined #rest |
06:28 |
|
|
tr3online joined #rest |
06:28 |
|
|
tr3online joined #rest |
06:33 |
|
|
daxim joined #rest |
07:01 |
|
|
shrink0r joined #rest |
07:29 |
|
|
lufi joined #rest |
07:34 |
|
lufi |
i have an endpoint that returns a collection of objects. for example the client request 10 items. am i required to give 10 items too? |
07:51 |
|
trygvis |
isn't that one of conway's laws? never trust anyone or something like that :) |
07:51 |
|
trygvis |
lufi: I would say: no |
07:52 |
|
trygvis |
for example, the server might not have 10 items, or someone might have deleted one between when the client got the idea that it wanted 10 and when the server got the request |
07:54 |
|
|
scflode__ joined #rest |
07:55 |
|
|
scflode__ joined #rest |
07:56 |
|
lufi |
i see. i am having this problem. the app devs depend on the number of items the endpoint is returning. example if they get less than 10 items in page 2 they assume that it is the end of the page |
07:57 |
|
Jarda |
why do they assume that? |
07:57 |
|
trygvis |
I would let the collection include a number of items/pages left |
07:57 |
|
Jarda |
shouldn't the backend tell that |
07:57 |
|
Jarda |
with hypermedia |
07:57 |
|
Jarda |
(or plain properties) |
07:58 |
|
trygvis |
I think opensearch has decent semantics for that |
07:58 |
|
lufi |
i know. thats the way their app was working before i got here |
07:58 |
|
lufi |
hmm i'll look into that trygvis |
07:58 |
|
lufi |
what I am planning to do is give them a 2xx response with a message like "COLLECTION_EMPTY" or something similar to that |
07:59 |
|
lufi |
maybe a 204 status plus that message |
07:59 |
|
Jarda |
with 204 you can't have a body |
08:01 |
|
lufi |
Jarda I see. |
08:03 |
|
lufi |
I think thats better. it will tell them that there is no content anymore for them to fetch. |
08:04 |
|
Jarda |
I'm in a situation where I have an existing API that is sending JSON arrays as response body |
08:04 |
|
Jarda |
I would need to add pagination |
08:05 |
|
Jarda |
so I have come up with three different solutions |
08:05 |
|
lufi |
what are those solutions jarda? |
08:05 |
|
Jarda |
1) Just add optional pagination parameters to the uri query and document it |
08:06 |
|
Jarda |
2) Change the response to be a json-object with pagination properties in the body, like {total_pages: 15, current_page: 10, items: [...]} |
08:06 |
|
Jarda |
3) Add pagination with headers ( Accept-Ragne, Range etc) |
08:06 |
|
lufi |
i am using both 1 and 2 |
08:07 |
|
Jarda |
with 2) I would break existing clients, so I would have to make a new media type for that and read the Accept-header in the backend |
08:07 |
|
lufi |
modifying the headers can be gruesome to your api consumers |
08:07 |
|
lufi |
I see |
08:07 |
|
lufi |
then use 1. then for the next version add 2 |
08:08 |
|
trygvis |
option 4) is to include a Link header with rel=next if there is a next page |
08:08 |
|
Jarda |
trygvis: yeah that too |
08:08 |
|
trygvis |
4) can make sure clients are not affected by new stuff added to the list |
08:09 |
|
Jarda |
Link <...page=2>, rel=next |
08:09 |
|
Jarda |
Link <...page=143>, rel=last |
08:09 |
|
Jarda |
hmm |
08:09 |
|
Jarda |
no |
08:09 |
|
Jarda |
Link <...page=2>; rel=next, <...page=143>, rel=last |
08:10 |
|
Jarda |
and a ':' there too |
08:11 |
|
trygvis |
well, I would use from-id= instead of page= to don't get extra stuff in your list |
08:11 |
|
Jarda |
but with both Link-header and Range related headers there is no good way of telling the API consumer how many items and/or pages there are |
08:11 |
|
trygvis |
true that. it's best to put them in the hypermedia, even if you use links |
08:11 |
|
Jarda |
maybe some custom X-MyApp-Total-Items: 14324 |
08:13 |
|
Jarda |
yeah I remembered correctly, github API uses Link header for paghination |
08:13 |
|
Jarda |
https://developer.github.com/guides/traversing-with-pagination/ |
08:13 |
|
Jarda |
and they have in their example code something like: number_of_pages = last_response.rels[:last].h​ref.match(/page=(\d+)$/)[1] |
08:14 |
|
Jarda |
so if the backend would want to change away from page=123 notation the client would break |
08:14 |
|
trygvis |
bleh, that's silly |
08:16 |
|
trygvis |
it's horrible |
08:17 |
|
Jarda |
it renders use of hypermedia a bit unusable |
08:17 |
|
Jarda |
or the idea |
08:17 |
|
Jarda |
if they advice people to still depend on URI schemes |
08:20 |
|
trygvis |
yeah, it's very bad REST. perhaps good RPC, but bad REST |
08:20 |
|
Jarda |
I think I'll still go with 2) with combined Links in repsonse headers |
08:21 |
|
Jarda |
that way clients saying 'I accept application/vnd.mycompany.myapp.v2+json' get the new version |
08:21 |
|
Jarda |
but here comes the tricky part again |
08:21 |
|
trygvis |
versioned hypermedia is also on my 'bad REST' list :) |
08:22 |
|
Jarda |
versioning with media type - can I assume that if they know myapp.v2 they also know how to use v1 |
08:22 |
|
Jarda |
or should I fallback to plain JSON |
08:22 |
|
Jarda |
(well my v1 is kinda plain JSON) |
08:23 |
|
Jarda |
I guess I can't make such assumptions |
08:23 |
|
trygvis |
if a client can't handle new elements in a response it shouldn't be allowed to exist |
08:24 |
|
Jarda |
trygvis: but this is one of such cases where it makes sense to version |
08:24 |
|
Jarda |
the response changes from array to object |
08:24 |
|
Jarda |
so it's not just a matter of added/missing properties |
08:24 |
|
trygvis |
it never makes sense to version |
08:24 |
|
Jarda |
and yes, I know sending plain arrays was a poor choice to begin with |
08:25 |
|
trygvis |
yes, that was a poor choice :) |
08:25 |
|
|
rincewind_ joined #rest |
08:25 |
|
trygvis |
but instead of adding a new version I would try to level up and make something more generic |
08:26 |
|
Jarda |
well most of the clients just send Accept: application/json anyway |
08:26 |
|
Jarda |
so I could actually send json arrays to them |
08:26 |
|
Jarda |
and those who actually know what they are doing I could start sending with a custom media type |
08:27 |
|
trygvis |
in your case that sounds like a good approach |
08:27 |
|
|
interop_madness joined #rest |
08:28 |
|
Jarda |
do you normally do traversable APIs? |
08:28 |
|
Jarda |
such that consumer just requests the root endpoint and uses hypermedia from there |
08:29 |
|
trygvis |
I've done a few |
08:30 |
|
interop_madness |
what's a good way to design a REST interface that recieves a file together with medatada? multipart/form-data? upload file first, then reference it in the POST request for the metadata (how exactly?)? |
08:30 |
|
trygvis |
a could was for downloading content from a CMS, where we had separate frontends for consumers and backends for editors |
08:32 |
|
trygvis |
interop_madness: there are many options! |
08:33 |
|
trygvis |
multipart is one way, but often a bit painful to code and get right |
08:33 |
|
trygvis |
libraries seems to suck at handling multipart correctly and have implicit assumptions about the request coming from a browser |
08:34 |
|
Jarda |
I have done three different approaches for files with metadata (my #1 pain point in API's actually) |
08:34 |
|
trygvis |
an alternative as you said is to have two endpoints, one for blobs and one for metadata. when you post to the metadata endpoint, one property could be the blob it's describing (the blob's URL) |
08:35 |
|
Jarda |
1) POST metadata first as JSON, then to the created resource (/foos/123) I post with Content-Type: application/pdf so my backend knows I'm adding files to the metadata |
08:36 |
|
Jarda |
2) use multipart/form-data which works allright but is a bit hard to get right in backends |
08:36 |
|
trygvis |
the "file with metadata" problem is a general problem of uploading many resources in one transaction-like operation |
08:36 |
|
Jarda |
3) post directly with the file (Content-Type: application/pdf) and send a query-string in headers |
08:37 |
|
Jarda |
3) is dirty, but works |
08:37 |
|
Jarda |
X-Upload-Metadata: foo=bar&baz=quux |
08:38 |
|
Jarda |
of course 3) could be also achieved by sending the parameters in URL |
08:38 |
|
trygvis |
3) is kinda bad |
08:38 |
|
Jarda |
yeah |
08:39 |
|
trygvis |
between two apps I recently made I made a JAR file instead, but this was more to do RPC stuff (splitting and converting an email to many files) |
08:40 |
|
trygvis |
the first file in the stream has to be report.properties which describes what do to with the rest of the stream |
08:40 |
|
trygvis |
(no external dependencies, yay) |
08:40 |
|
Jarda |
btw: http://www.w3.org/TR/html-json-forms/ |
08:41 |
|
Jarda |
they have done files so that they are base64 strings inside the json |
08:41 |
|
Jarda |
I have yet to find a streaming JSON parser |
08:41 |
|
Jarda |
after that I could use that too |
08:42 |
|
trygvis |
orly? in java there are many |
08:42 |
|
Jarda |
but with big files and string serialization/deserialization that could be a memory consuption nightmare |
08:42 |
|
Jarda |
trygvis: well I use nodejs on all backends |
08:42 |
|
Jarda |
I guess there are streaming parsers |
08:42 |
|
trygvis |
yeah, I would assume so to |
08:42 |
|
Jarda |
but the frameworks tend to do string serialization automatically everywhere |
08:43 |
|
Jarda |
so I would have to go through the whole stack to see no tool serializes response bodies to strings etc |
08:43 |
|
trygvis |
but you probably wouldn't do >1GB files with html-json-forms |
08:44 |
|
trygvis |
I honestly don't see that html-json-forms is adding much value to the world |
08:44 |
|
Jarda |
I have come up with one use case |
08:45 |
|
Jarda |
these POST->redirect back type of things when CORS wants to be avoided |
08:45 |
|
Jarda |
and then you don't have to implement anything other than application/json parsing in the backend |
08:48 |
|
|
lufi joined #rest |
08:49 |
|
|
shrink0r joined #rest |
09:03 |
|
interop_madness |
ok, i'm warming up to the idea of multipart/form-data (one use case is specifically metadata+file within a transaction)... |
09:04 |
|
|
lemur joined #rest |
09:08 |
|
|
lufi joined #rest |
09:17 |
|
|
graste joined #rest |
09:27 |
|
|
marcoslamuria joined #rest |
09:28 |
|
|
lufi joined #rest |
09:51 |
|
|
lufi joined #rest |
10:10 |
|
|
scflode____ joined #rest |
10:14 |
|
|
martinfilliau joined #rest |
10:17 |
|
|
Left_Turn joined #rest |
10:38 |
|
|
shrink0r joined #rest |
11:21 |
|
|
tr3online joined #rest |
11:27 |
|
|
scflode joined #rest |
12:27 |
|
|
shrink0r joined #rest |
12:39 |
|
|
scflode joined #rest |
12:49 |
|
|
marcoslamuria joined #rest |
13:23 |
|
|
lufi joined #rest |
13:32 |
|
|
marcoslamuria joined #rest |
13:43 |
|
|
shrink0r joined #rest |
13:52 |
|
|
tr3online joined #rest |
14:08 |
|
|
rincewind666 joined #rest |
14:23 |
|
|
marcoslamuria joined #rest |
14:25 |
|
|
scflode_ joined #rest |
14:28 |
|
|
scflode_ joined #rest |
14:54 |
|
|
tr3online joined #rest |
14:55 |
|
|
martinfi_ joined #rest |
15:09 |
|
|
scflode__ joined #rest |
15:09 |
|
|
marcosla_ joined #rest |
15:09 |
|
|
nkoza joined #rest |
15:59 |
|
|
marcoslamuria joined #rest |
16:20 |
|
|
fumanchu joined #rest |
16:55 |
|
|
tr3online joined #rest |
17:36 |
|
|
nkoza joined #rest |
17:45 |
|
|
mezod joined #rest |
17:50 |
|
|
marcoslamuria joined #rest |
17:51 |
|
|
tr3online joined #rest |
18:10 |
|
|
rue joined #rest |
18:38 |
|
|
lemur joined #rest |
18:42 |
|
|
lemur joined #rest |
19:10 |
|
|
tr3online joined #rest |
19:11 |
|
|
tr3online joined #rest |
19:17 |
|
|
rue joined #rest |
20:05 |
|
|
rue joined #rest |
20:12 |
|
|
graste joined #rest |
20:41 |
|
|
marcoslamuria joined #rest |
20:51 |
|
|
marcoslamuria joined #rest |
20:57 |
|
|
talios joined #rest |
21:01 |
|
|
znn joined #rest |
21:26 |
|
|
marcoslamuria joined #rest |
21:39 |
|
|
pezra joined #rest |
22:12 |
|
|
jackalista joined #rest |
22:41 |
|
|
proteusguy joined #rest |