Fork me on GitHub
#yada
<
2017-03-24
>
dominicm12:03:15

@korny feel free to just use edge 😉

korny12:03:24

Hey folks - I'm looking at making a really simple hacky json API for an internal company hackathon - it doesn't need to do much at all beyond accepting POSTS with json payloads and return JSON responses. I'd like to keep my example really simple, along the lines of a Sinatra app. What's the minimum to do this in Yada/Bidi?

dominicm12:03:31

boilerplate for yada is prtty small, yada/listener covers the bulk.

dominicm12:03:57

(yada/resource
  {:methods
    {:post {:response "application/json" :accepts "application/json" :response (fn [ctx] {:hello "world"})}})
is the resource

korny12:03:06

It feels like the docs jump straight from "here's a sample with no routes" to git clone edge 🙂

dominicm12:03:08

& it will handle content negotiation & failure if clients ask for edn or somewhat

dominicm12:03:24

yada doesn't handle routes, period. bidi docs should cover that for you though 🙂

malcolmsparks12:03:19

@korny noted. Good feedback!

korny12:03:28

@dominicm I get that - but that's not particularly a great demo for me to say "hey, this is as easy as your Sinatra example. Oh, hang on, you need to look at this other projects for routes" 🙂

korny12:03:04

I should say I like the separation between the two. And "being like Sinatra" isn't a goal for yada!

malcolmsparks12:03:06

yada depends on bidi

malcolmsparks12:03:27

So you just need to depend on yada

dominicm12:03:39

ah, megayada.

malcolmsparks12:03:08

Architecturally they are separate libs but yada 'know' about bidi and provides some extra features if it's present

korny12:03:30

I suspect I'll just git clone edge then delete all the bits I don't want. I'm just lazy and hoped someone else had already done this 🙂

korny12:03:41

s/lazy/baby-driven-sleep-deprived/g

malcolmsparks12:03:18

The ext mechanism means you can have a yada which eliminates bidi completely. But that's just a technical point. Yada 'full' comes batteries included with bidi. Fine for hackathons.

malcolmsparks12:03:25

Edge is intended to show 'full stack' including the great adzerk cljs reloading and browser repl figwheel-style experience

malcolmsparks12:03:41

Overkill for a sinatra-like backend

malcolmsparks12:03:44

@korny I was trying to find the emoji for 'I know the feeling' but then Bruce came up

korny12:03:00

bruce embraces all human feelings

dominicm12:03:04

I have something like that locally, but I added stuff to it 😛

dominicm12:03:20

I feel a boot-new template coming on 😄

malcolmsparks12:03:20

So cool that someone made an emoji for Bruce!

dominicm12:03:33

I'm submitting it to the Unicode Standard to be in v9

malcolmsparks12:03:53

Yeah. The Edge thing is great for full stack (needs a db layer though)

malcolmsparks12:03:10

But would be great to have a stripped down version

malcolmsparks12:03:19

It would be a lot simpler

snorremd13:03:48

@dominicm Does Yada really handle content negotiation? I tried to coerce a 406 Not Acceptable out of Yada by sending a request with a Accept: application/edn header to a resource which only produced json i.e. :produces "application/json". The only thing Yada checked as far as I could tell was that the request body was on the accept-format specified in the resource.

snorremd13:03:39

I ended up creating my own interceptor to handle 406 responses. Edit: Would be nice to not have to do that.

malcolmsparks13:03:44

If you only produce EDN but the client asks for JSON it's a 406

malcolmsparks13:03:54

Yada supports content negotiation.

malcolmsparks13:03:12

(Took me a whole summer to implement properly)

snorremd13:03:54

Well, I'l be damned if it does not work without my interceptor. I must have missed something when testing this earlier on. Thank you both for the clarification.

dominicm13:03:20

deleting code is the best pr

grav20:03:15

Can I somehow do a “server-side” redirect instead of returning 302 and letting the client do a new request?

grav20:03:41

In my case, I need all uri ending in “/” to redirect to the uri without the “/”. I could do a regex on all routes, but that seems a bit like a lot of local fixes to a global problem

grav21:03:08

A 302 is a global solution, but that won’t work behind a proxy

dominicm21:03:29

What is a server-side redirect?

grav21:03:53

Hmm, well, a redirect that the server (yada) takes care of, eg it does not involve the client. So it’s a kind of an alias of a uri

grav21:03:40

Server-side is probably not the correct frase

dominicm21:03:19

Ah, okay. Multiple routes for the same resource?

dominicm21:03:26

Redirect made me think 30{2,1}

grav21:03:06

Yes, exactly. 30x was what I’m using, but that gives me trouble with nginx.

dominicm21:03:08

Why's that :thinking_face:

grav21:03:00

Well, my service is serving stuff like /some-resource, but that gets prepended with /api/some-resource by nginx.

grav21:03:56

So only nginx know the correct “full” path from the client’s point of view.

grav21:03:30

Of course, nginx could do a redirect instead. Which might be the way to solve it.

dominicm21:03:10

ah, hadn't ever considered that. Surprised nginx can't prepend onto that sort of thing.

grav21:03:55

There’s probably a way to do what I want with nginx. But it’s more fun to solve in clojure 😉

grav21:03:07

But is there a way to do multiple routes for the same resource in some global way?

dominicm21:03:24

I mean, this will be a bidi solution I think.

dominicm21:03:16

The simplest way I can think of is a function which takes the "pattern" and doubles it up:

(defn double-vision
  [pattern]
  #{pattern (concat pattern ["/"])})

dominicm21:03:16

Might need to handle non-nested too, something like:

(if-not (sequential? pattern)
  (vector pattern)
  pattern)

grav21:03:28

Cool, I think I understand that. I’ll try it out!

dominicm21:03:28

Basically, it will take this: [(double-vision ["/some-resource"]) (fn [req] …)] and generate [#{["/some-resource"] ["/some-resource" "/"} (fn [req] …)]

dominicm21:03:03

You probably want (double-vision "/some-resource") to work too though. So that's why you might add a sequential? check.

dominicm21:03:08

Maybe even vector?