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

Provide a generic interface for requires: complex type. #827

Open
dblock opened this issue Nov 28, 2014 · 17 comments
Open

Provide a generic interface for requires: complex type. #827

dblock opened this issue Nov 28, 2014 · 17 comments

Comments

@dblock
Copy link
Member

dblock commented Nov 28, 2014

http://pastebin.com/QQV0NJ5K

  # Entity
  module API
  module Entities
    class Article < Grape::Entity
      expose :title, documentation: { type: 'string', desc: 'Title' }
      expose :body, documentation: { type: 'string', desc: 'Body' }
    end
  end
end

  # API
  desc "Create an article"
  params do
    requires :article, type: API::Entities::Article, documentation: { example: "aklsdfj" }
  end
  post '/articles' do
    puts params
    article = Article.create(params(:title, :body))
    represent(article, env)
  end

Currently:

# curl -X POST -H "Content-Type:application/json" 0:9292/v1/articles -d '{"title":"hello","body":"world"}'  
# {"error":"article is missing"}
# curl -X POST -H "Content-Type:application/json" 0:9292/v1/articles -d '{"article":{"title":"hello","body":"world"}}'
# {"error":"article is invalid"}
@antonzhyliuk
Copy link

👍

1 similar comment
@dim
Copy link
Contributor

dim commented Jun 17, 2015

+1

@0x5d
Copy link

0x5d commented Jun 26, 2015

Acording to the documentation , it is supported (in a way, I guess).

@birbird
Copy link

birbird commented Jul 18, 2015

Hi, what's status of this issue?
I wrote something like

    params do
      requires :user, type: Entities::User
    end

But when I pass a user json as parameter, it throws {"error":"user is invalid"}

It the result expected or I made some mistake?

@dblock
Copy link
Member Author

dblock commented Jul 18, 2015

I believe #1039 has implemented this, @rnubel would you confirm and I'll close this issue? Is this any different from #993?

@dblock
Copy link
Member Author

dblock commented Jul 18, 2015

@birbird this is on HEAD FYI, not in any released version of Grape yet.

@dblock
Copy link
Member Author

dblock commented Jul 18, 2015

Maybe we need to do something built-in for Grape entities though ...

@birbird
Copy link

birbird commented Jul 18, 2015

@dblock Thanks a lot for you help.

Actually, before I asked, I have tried exactly the same code with https://github.com/intridea/grape#custom-types, which is also the sample code in #1039. But got the {"error":"color is invalid"} sadly.

All the things can be explained with your reminder.

A little suggestion, if this feature has not been released, it should not be in the document.

@birbird
Copy link

birbird commented Jul 18, 2015

But even with custom-types, Grape Entity still could not be processd.
custom-types require the input type is String, this is not the case for Entity.

@rnubel
Copy link
Contributor

rnubel commented Jul 18, 2015

Yeah, like @birbird noted, #1039 added support for custom primitive types (i.e., something that can be parsed from a single string parameter) whereas this story requires support for complex types. And actually, grape does have support for that already, but only when done through Virtus. It would certainly be possible to also support coercion into Grape::Entitys, but that's not existing functionality.

@guizmaii
Copy link

Is it possible to express required/optional parameters in entities ?

With a required: parameters ?
Does it fail if the title in not passed in the following example ?
Or is it just documentation ?

module API
  module Entities
    class Article < Grape::Entity
      expose :title, documentation: { type: 'string', desc: 'Title', required: true }
      expose :body, documentation: { type: 'string', desc: 'Body', required: false }
    end
  end
end

Can we express complex validations as with "normal" params ? ( https://github.com/intridea/grape/blob/v0.12.0/README.md#parameter-validation-and-coercion)

@atljeremy
Copy link

I'm also wondering the exact same thing as @guizmaii. I have a Grape Entity with some required attributes but if I only use the desc block with params set to my Entity's documentation there isn't any validation being done on the params when i make requests to the API for those resources. The only way I can get validation of the params is to also use the separate params block like below...

This will validate the params:

desc 'Create a User.', {
    detail: 'Used to create a new User.',
    named: 'Create User',
    success: Entities::User,
    failure: [
        [400, 'Bad request', Entities::Error],
        [422, 'Bad parameter entry', Entities::Error]
    ],
    notes: <<-NOTE
      Creates a new User

      ## Request properties

      * _Safe:_ Yes
      * _Idempotent:_ No
      * _Can be retried:_ Yes
    NOTE
}
params do
  requires :email, type: String, desc: 'Email address.'
  requires :password, type: String, desc: 'Password.'
  requires :password_confirmation, type: String, desc: 'Password Confirmation.'
  optional :first_name, type: String, desc: 'Users first name.'
  optional :last_name, type: String, desc: 'Users last name.'
  optional :phone, type: Integer, desc: 'Users phone number.'
  optional :address, type: String, desc: 'Users address.'
  optional :address_two, type: String, desc: 'Users address line two.'
  optional :city, type: String, desc: 'Users city.'
  optional :state, type: String, desc: 'Users state.'
  optional :zip, type: Integer, desc: 'Users zip code.'
end
post do
  # stuff ...
end

This will not validate params:

desc 'Create a User.', {
    detail: 'Used to create a new User.',
    named: 'Create User',
    params: Entities::CreateUserParams.documentation,
    success: Entities::User,
    failure: [
        [400, 'Bad request', Entities::Error],
        [422, 'Bad parameter entry', Entities::Error]
    ],
    notes: <<-NOTE
      Creates a new User

      ## Request properties

      * _Safe:_ Yes
      * _Idempotent:_ No
      * _Can be retried:_ Yes
    NOTE
}
post do
  # stuff ...
end

# here is what CreateUserParams looks like...
module API
  module V1
    module Entities
      require 'grape-entity'
      class User < Grape::Entity
        expose :id, documentation: { type: Integer, desc: 'User unique identifier.' }
        expose :first_name, documentation: { type: String, desc: 'User first name.' }
        expose :last_name, documentation: { type: String, desc: 'User last name.' }
        expose :email, documentation: { type: String, desc: 'User unique email address.' }
        expose :username, documentation: { type: String, desc: 'User unique username.' }
        expose :errors, documentation: { type: Hash, desc: 'A hash containing any validation errors that may have occurred.' }
        expose :phone, documentation: { type: Integer, desc: 'User phone number.' }
        expose :address, documentation: { type: String, desc: 'User address line 1.' }
        expose :address_two, documentation: { type: String, desc: 'User address line 2.' }
        expose :city, documentation: { type: String, desc: 'User city.' }
        expose :state, documentation: { type: String, desc: 'User state.' }
        expose :zip, documentation: { type: Integer, desc: 'User zip code.' }
        expose :created_at, documentation: { type: DateTime, desc: 'The date the user was created.' }
        expose :updated_at, documentation: { type: DateTime, desc: 'The date the user was last updated.' }
      end

      class CreateUserParams < User
        unexpose :id
        unexpose :email

        expose :email, documentation: { type: String, desc: 'User unique email address.', required: true }
        expose :password, documentation: { type: String, desc: 'Password.', required: true }
        expose :password_confirmation, documentation: { type: String, desc: 'Password Confirmation.', required: true }
      end

      class UpdateUserParams < User
        unexpose :id

        expose :id, documentation: { type: Integer, desc: 'User unique identifier.', required: true }
        expose :password, documentation: { type: String, desc: 'Password.' }
        expose :password_confirmation, documentation: { type: String, desc: 'Password Confirmation.' }
      end
    end
  end
end

@dpad
Copy link

dpad commented Mar 4, 2016

Same request as per @guizmaii and @atljeremy above. Did either of you manage to get some sort of simple/elegant workaround?

@atljeremy
Copy link

@dpad Unfortunately no. I'm having to use the explicit params do block to define required and optional params separately from my Grape::Entity's. I'm really hoping that this gets updated so that I don't have to keep maintaining two separate sets of params documentation.

@emanoelxavier2
Copy link

+1

@nanderss
Copy link

nanderss commented Nov 3, 2018

I was wondering if there's a solution to this?

@maxgurewitz
Copy link

+1

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

No branches or pull requests