Fork me on GitHub
#yada
<
2016-10-04
>
kurt-yagram08:10:18

my (yada) api roughly looks like this:

["/"
  {"v1" (swaggered ... 
         ["/" {...}
          {:info {...}
            :tags {...}
            :basePath "/v1"})
   "swagger/with-jwt.html (yada (io/resources "swagger/with-jwt.html"))
   "swagger (yada (new-webjar-resource "swagger-ui"))
   "status" (yada {:status ok :version (read-version)})}]))
This works fine when run locally. However, when I put on a remote server, /v1 works, and /status as well, but /swagger or /swagger/with-jwt.html gives this:
java.lang.IllegalArgumentException: cannot treat nil as HTTP response for request to ''
	at aleph.http.server$invalid_value_response.invokeStatic(server.clj:133)
	at aleph.http.server$invalid_value_response.invoke(server.clj:130)
	at aleph.http.server$handle_request$fn__16419$fn__16420.invoke(server.clj:186)
  ...
I'm missing something here (again). It seems that the webjar resource is somehow not found?

dominicm08:10:09

@kurt-yagram Does it happen in an uberjar locally? Might help figure out the difference between remote and local. Also, you could try print the webjar resource more directly on startup, figure out if it's bidi or -

dominicm08:10:51

> (io/resources "swagger/with-jwt.html") http://clojuredocs.org/clojure.java.io/resource I think this is wrong. Probably not nil though.

kurt-yagram08:10:21

yeah, that's what I don't understand. It works locally... weird.

kurt-yagram08:10:06

I do have the html file:

$ ls resources/swagger/
mumtobe.html
so that's not the problem. I think it's more about the webjar. But I can't find it 😛.

dominicm08:10:32

Sorry, I meant. There's an s on the end.

dominicm08:10:51

Possibly just copy/paste mistake though.

dominicm09:10:27

Well worth trying to print out the resource when the application starts, see if it's yada acting strange on the server, or your application in general.

kurt-yagram09:10:52

hmmm, it's nginx something... when I run localhost:3000/swagger/with-jwt.html remotely, it does work fine. When I try to access via browser (on curl on my local pc), i.e. with nginx as reverse proxy, it returns the nil-thing - by the way, is there a way to show a nicer message when the requested resource is nil?.

dominicm09:10:10

I wonder if yada is getting hit with a slightly different url or something. No idea what it could be really.

dominicm09:10:35

I'm not sure how to do it exactly. I think the trick is walking over your resources. But, unsure.

kurt-yagram09:10:59

well, it's probably nginx config. will have to check that

kurt-yagram09:10:56

dunno what was wrong. 2 nginx restarts, and a few browser refreshes and it all works fine.

dominicm10:10:28

¯\(ツ)/¯

dominicm10:10:35

Also, slack has a /shrug command. TIL

stijn12:10:30

I'm getting clojure.lang.ExceptionInfo: Context does not contain a :uri-info entry when calling path-for on a ctx

stijn12:10:02

I've searched edge and yada repos for uri-info, but I don't see where this gets set or what I should do to have it set

stijn12:10:51

how does it resolve the path?

stijn12:10:57

previously I was keeping my routes in an atom and once constructed dereference it and call bidi/path-for on it

stijn12:10:25

but how should the yada ctx know about my bidi routes?

malcolmsparks12:10:53

@stijn Hi there - what's your current bidi/yada version?

malcolmsparks12:10:52

Here's what's going on - bidi's bidi.vhosts/find-handler is the function involved. Bidi 2.0.12 switched from uri-for to uri-info. It was just too confusing that uri-for returned a map, so I've renamed to uri-info

malcolmsparks12:10:25

The latest yada (1.1.37) picks up this new version of bidi.

malcolmsparks12:10:50

So if you've upgraded yada, make sure you're not overriding the version of bidi

stijn12:10:10

yes, yada "1.1.37"

stijn12:10:20

and for bidi I have no explicit dependency

stijn12:10:32

oh, so I should wrap my routes in bidi.vhosts/vhosts-model ?

malcolmsparks12:10:30

@stijn - yes, if you're using yada's uri-for, because forming urls to routes, yada needs to be able generate absolute uris in many cases (Location headers), so the idea is that you use bidi's vhosts support if you use yada, and yada/server does this

malcolmsparks12:10:57

it's an area that's been stabilizing these last few weeks, so sorry for the breakage

malcolmsparks12:10:39

I assume that people who upgrade to later versions are happy with some upgrade pain, but I've found that people are upgrading very quickly these days (partially thanks to things like lein-ancient).

malcolmsparks12:10:21

That's created more of an onus on library developers to maintain strict compatibility between versions, I try to do that in general but sometimes it's nice to hide behind a library version

stijn12:10:43

@malcolmsparks no worries about breakages, i'm finally upgrading from pre-1.1, so this is like a minor update 😄

stijn12:10:35

I understand the use case of Location headers e.a. but our backend currently doesn't really care how requests come in. We have 2 domains routing to the same REST API.

stijn12:10:11

does yada determine the uri-info on the incoming request domain, or do I have to list up all the vhosts as a 'synonymous vhost' in bidi?

malcolmsparks12:10:23

you need to list all the vhosts (currently)

malcolmsparks12:10:19

happy to discuss future functionality

stijn13:10:32

ok, does it make sense to detect uri from incoming requests? because we are currently not using any vhosts and everything that gets routed to the API (load balancer traffic, but also inter-machine traffic that's routed differently) will get a response served.

stijn13:10:12

ha! it works. this is really cool 🙂

dominicm13:10:34

It would probably make more sense to backport the uri-for change to the main part of bidi, and cut down the bidi.vhosts namespace a little.

lmergen13:10:31

btw, lately i’m thoroughly considering making a complete ‘bidirectional’ interface on top of yada, but i’m not sure whether that’s a good idea

lmergen13:10:16

we have quite a few yada microservices over here, and they all have their ‘interface’ in a thousand http/get statements

lmergen13:10:39

i would love to be able to use uri-for to generate urls between loosely connected services

dominicm13:10:26

Hmm, Martian might interest you

lmergen13:10:05

that’s an appropriate name for these architecture-astronaut features

dominicm13:10:13

I only just got it

lmergen13:10:19

it’s exactly what i had in mind

lmergen13:10:49

but it uses swagger

dominicm13:10:55

Yeah 😞

lmergen13:10:58

personally i think swagger is too limited

lmergen13:10:08

i run into problems when i do s/either and things like that

dominicm13:10:20

Ah. Makes sense.

malcolmsparks15:10:25

@lmergen i'm a little hesitant to recommend a strategy of centralizing routes, although I'm interested in Martian (obviously) and what Oliy is doing with it

malcolmsparks15:10:37

My default position is that URIs should be discoverable from the services that provide them. So responses (especially those in JSON) should use bidi to construct links to other resources provided on the same server. That's why bidi was developed - to make this accurate and less error-prone

malcolmsparks15:10:13

However, centralising all URIs seems brittle to me. I think they feel a little too much like WSDL, CORBA Naming, etc.

malcolmsparks15:10:11

When you change URIs (and you inevitably do), you want your clients to work regardless. However, if you are in control of all clients and servers (as Oliy and his team are) then it seems perfectly fine to use a common model.

malcolmsparks15:10:58

But I think people should understand first the REST approach and how it can solve this problem (by hypermedia), before resorting to alternatives that are (even) less tried and tested

malcolmsparks15:10:02

To use an analogy, if you drive to a destination, should you take a (potentially out-of-date) road map, or follow road signs? What happens if there's a diversion or road block?

malcolmsparks15:10:18

To collapse the analogy, of course, you'd take a sat nav 🙂

malcolmsparks15:10:58

I think the rule of thumb here is that if you're developing services to support external users (public, or in other departments in your org), then you should think about longevity and how those users can use hypermedia to navigate change

malcolmsparks15:10:34

If you're in control of everything, then it's fine to use a central model. I think HTTP presumes the former but works perfectly well for the latter.

dominicm15:10:43

@malcolmsparks depends on the satnav. Satnav's road map might be outdated. It would be best if the satnav read the road signs around me, and figured out the new road map as I went ... 😉

lmergen15:10:51

i actually don’t think these approaches are as mutually exclusive. you can perfectly do both.

lmergen15:10:18

a government can supply both road maps and road signs

lmergen15:10:44

in the end, you want to reduce the amount of problems you have in production; increasing the understanding of the http client about the service it is talking to will only help this cause. also, doing everything purely in REST mostly works in theory, but not in practice (for example, implementing pagination is something that every dev shops seems to invent its own solution to) what are the real downsides, actually, of projects like Martian, other than the philosophy ?