greptilian logo

IRC log for #rest, 2014-12-18

https://trygvis.io/rest-wiki/

| Channels | #rest index | Today | | Search | Google Search | Plain-Text | plain, newest first | summary

All times shown according to UTC.

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

| Channels | #rest index | Today | | Search | Google Search | Plain-Text | plain, newest first | summary

https://trygvis.io/rest-wiki/