Fork me on GitHub
#yada
<
2016-06-27
>
jonathanj07:06:06

How does one actually return one or the other for a given request?

jonathanj07:06:00

According to the “Responses” chapter in the manual, it looks like the answer is to manually construct the switch in the response function.

imre08:06:05

is there any specific reason you want to return one over the other?

imre08:06:24

usually if you offer multiple representations it's for the client's convenience

imre08:06:11

so it would be the client asking for one or the other and then what gets returned would be decided by yada during content negotiation

malcolmsparks08:06:36

@jonathanj: Here's how it works:

malcolmsparks08:06:12

1. You declare the representations your resource can support 2. yada does the negotiation (proactively, reactive is on its way, not ready yet) 3. yada calls your response function with the results of the negotiation process contained in the ctx argument 4. You decide what to do - you can manually switch or you might return some data, in which case yada will try to automatically coerce if for you

malcolmsparks08:06:58

So yes, it is manual, unless you rely on yada's automatic response coercion capabilities - and its protocol based so you can add your own

jonathanj08:06:50

There are unfortunate knock-on effects to all that though, like if your two representations are JSON and XML, there’s no obvious intermediate data structure that can be encoded into a reasonable representation of both, so you end up having to write this switch in your 200, 404, 500, etc. handlers.

jonathanj08:06:02

But it’s all kind of stuffed into one resource.

malcolmsparks08:06:27

Yes, but you can programatically create such constructions

malcolmsparks08:06:51

Do you need to return the representation in 404 and 500?

malcolmsparks08:06:34

Typically they would return something different. It isn't idiomatic to return the same JSON/XML data for them as you would for a 200

jonathanj08:06:14

I’m not too sure I understand, wouldn’t the content of the response be wildly different for 500 and 200?

jonathanj08:06:25

Namely “Here’s the failure” and “Here’s the successful result”?

jonathanj08:06:29

I guess if you’re constrained to describing your result as a schema then probably you can’t actually use something like XML attributes?

jonathanj08:06:39

I think that perhaps it might be best to simply have separate resource hierarchies, keeping resources simpler seems like the more manageable solution.

malcolmsparks08:06:20

Yes, the content of a 200 response would be wildly different from a 500 one. So then I don't understand the question.

malcolmsparks08:06:05

I think I'm beginning to understand it though 🙂

jonathanj08:06:36

I was just pointing out that you’d likely have to repeat the same kind of logic (albeit slightly different) for each response handler

malcolmsparks08:06:58

If there is an error, yada renegotiates the representation. So your 500 response can declare it only response with text/plain, while your 200 responds with XML and JSON

malcolmsparks08:06:23

there's no obligation for your error responses to support the same media-types, etc. as your 200 response

jonathanj08:06:04

That’s true but it’s a bit rude, for example I don’t think SOAP actually allows that.

malcolmsparks08:06:35

Why is it rude?

malcolmsparks08:06:00

The client is saying 'I'm happy with JSON, XML and text/plain', so it gets what it's asking for

malcolmsparks08:06:30

If you client is saying 'I'm only happy with JSON', then yes, you have to support a JSON-formatted error

jonathanj08:06:48

If the client says it’s happy with JSON and XML but not plain text then your 500 response that is only available in plaintext is invalid or what?

malcolmsparks08:06:59

but mostly these will be similar for every resource in that case and you can weave them in to all your resources - this is the reason resources are described in data

malcolmsparks08:06:44

Yes, if your error code can only produce plaintext, then you'd get a 406 situation in that case

jonathanj08:06:54

I guess this would actually be specified in your API, so a request of that fashion would be a fault of the client’s.

malcolmsparks08:06:29

The question is, would you produce a 406 or a 500?

malcolmsparks08:06:47

I'm not aware of any substantial advice in the RFCs for this situation

malcolmsparks08:06:18

I think a 500 without a message body would be the right thing to do, you shouldn't reasonably be able to recover from a 500

malcolmsparks08:06:47

I think if you're writing a public API for general consumption you should try to support a reasonable number of media-types and should expect that clients know how to cope with plaintext as a fallback.

malcolmsparks08:06:17

If it's an error and they insist on JSON only, just don't return anything besides the error code.

jonathanj10:06:48

@malcolmsparks: That seems like good advice, thanks.

statonjr12:06:18

RFC 7231, Section 5.3.2 says that servers can reply with 406 (Not Acceptable) or disregard the Accept header and send whatever it wants. We typically use the application/vnd.error+json media type for error messages, so we send that in the message body.

jonathanj16:06:00

I can’t seem to find the part in the manual that explains how to capture path parameters.

jonathanj16:06:57

I’m trying to match a path like /notices/:domain, so I have a route like

[“/notices/“ [[“” global-notices] [“:domain” domain-notices]]]

jonathanj16:06:19

If I visit /notices/ then I see my global-notices resource, if I visit /notices/arst then I get an exception:

java.lang.IllegalArgumentException: cannot treat nil as HTTP response for request to '’

jonathanj16:06:37

And I have no idea what this exception is trying to tell me.

jonathanj16:06:18

If I change the route from ”:domain” to ”domain”, then I can visit /notices/domain (literally) and see the resource I was expecting, but obviously no path parameter is being captured.

jonathanj16:06:42

Oh, it needs to be [[:domain] domain-notices].

malcolmsparks17:06:26

Yes. It's bidi. A lone keyword means something different: a method match

malcolmsparks17:06:05

Which is one thing I dislike about Compojure (matching methods) I wish the bidi author hadn't copied that

malcolmsparks17:06:43

@jonathanj: this isn't going to excuse the bad error message but it's one that aleph emits when you return nil as a response, which is what is returned from the bidi matching process. I can't think of a reasonable way to avoid that error other than telling everyone to back stop their route structures with a catch all: [true (yada/handler nil)]