This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-09-01
Channels
- # admin-announcements (1)
- # aws (1)
- # beginners (14)
- # boot (19)
- # cljs-dev (10)
- # cljsrn (2)
- # clojure (64)
- # clojure-android (4)
- # clojure-dev (5)
- # clojure-greece (7)
- # clojure-italy (10)
- # clojure-russia (42)
- # clojure-spec (117)
- # clojure-uk (78)
- # clojurescript (160)
- # cloverage (1)
- # conf-proposals (1)
- # cursive (8)
- # datomic (93)
- # editors (8)
- # editors-rus (5)
- # figwheel (1)
- # flambo (14)
- # hoplon (95)
- # jobs (2)
- # jobs-rus (1)
- # lambdaisland (4)
- # lein-figwheel (6)
- # leiningen (3)
- # om (106)
- # onyx (33)
- # planck (6)
- # proton (3)
- # protorepl (2)
- # random (2)
- # re-frame (9)
- # reagent (5)
- # ring (1)
- # untangled (61)
- # yada (50)
I’m curious how a resource in yada and/or strict RESTful approach would conceptually have more than one POST actions for a resource. For example take an imaginary API for cloud resources. All endpoints should take 1-n resource uuids as args.
Option 1: POST takes multiple :fn/:args messages.
POST /instance
- Start
- Stop
- Restart
Option 2: Multiple urls
POST /instance/start
POST /instance/stop
POST /instance/restart
Option 3: More CQRS actions endpoint
POST /action :fn/:args message
Trouble with Options 1 and 3 is both have variable messages making the request/response dispatch on type and would be ambiguous potentially. You’d probably lose the benefit of swagger there too. Problem with Option 2 feels more verbose and seems to fly in the face of endpoint as resource location with multiple verbs. I’d love to hear the yada perspective on something like this! Cheers!@kingoftheknoll: In REST, verbs are discouraged. Resources are nouns. POST /instances returns 201 Location /instances/af4b3c. Shutdown that instance with DELETE /instances/af4b3c
Your suggestion seems a bit like RPC which is creating a bespoke API. One of the REST constraints is a common API
@lmergen Option 3 would be a message in the body. @malcolmsparks resources as nouns makes great sense however, using HTTP methods as verbs acting on a resource doesn’t work once you have 15+ actions to can take on it. Thus you’re only given two choices to increase specificity 1) put the action type in body or 2) specify in the url.
Hey there! How do I start up a yada-based web service from command line? I can do it from my repl, but not from command line without the service exiting again. I’m using leiningen
From the repl, I do
(yada/listener [“/endpoint” (yada/resource {:produces “text/plain” :response (fn [ctx] “hello world”)})])
@grav: add a @(promise)
after you start the server
@grav this is due to a recent(ish) update in aleph. You should use wait-for-close
https://github.com/ztellman/aleph/issues/265#issuecomment-237705049
Yes, I agree
@malcolmsparks I'm updating an old project and I think I need to replace the old yada.bidi/partial
:authorization
with a method of yada.authorization/validate
. The problem is that I get an error when I try to return {:status 403}
. Am I supposed to return something else?
Oh wait... I think I need to use ex-info
https://github.com/juxt/yada/blob/b9cc97d0e73dd46e962bb51fff83a62c5a18f1fe/src/yada/authorization.clj#L46
Is there a way to make the swagger UI show the endpoints in order of path length, or is that something completely out of yada's reach?
i'd prefer them in the same order as my bidi routes @frozenlock
Yeah... in my case they are both the same 😛
@frozenlock are you returning the response, i.e. (:response ctx)
- if you just return a map yada will treat it as data
@frozenlock thanks for the hint re: .wait-for-close
. But it seems to be an 0.4.2-alpha6
feature, according to the github link. Is there a method that works with 0.4.1
? Would that be @(promise)
, as suggested by @malcolmsparks?
@lmergen I can’t change the fact that I have many actions. So I made the suggestion that I make multiple ‘resources’ but then that breaks convention with endpoints being nouns. The only way to do this in a true REST manner it seems would be to invent my own methods in addition to GET PUT POST DELETE
which of course is silly. I think it comes down to a strict RESTful interface doesn’t work if your interface is any more complicated than CRUD.
I am trying to create a WFS endpoint for a Geoserver. The Geoserver sends accept header "accept: *; q=.2”
which seems to crash yada. Any hints?
@kingoftheknoll: in that case I would probably settle with a POST and put a {"action": "create"} in the body or something like that
@lmergen I think that’s what I like but with Yada can I make is so swagger knows about multiple message types. Those actions might have different message bodies
it gets tricky, as soon as you start doing complicated stuff such as optionals and enums/sets the documentation starts to get weird.
that’s why I keep going back to multiple endpoints. I mean when I comes down to it, the goal is to auto generate these endpoints for customers and documentation. However internally I’m going to have a single endpoint that takes any action message.
which comes to another question, can I skip swagger validation on some endpoints
yes but while that is an idea, you should try sticking to rest as close as possible. so DELETE /instance/:id and not POST /instance/:id/delete. POST /instance/:id/restart is fine though.
Another thing that’s tough is the requirements that all actions take a list of :ids to work on. I’m never guaranteed to be working with one resource. So the conceptual metaphor weakens.
So the lesser of all evils would be to have POST endpoints for all actions that take a list of ids.
That way I can spec all messages with swagger
you must start considering your set as a representation of resources. it is not the set you are modifying, it is each one of these resources. as such, your set should filter the resources as a parameter.
and then assuming you’d specify PUT /instances/restart?ids=2,3,4
for other actions
I could see you killing the max length of a url though pretty quick
btw, I just thought about http's Range field, which would be a great fit for resource collections.
anyway I think you just have a problem that your actions don't map to REST in a sensible way. I would suggest mapping these actions as fields of a resource, so POST /instance/:id/restart, or POST /instances/restart, and I think I would use the Range header.
@lmergen Thanks for taking the time to chat with me! I'll check that out and I really appreciate the insight!
Seems “*”
in accept header crashes yada 1.1.31. I’ve created an issue here: https://github.com/juxt/yada/issues/120
Of course it’s not that easy, since it could be “*; q=0.2"
or similar. That’s what Geoserver sends me...
@kingoftheknoll: no problem! it's an annoying problem with many possible solutions, so I would suggest you just choose one that seems right to you. be careful about some of the implied semantics of the http methods such as PUT, though.
Totally, thanks so much