Fork me on GitHub
#yada
<
2016-08-17
>
kurt-yagram06:08:51

when I want to return another http status (and body) from the response-function, is throwing an exception the best way to do that? Now, I have something like:

(defn response ""
  [ctx]
  (let [pars (:parameters ctx)]
    (if (spec/valid ::pars-spec pars)
      {...}
      (throw (ex-info "Invalid parameters" {:status 400 :error ...})))))

kurt-yagram06:08:59

... it should be spec/valid? (with a question mark)

dominicm07:08:59

It's a way to do it. You can also:

(assoc ctx :response
                       {:status 200
                        :body "content"})

kurt-yagram07:08:03

This makes more sense. I don't like throwing exceptions 'everywhere'.

malcolmsparks07:08:20

@dominicm: that will nullify any response headers set. Better to (assoc (:response ctx) :status 200 :body "content")

kurt-yagram07:08:55

allright, thx!

kurt-yagram11:08:41

... doesn't seem to work as expected. When I change

(throw (ex-info "Invalid parameters" {:status 400 :error ...}))
with
(assoc (:response ctx)
               :status 400
               :error ...
               :body "Invalid profile data")
I get response code 0 (response body: no content). If I add ctx as return value, I get response code 204 (response body: no content).

malcolmsparks11:08:39

what method are you using, I'll check the code

malcolmsparks11:08:36

If it isn't working I'd like to understand why

malcolmsparks11:08:26

@kurt-yagram: can you share a bit more code that will reveal the method name you're using? perhaps the whole resource model would help

malcolmsparks11:08:34

you definitely should not be getting status of 0

kurt-yagram11:08:56

yeah, just a sec... I'll post the code and remove irrelevant parts

malcolmsparks11:08:45

np - take your time. I'm sure it's something I can help with - if there's a bug in yada I can fix that too -although lots of people use the explicit response feature so I'm fairly surprised it isn't working for you. I'll do my best to help

malcolmsparks11:08:44

@kurt-yagram: is it really 4.25am for you there?

malcolmsparks11:08:06

i like your profile picture - is that a recent photo? if so, might explain why you're up at 4.25 🙂

kurt-yagram11:08:14

euh, no, it's 1.26 pm - lol, but yes, photo is recent. Does it show 4.26 am? slack tells me it's 1.26 pm

malcolmsparks11:08:20

that code looks fine to me, i'm going to try to replicate here

malcolmsparks11:08:41

yeah, but slack is very fallible 🙂

kurt-yagram11:08:42

well, I'm using swagger ui, so I don't know if it could be a swagger/swagger-ui thing or not. It works with throwing exceptions...

malcolmsparks11:08:49

Ah, that might explain it. Try using curl or postman too, so you can distinguish between whether it's a yada thing or swagger-ui thing - I've seen swagger ui report status as 0 when it isn't

malcolmsparks11:08:56

swagger-ui is a nice, but complex beast

kurt-yagram11:08:22

ah, ok... will try 🙂

kurt-yagram11:08:13

that looks different... I do get the response body... How do I get the http status from curl?

kurt-yagram11:08:25

got it: add -w %{http_code}

kurt-yagram11:08:37

seems to be a swagger ui thing.

malcolmsparks11:08:29

it will show the status and all the response headers

kurt-yagram11:08:59

that's what I was looking for, thx !

kurt-yagram11:08:22

so, curl works fine... it's swagger-ui that has issues with the response

malcolmsparks11:08:29

curl -v will show the request stuff too, fyi

malcolmsparks11:08:38

what's the response code - is it a 400?

kurt-yagram11:08:04

so yes, it works fine...

malcolmsparks11:08:12

is the response body and content-type aligned?

malcolmsparks11:08:36

maybe swagger-ui is trying to parse the response body and failing - mind you, this is something yada tries to get right for you

kurt-yagram11:08:41

well, I first should make the body a little more like a map 🙂

kurt-yagram11:08:54

now it's just a string

malcolmsparks11:08:49

your PUT code is working for me, but...

malcolmsparks11:08:15

`(assoc (:response ctx) {:status 400 :body "Invalid profile data"}`

kurt-yagram11:08:25

yeah, that's wrong

malcolmsparks11:08:34

that's wrong - you either need 'merge' there, or remove the curlies

kurt-yagram11:08:36

fixed that part 🙂

kurt-yagram11:08:41

removed the curlies

dominicm11:08:53

That's my fault, oops

dominicm11:08:13

I may have accidentally read that from pedestal docs instead of yada docs...

kurt-yagram11:08:48

ok, and now, if I make the body a map instead of a string, it works in swagger-ui as well

malcolmsparks11:08:51

@dominicm: not sure that 747 issue is relevant here but I could be wrong

kurt-yagram11:08:16

how easy life can be

dominicm11:08:47

@malcolmsparks: If swagger is trying to parse a JSON object and failing, could that cause it? Because "Invalid profile data" is invalid JSON

kurt-yagram11:08:57

Yes, that's it

dominicm11:08:47

That's what 747 goes into.

kurt-yagram11:08:48

That's why swagger-ui couldn't handle the response - which makes perfect sense. My application didn't do what it promised 😛.

malcolmsparks11:08:51

typically what you do when you've got multiple possible content-types, is you ask yada which content-type was negotiated - with (yada/content-type ctx)

malcolmsparks11:08:22

then you switch on the result - say if it's text/html you can proceed to return a string, but if it's application/json you need to return a map (any value you do return will be coerced into JSON)

dominicm11:08:07

That reminds me I need to do my template-record hybrid thing, which becomes JSON on demand

malcolmsparks11:08:30

yada does all the content-negotiation for you, so by the time you get to decide the body, you already know what content-type to produce. That's one of the really big things yada offers over pedestal and others

malcolmsparks11:08:03

liberator does conneg, but it's a bit more primitive and doesn't do all the content axes

malcolmsparks11:08:35

most of my API services emit application/json and application/edn by default

kurt-yagram11:08:08

well, now I'm busy here: if I want to use declared responses: do I understand it well that if I return just an integer (e.g. 400) and in my yada/resource map I add a :responses key, I can put the assoc-part inside that function? - Well, I just try 😛

malcolmsparks11:08:20

See the docs, chapter 10

kurt-yagram11:08:44

yeah, I was looking at them.

vinnyataide20:08:18

hello I checked out the local tutorial, but with all that tooling I'm overwhelmed by how can I setup yada with my simple resource project, no need for reload or anything, just a simple webserver...

vinnyataide20:08:20

I tried with a ring middleware but couldnt make it work

vinnyataide20:08:17

I think it's something about the run-jetty function that doesnt seem to work with yada

vinnyataide20:08:36

aw sorry man, I couldnt figure how to pass after point 3 then I came here

vinnyataide20:08:15

maybe a little bit of reindexing the manual could help the newcomers, but I know that I shouldve keep reading, thanks, gonna try it now

malcolmsparks20:08:26

you can't run yada with run-jetty because it's asynchronous - that's why you have to use aleph which supports it

malcolmsparks20:08:09

it's possible to write an adaptor which could deref the response, but doing so with defeat the point of yada being asynchronous in the first place

vinnyataide20:08:13

@malcolmsparks: that's more than clear, I'm now on the track

vinnyataide20:08:44

yeah, I didn't know anything about java servers, since I'm a node dev

malcolmsparks20:08:56

thanks for the feedback on the docs, I'm working hard on improving them and making them more complete - but yes, some reindexing would help

malcolmsparks20:08:31

in a sense, as a node dev you'll be more familiar with the yada mode of operation than Ring, because in yada everything is async

vinnyataide20:08:54

cool, that's what made me choose, now I know a little more about the underparts

malcolmsparks20:08:20

there's a bit of a debate in the clojure/jvm world about whether async is overkill - of course in nodejs there's nothing but async because you can't have multiple threads

vinnyataide20:08:21

it's strange since ring is the defacto server solution for clojure

malcolmsparks20:08:25

I wrote a blog article a couple of months back that touches on these points: https://juxt.pro/blog/posts/yada-2.html

malcolmsparks20:08:03

but yes, Ring is definitely the de-facto approach

vinnyataide20:08:12

I don't think that it's overkill... If you need more control you can use threads, but async operations in the request response need to be as fast as possible

vinnyataide20:08:17

hence the node popularity

vinnyataide20:08:30

gonna read it later

vinnyataide20:08:56

congratulations on the lib, it's a really breath for async programmers to work

malcolmsparks20:08:14

thanks - i'll continue to invest in improving the docs, especially for beginners.

vinnyataide20:08:02

giving my 2cent, today's everyday little business solution needs much more speed in the I/O than in proccess handling... IDK about other peoples vision since I'm solely invested in web development

vinnyataide21:08:54

the server is working perfectly