Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested Resources? #19

Open
oladon opened this issue Feb 5, 2020 · 4 comments
Open

Nested Resources? #19

oladon opened this issue Feb 5, 2020 · 4 comments

Comments

@oladon
Copy link

oladon commented Feb 5, 2020

Hi João!

I like the premise of Snooze — nice work! I've run into a bit of a snag, though...

Say I have the resource "dogs". I want to support:

GET /dogs/4 (get a dog by ID)
POST /dogs (make a new dog)

When I try to do that with Snooze:

(defroute dogs (:get :text/html id)
  "Retrieve a dog by ID")

(defroute dogs (:post :text/plain)
  "Make a new dog.")

... Lisp complains (with good cause) because the number of arguments differ between the two methods.

I've looked through the docs and can't seem to find anything to support this use case. I've also tried specializing the defroute method on a null argument, but that doesn't seem to get passed along to defmethod correctly.

Could you help me understand what I'm missing?

@oladon
Copy link
Author

oladon commented Feb 5, 2020

Nevermind — I realized I can accomplish this using &optional parameters, of course. :)

@oladon oladon closed this as completed Feb 5, 2020
@oladon
Copy link
Author

oladon commented Jan 18, 2021

Well, I'm back... :)

I'm hoping for some design help. I've read through this issue, and it seems like what I'm wanting should be doable, but I'm not sure the best way to go about it.

So as mentioned previously, I want to enable nested resources, like so:

GET /dogs
GET /dogs?breed=malinois
POST /dogs
GET /dogs/1 (i.e. /dogs/:id)
POST /dogs/1/foo

I'd previously closed this because designating parameters as optional solves part of this... but only if there are no query parameters allowed, because you can't have both &optional and &key. I can't seem to figure out a way to support this using Snooze.

Do any suggestions come to mind?

@oladon oladon reopened this Jan 18, 2021
@BenedictHW
Copy link

I'm a beginner who was also wondering about this. I had to look back to Practical Common Lisp's section on 'Mixing Different Parameter Types' . It gave the design advice to not mix &optional and &key, for keywords can be mistaken as optional parameters. I suppose if we included an identifier while passing &optional arguments we would have re-invented keywords. Hence Seibel's later design recommendation to convert &optional to &key as the solution.

I'm also not creative enough to see a way for Snooze to support this mixture without also replicating the surprising behaviour. And to do so while remaining faithful to CL semantics. Not very helpful, but nonetheless I hope that helped.

Been loving snooze, thanks Joao.

@hyotang666
Copy link

I use URI-TO-ARGUMENTS for such things as below.

(defresource dogs (http-method content-type &key))

(defroute dogs (:get :text/html &key id nested)
  "Retrieve a dog by ID" 
  (cond
    (nested :nested)
    (id :id)
    (t :otherwise)))

(defroute dogs (:post :text/plain &key)
  "Make a new dog.")

(defmethod uri-to-arguments ((resource (eql #'dogs)) uri)
  (multiple-value-bind (plain-args keyword-args)
      (call-next-method)
    (values nil
	    (case (length plain-args)
	      (0 keyword-args)
	      (1 ; id
	       (pairlis '(:id) plain-args keyword-args))
	      (2 ; /:id/foo
	       (pairlis '(:id :nested) plain-args keyword-args))))))

Do not know the best way though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants