Fork me on GitHub
#liberator
<
2017-04-04
>
ordnungswidrig15:04:02

This should work: ((resource “hello-world”) {:request-method :get})

ordnungswidrig15:04:29

Parametrized resources accept the parameters as function arguments and return an actual handler function.

ordnungswidrig15:04:40

@ejelome ^^ got you an answer. see above.

bostonaholic16:04:07

@ejelome 2 things. 1) I think testing defresource directly isn’t valuable. My opinion. defresource is already tested within liberator’s source code. 2) If you still feel like you need to test it, just check out liberator’s test suite on how to do it. https://github.com/clojure-liberator/liberator/blob/master/test/test_defresource.clj

caio16:04:12

probably an e2e test would be better in these cases

ordnungswidrig16:04:44

I had the impression that the OP simply wanted to test his resource and struggled with how parameters would be passed. That's a valid and proper test. OP might have simplified for the sake of example I guess.

ordnungswidrig19:04:20

Regarding the detailed messages: the server returns an error if the username was already taken. But this could be the case when a user tried to register the first time or when he/she wants to change the username.

ordnungswidrig19:04:03

For the server it’s the same operation, e.g. PUT /users/ordnungswidrig/name but you want to show different error messages to the user.

ordnungswidrig19:04:47

I had good experience with a server returning a keyword for the error, e.g. :username-conflict and the client uses a dictionary to lookup an appropriate error message depending on the interaction.

urzds19:04:58

That's kind of what I am trying to do.

urzds19:04:05

Actually exactly

urzds19:04:25

But I want to check all errors that leave Liberator to adhere to a schema. And as a bonus, I would like to make it easy to find the source of :username-conflict, i.e. where in the code it was emitted.

ordnungswidrig19:04:38

there’s grep for that 🙂

urzds19:04:51

(I'm also passing all non-error data through functions in :handle-ok, to make sure they also conform to the spec.)

urzds19:04:14

Hm, I guess I could pass :error/username-conflict and just check whether the namespace is error, to guarantee that the grepping will not become too difficult...

ordnungswidrig19:04:47

yes, namespaced keywords is the way to go

urzds19:04:54

How are people with really large code bases and different teams working on API and UI doing this? I.e. they have to pass around some kind of documentation...

ordnungswidrig19:04:49

well, my personal take on this is to stick with the ideas behind REST. One important constraint is that the only documentation is the description of the media types of the resources. This includes the semantics, error cases etc.

urzds19:04:06

On another topic: @ordnungswidrig Do you have an answer to https://github.com/clojure-liberator/liberator/issues/237#issuecomment-287816541 ? I.e. how to do API documentation with Liberator without Swagger?

ordnungswidrig19:04:09

That must be sufficient for a well formed user facing client to reason about the system.

ordnungswidrig19:04:48

Oh you meant that example? No I did not came up with one.

ordnungswidrig19:04:45

This very much depends on the actual usecase, but people nowadays use HAL, Collection+JSON etc. as the underlying media types and there is documentation tooling support for these.

urzds19:04:46

My knowledge of the terms you used was also too small to fully grasp what you propose as an alternative.

ordnungswidrig19:04:20

So in recent projects we used application/edn and clojure.spec specification for the interop. The resources linked to each other and the links used a well defined set of relations, e.g. “child”, “parent”, “authorization”

urzds19:04:28

media type, hypermedia, resource deployment (you refer to (defresource)?), the relation delete, again media types, ...

ordnungswidrig19:04:09

HAL http://stateless.co/hal_specification.html might be a good start on the ideas of hypermedia.

urzds19:04:37

The wikipedia definition of hypermedia, e.g., was rather confusing in this context: https://en.wikipedia.org/wiki/Hypermedia

ordnungswidrig19:04:59

yes, it’s data pointing to other data 🙂

ordnungswidrig19:04:31

Important is that if you have a, say a resource of type “order” that links to a resource “xyz” and the link is qualified as the relation “payment” that you have documented what this relation means for a resource of type “order”.

urzds19:04:41

Thanks for the link.

ordnungswidrig19:04:05

And what is the expected semantics when you POST or DELETE to that link. (e.g. “initiate paymen” and “cancel payment” or “refund payment”)

ordnungswidrig19:04:34

That’s only documented for the resource types, not for a particular URI. This is a main difference to the RPC based API descriptors like swagger.

urzds19:04:47

Thanks a lot for all that input. I'll read and then chart a new course taking into account all that new data 🙂

ordnungswidrig19:04:00

One step after the other 🙂

urzds19:04:15

omg, clojure is soooo awesome:

clj
(defn error-namespace? [s]
  (= (namespace s) "error"))
...
(s/constrained s/Keyword error-namespace?)
This is actually enough to check my error codes... Incredible...

urzds20:04:05

I start with an extremely elaborate and thought through way of managing error codes, that only involves a registry and some macros and namespaces and ... And I end up with (basically) a one-liner.