ruby-grape / grape

An opinionated framework for creating REST-like APIs in Ruby.
http://www.ruby-grape.org
MIT License
9.88k stars 1.22k forks source link

Make parameters required or optional later #829

Open kuraga opened 9 years ago

kuraga commented 9 years ago

Good day! I have a suggestion. The next code illustrates it:

class API < Grape::API
  helpers do
    params :car do
      param :name, type: String # param is a synonim for optional
      param :desc, type: String
    end
  end

  params do
    use :car
    requires :name
    optional :desc
  end
  post do
     # Create a car. Name is required.
  end

  params do
    use :car
    optional :name, :desc
  end
  put do
     # Update the car. Nothing is required.
  end
end

UPD: Another example:

params do
  param :name, type: String # param is a synonim for optional
  param :desc, type: String
end
namespace :cars do
  params do
    requires :name
  end
  post do
    # name required, not desc
  end

  put do
    # name, desc are optional
  end
end

What's your opinion? Thanks.

dblock commented 9 years ago

Do you have a real world scenario for something like this that you'd like to share?

kuraga commented 9 years ago

Yes, and the code above contains it: 1) a car has many attributes, 2) when I create a car, I should receive some of them as parameters, 3) when I update a car, required parameters are else. And I don't want to code the list of parameters twice. Well it's just big, that's not DRY.

dblock commented 9 years ago

Yes, this makes sense. I wonder though whether the entire group should be made optional vs. required, so requires :car instead of :use. Another variation that seems like a more natural extension is to merge the params via use with a block, instead of set ..., I would definitely take a PR that accomplishes this:

use :car do
    requires :name
    optional :color
end
kuraga commented 9 years ago

@dblock thank you for response!

Well use way is just an example. I can (just) redefine mode later. See the (updated) second example in topic-start please.

dblock commented 9 years ago

Yep, I think overwriting parameters either way is a reasonable feature request. Maybe it already works? ;)

rodzyn commented 9 years ago

I went through some issues here and I saw a lot of them regarding parameters which led me to thinking about them a bit. Did you think about moving them to separate gem (some time ago you did it with entities - great work)?

However, it will be less in DSL style then. Quick example (could be totally different):

module API
  module Parameters
    class UserParams < Grape::Parameters
      parameter :first_name, require: true,
      parameter :last_name, require: -> (){}
      parameter :address do
        parameter :city, type: String, require: true
      end

    end
  end
end

post '/user' satisfy: API::Parameters::UserParams do
end

btw. Is there any Gitter room for grape to discuss such things?

kuraga commented 9 years ago

Yeah, OOP solution is a good idea! @dblock what do you think?

dblock commented 9 years ago

I don't have strong opinions, although I am always apprehensive about introducing new DSL language (eg. satisfy). I would want to just be able to say params API::Parameters::UserParams.

dsager commented 3 years ago

Has been a while :)

Is there any update on changing parameters to be required/optional later on? For us it's also a common use case when defining POST & PATCH endpoints. So far we just work around this with leaving the specific parameters out of the optional group and defining them explicitly via requires and optional, but I feel like such a mechanism would be more elegant...