ruby-grape / grape Goto Github PK
View Code? Open in Web Editor NEWAn opinionated framework for creating REST-like APIs in Ruby.
Home Page: http://www.ruby-grape.org
License: MIT License
An opinionated framework for creating REST-like APIs in Ruby.
Home Page: http://www.ruby-grape.org
License: MIT License
Allow for a generic auth helper that works against an Endpoint and is meant to return a user object that is exposed in the endpoint as current_user
. It will also return a boolean for current_user?
and authenticated?
based on the truthiness of the current_user
returned from the auth.
class MyAPI < Grape::API
auth do
User.find_by_api_token(params[:api_token] || request.headers['X-Token'])
end
end
Create a DSL wrapper around Rack::Builder that will be able to dynamically generate a Rack application based on the provided API structure. For starters, it should have support for:
Should be able to configure a logger either by supplying one or supplying a filename. Should default to STDOUT
Hi. Was MiddlewareStack intended to be used in API.build_endpoint? If so, I made some changes to MiddlewareStack so it could accept a block argument. This seems to be necessary for Rack::Auth::Basic. Here's the commit on my fork
CapyTheBeara@c6901eb
I image that if we use MiddlewareStack in API then it might be possible to insert user defined middleware into the stack. Is this what you were planning for? Thanks.
Grape::Entity breaks Grape::API when requesting a collection with a query scope
Using entity on a collection with a query scope is throwing an error
the following works without issue
resource :posts do
get do
@posts = Post.all
present @posts, :with => PostEntity
end
end
while
resource :posts do
get do
@posts = Post.order('published_at DESC')
present @posts, :with => PostEntity
end
end
throws the following error
undefined local variable or method `published_at' for #<ActiveRecord::Relation:0x000001010b15b0>
# ./spec/api/posts_api_spec.rb:12:in `block (3 levels) in <top (required)>'
With the following framework trace
activerecord (3.1.1) lib/active_record/relation.rb:459:in `method_missing'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/entity.rb:145:in `value_for'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/entity.rb:124:in `block in serializable_hash'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/entity.rb:123:in `each'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/entity.rb:123:in `inject'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/entity.rb:123:in `serializable_hash'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/base.rb:115:in `encode_json'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/formatter.rb:79:in `call'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/formatter.rb:79:in `block in after'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/formatter.rb:78:in `collect'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/formatter.rb:78:in `after'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/base.rb:26:in `call!'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/base.rb:19:in `call'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/base.rb:25:in `call!'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/base.rb:19:in `call'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/error.rb:44:in `block in call!'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/error.rb:43:in `catch'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/error.rb:43:in `call!'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/middleware/base.rb:19:in `call'
rack-mount (0.8.3) lib/rack/mount/route_set.rb:152:in `block in call'
rack-mount (0.8.3) lib/rack/mount/code_generation.rb:96:in `block in recognize'
rack-mount (0.8.3) lib/rack/mount/code_generation.rb:68:in `optimized_each'
rack-mount (0.8.3) lib/rack/mount/code_generation.rb:95:in `recognize'
rack-mount (0.8.3) lib/rack/mount/route_set.rb:141:in `call'
/[...]/bundler/gems/grape-12e44781d7e8/lib/grape/api.rb:33:in `call'
rack-mount (0.8.3) lib/rack/mount/prefix.rb:26:in `call'
rack-mount (0.8.3) lib/rack/mount/route_set.rb:152:in `block in call'
rack-mount (0.8.3) lib/rack/mount/code_generation.rb:96:in `block in recognize'
rack-mount (0.8.3) lib/rack/mount/code_generation.rb:75:in `optimized_each'
rack-mount (0.8.3) lib/rack/mount/code_generation.rb:95:in `recognize'
rack-mount (0.8.3) lib/rack/mount/route_set.rb:141:in `call'
actionpack (3.1.1) lib/action_dispatch/routing/route_set.rb:532:in `call'
airbrake (3.0.4) lib/airbrake/rack.rb:27:in `call'
sass (3.1.10) lib/sass/plugin/rack.rb:54:in `call'
warden (1.0.6) lib/warden/manager.rb:35:in `block in call'
warden (1.0.6) lib/warden/manager.rb:34:in `catch'
warden (1.0.6) lib/warden/manager.rb:34:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
rack (1.3.5) lib/rack/etag.rb:23:in `call'
rack (1.3.5) lib/rack/conditionalget.rb:25:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/head.rb:14:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/flash.rb:243:in `call'
rack (1.3.5) lib/rack/session/abstract/id.rb:195:in `context'
rack (1.3.5) lib/rack/session/abstract/id.rb:190:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/cookies.rb:331:in `call'
activerecord (3.1.1) lib/active_record/query_cache.rb:62:in `call'
activerecord (3.1.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:477:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (3.1.1) lib/active_support/callbacks.rb:392:in `_run_call_callbacks'
activesupport (3.1.1) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.1.1) lib/action_dispatch/middleware/callbacks.rb:28:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/reloader.rb:68:in `call'
rack (1.3.5) lib/rack/sendfile.rb:101:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/remote_ip.rb:48:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/show_exceptions.rb:47:in `call'
railties (3.1.1) lib/rails/rack/logger.rb:13:in `call'
rack (1.3.5) lib/rack/methodoverride.rb:24:in `call'
rack (1.3.5) lib/rack/runtime.rb:17:in `call'
activesupport (3.1.1) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.3.5) lib/rack/lock.rb:15:in `call'
actionpack (3.1.1) lib/action_dispatch/middleware/static.rb:53:in `call'
airbrake (3.0.4) lib/airbrake/user_informer.rb:12:in `call'
railties (3.1.1) lib/rails/engine.rb:456:in `call'
railties (3.1.1) lib/rails/rack/content_length.rb:16:in `call'
railties (3.1.1) lib/rails/rack/log_tailer.rb:14:in `call'
rack (1.3.5) lib/rack/handler/webrick.rb:59:in `service'
/[...]/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
/[...]/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
/[...]/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'
and a simplified version of the app setup I am using
# app/models/post.rb
# == Schema Information
#
# Table name: lessons
#
# id :integer not null, primary key
# published_at :datetime
# title :string(255)
# body :text
# created_at :datetime
# updated_at :datetime
class Post < ActiveRecord::Base
end
# app/api/posts_api.rb
class PostsApi < Grape::API
represent Post, :with => PostEntity
prefix "api"
resource :posts do
get do
@posts = Post.order('published_at DESC') #vs Post.all
present @posts, :with => PostEntity
end
end
end
# app/entities/posts_entity.rb
class PostEntity < Grape::Entity
expose :title, :body, :published_at
end
# config/routes.rb
mount PostsApi => "/"
# config/application.rb
module myApp
class Application < Rails::Application
...
config.autoload_paths += %W(#{Rails.root}/api, #{Rails.root}/entities)
...
I'm using the most current version of Grape and when I try to POST with the content-type as "application/json," Grape isn't picking up the params in the JSON body. The only params listed when I debug is the version number.
Is there a way to have nested resources to get routes like this:
foo id bar id
| |
/foo/:id/bars/:id
Something along those lines:
resource :foo do
resource :bar do
get '/:id' do
#...this obviously misses the foo id
That would make it easy to map (model) relations to the API.
When I have a Grape::API application and I declare a namespace, if I declare a route before the helpers block, those helpers aren't available to the route. If I declare the route after, they are. For example:
require 'grape'
class DamnDirtyGrape < Grape::API
resource :foo do
get :broke do
# NoMethodError here.
hello_helper
end
helpers do
def hello_helper
"Hello World!"
end
end
get :works do
hello_helper
end
end
end
In Sinatra, a simiilar small framework from which Grape takes inspiriation, both methods work
require 'sinatra'
get '/' do
hello_helper
end
helpers do
def hello_helper
"Hello World!"
end
end
It's not a major priority but given that Sinatra behaves this way it would be nice from a consistency perspective. If anyone is willing to mentor me a little for this I am more than willing to give it a stab myself.
Cheers and thanks!
Steven!
does Grape provide a mechanism like before_filter in rails controller?
say:
resources :missions do
before_filter :authenticate!, :only => [:post]
post do
create mission here...
end
get do
return all missions here...
end
end
Hey,
In addition to the point for self documenting APIs in the roadmap - did you also think about generating formal descriptions?
I always wondered why no-one thought about it/has done it for rails already.
Basically you could easily generate a semantic description of the existing actions, and parameter annotations - the annotations could then also be used for validation or similar stuff...
The benefit is that they are machine readable, and could be automatically invoked, searched, described, etc...
Greetings,
Christoph
ActiveResource
uses either application/xml
or application/json
as the content_type
when submitting HTTP requests.
When an ARes request is submitted, the associated Rack::Request
's POST
method returns {}
rather than the params ARes submits, because Rack expects POST requests to have content_type
application/x-www-form-urlencoded
or multipart/form-data
.
Grape uses the Rack::Request
's params
method to set the params
hash (which returns the union of the GET
and POST
data - which is empty).
For Grape to natively support ActiveResource, it needs to also merge env["action_dispatch.request.request_parameters"]
in Endpoint#params
.
Alternatively, you could create your own ActiveResource::Format
and make mime_type
return application/x-www-form-urlencoded
, then use your format by calling self.format = :format_name
in your ARes subclass.
There may well be a saner way to solve this. ARes seems to be at fault here; I'm not sure what their rationale is for setting the content_type to application/xml. I'm a bit of a Rack nub so maybe I'm missing something.
I thought I'd submit this here for the next person to hit this wall. Any thoughts are appreciated!
Edit
I ended up defining an ares_params
helper in my grape API to merge the action_dispatch.request.request_parameters
with params
. This seems like the cleanest approach; there seem to be weird discrepancies in the way ActiveResource::Format
encode
methods are used (the encoding is done by calling to_#{extension}
rather than encode
).
We'd like to use http_basic for authenticating users of the API via an id and token for certain resources. It appears though that http_basic will always fail unless you provide credentials. https://github.com/intridea/grape/blob/master/lib/grape/middleware/auth/basic.rb
I tried to do something like the following as a test:
http_basic do
true
end
and my unit tests always seemed to get the 401.
To further compound the issue we need some way to tell the basic auth to only work for certain resources without duplicating the basic block.
Has anyone ran into this? Any thoughts would be greatly appreciated.
I shouldn't have to double-check that present
isn't called with nil
. If the model passed is nil
, then it should just return empty JSON for that object.
I can write a middleware handler to trap all exceptions.
class ApiErrorHandler < Grape::Middleware::Base
def call!(env)
@env = env
begin
@app.call(@env)
rescue Exception => e
throw :error, :message => e.message || options[:default_message], :status => 500
end
end
end
But this doesn't let me return a JSON error because there're still other things executing in the stack (which produce errors with this result).
Should Grape::Middleware::Error just be refactored to trap all exceptions (optionally)?
when i go to /users
I get this error undefined method 'full_name' for #<Array:0x007fc2d62d69c8>
full_name or what ever fields.
get "users" do
@users = User.all
present @users, :with => Entities::UserEntity
end
module Entities
class UserEntity < Grape::Entity
expose :full_name, :email
end
end
Grape is not a controller or view. An example of how to write an rspec test would be great.
How would one go through to plug this into middleware without using the Rails 3 routes?
Because using the routes would put it at th bottom of the stack.
Would save me time from implementing my own dsl... again.
It would be great to be able to call logger.debug or whatever from within the route handler methods.
Hi,
Grapes is working fine for me as a basic Rack app, very pleasing. I am contrasting to my Sinatra API work, and liking the possibilities.
I setup and started using @CloudHeads http-console; sent some requests to my API.
eg: /1/service/feedme
The response showed "application/json" for content-type. I returned ["english","french"] from my feedme API and the response was ['english','french']. Only the quoting was changed.
When I changed my request to /1/service/feedme.json I received 404. Any type was refused with 404. Is there something I am missing about configuring the routes with Grape to return content as XML, or other formats?
I figured that since my initial request returned JSON without me specifying JSON, asking for JSON would do that same...any info on the current state of route recognition based on the incoming request?
Thanks!! This looks like a wicked little gem for my toolbox!!
It would be great to use grape as rack middleware in sinatra or rails. Currently it seems that Grape::API doesn't support this scenario. I wonder why call(env) method was made class method?
I see the documentation for it and this one example, but cannot get it to work.
Surely I am missing the method 'before' defined in the Grape::API class in the source code.
Is it just me or does the before render a method_missing error?
class MyProject::API < Grape::API
prefix 'api'
version '1.0'
rescue_from :all #for all errors
before do
# before code
end
...
end
"undefined method `before' for MyProject::API:Class"
Thanks in advance!
API code is not reloaded when it changed since it's building routes. The feature request is to be able to reload API code dynamically, ideally automatically when code changes.
For example:
class MyAPI < Grape::API
prefix 'api'
version '1'
callback 'my_callback'
resources :posts do
# GET /api/1/posts/:id
get ":id" do
Post.find(params[:id])
end
end
end
Then visiting http://0.0.0.0:3000/api/1/posts/1?b=c&my_callback=foo
, would result in
foo({ ... });
Hey,
Either I don't it, or I am missing something.. but how do you return xml/xhtml?
Cannot figure it out...
I want to return xhtml rendered with a haml templates, isn't this possible?
Furthermore I wanted to return .pdf rendered with prawn but I assume then this is also not possible?
Thanks,
Christoph
I can't seem to get grape to work with requests sent as application/json content-type without actually serializing the request into a param string. Is this not supported?
Most apis return some kind of error object when they return an error. It would be nice if grape supported any kind of input into the error! method and then parsed and returned it in the requested format
I have /api/v1/widgets/my-widget-name that returns a widget. Now I want to return my-widget-name's gadgets. It doesn't seem to be possible to do /api/v1/widgets/:widget/gadgets.
(Also, is this a good idea at all?)
The Sinatra request object has more robust accessors for parsing the Accept header according to rfc2616 definitions. The current implementation works fine for versioning, but at some point it might be worthwhile to complete a more full implementation according to the RFC.
Is there any timescale for when the OAuth authentication will be added?
I have taken a look on the roadmap as it is listed quite high up on there, but it was last updated on 15th Nov 2010?
Here is the offending code on line 30 in grape/endpoint.rb:
# The parameters passed into the request as
# well as parsed from URL segments.
def params
@params ||= request.params.merge(env['rack.routing_args'] || {}).inject({}) do |h,(k,v)|
h[k.to_s] = v
h[k.to_sym] = v
h
end
end
You can get access to the unmodified version of the params through the request
object, but I think most people expect the params
method to return the params hash in unmodified.
This behavior causes problems for recreating a hash signature if you don't know to use request.params
.
I would rather see a wrapper around the params hash as a means to provide HashWithIndifferentAccess
-like functionality rather than modifying the params hash itself.
Just like the title. for example, how to integrate it with rack-oauth2-server.
There's no a default logger.info "#{env['REQUEST_METHOD']} #{env['PATH_INFO']}"
in grape/api.rb. It's annoying in tests, at least. Maybe it shouldn't be there? Or maybe we should have a nice way of silencing it?
I should not be required to use your version of Ruby and your Gemset name ;)
from sinatra documentation:
get '/say/*/to/*' do
# matches /say/hello/to/world
params[:splat] # => ["hello", "world"]
end
get '/download/*.*' do
# matches /download/path/to/file.xml
params[:splat] # => ["path/to/file", "xml"]
end
is it possible do something like that using grape?
The best that I could come up with is http://code.dblock.org/modularizing-a-ror-grape-api, faking modularization in Grape.
module Api_v1_Ping
def self.included(api)
api.namespace :ping do
# GET /api/v1/ping/pong
get "pong" do
"pong"
end
end
end
end
But I would like to be able to write the following.
class Api_v1 < Grape::API
prefix 'api'
version 'v1'
include Api_v1_Ping
end
module Api_v1_Ping
include Grape::APIModule
namespace :ping do
# GET /api/v1/ping/pong
get pong" do
"pong"
end
end
end
require 'active_support/core_ext'
...
get '/foo' do
present [(class Foo; self; end).new], :with => Grape::Entity
end
The above (entity-wrapping an Array) results in a stacktrace.
TypeError: can't convert nil into Hash
./bundler/gems/grape-883295cf0856/lib/grape/entity.rb:121:in `merge'
./bundler/gems/grape-883295cf0856/lib/grape/entity.rb:121:in `serializable_hash'
./gems/activesupport-3.0.0/lib/active_support/json/encoding.rb:46:in `block in encode'
./gems/activesupport-3.0.0/lib/active_support/json/encoding.rb:60:in `check_for_circular_references'
./gems/activesupport-3.0.0/lib/active_support/json/encoding.rb:45:in `encode'
./gems/activesupport-3.0.0/lib/active_support/json/encoding.rb:190:in `block in encode_json'
./gems/activesupport-3.0.0/lib/active_support/json/encoding.rb:190:in `map'
./gems/activesupport-3.0.0/lib/active_support/json/encoding.rb:190:in `encode_json'
./gems/activesupport-3.0.0/lib/active_support/json/encoding.rb:46:in `block in encode'
./gems/activesupport-3.0.0/lib/active_support/json/encoding.rb:60:in `check_for_circular_references'
./gems/activesupport-3.0.0/lib/active_support/json/encoding.rb:45:in `encode'
./gems/activesupport-3.0.0/lib/active_support/json/encoding.rb:30:in `encode'
./gems/activesupport-3.0.0/lib/active_support/core_ext/object/to_json.rb:20:in `to_json'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/base.rb:117:in `encode_json'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/formatter.rb:79:in `call'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/formatter.rb:79:in `block in after'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/formatter.rb:78:in `collect'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/formatter.rb:78:in `after'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/base.rb:26:in `call!'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/base.rb:19:in `call'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/base.rb:25:in `call!'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/base.rb:19:in `call'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/error.rb:44:in `block in call!'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/error.rb:43:in `catch'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/error.rb:43:in `call!'
./bundler/gems/grape-883295cf0856/lib/grape/middleware/base.rb:19:in `call'
I fixed this locally by rewriting the serializable_hash
method to set runtime_options ||= {}
, since it may be passed in as nil
.
The Grape framework by default serializes return objects as JSON. Currently this is a shallow serialization. I propose to add a clause to the encoding strategy which inspects an Array, Hash, or other Enumerable type and calls the serialization methods on its elements. I have forked on GitHub and this issue is mostly an announcement and self-reminder.
A Grape API should be able to mount other Rack applications inside of it. In addition, it should be able to mount another API and that API will inherit the other API's settings.
class UsersAPI < Grape::API
get '/:id' do
# ...
end
end
class MyAPI
version :v1
mount UsersAPI => '/users'
end
The Formatter takes care of handling the various formats into which Grape API responses can be converted. It consists of two parts:
This would first look at any format appended as an extension (i.e. .json
or .xml
). If no format is appended, it would properly parse and use the HTTP Accept
header (including weighted quality values) to determine an array of acceptable formats.
The middleware would be transparent in Grape, but also usable outside of it. Any data set in the Rack env
hash on the key api.response_data
should automatically be converted to the desired format (falling back to a to_format
call if existing methods aren't in place) and sent along as the response body. A proper content type should also be set based on the used response format.
This should be flexible enough to allow for stranger formats (for example, a PDF or a Zip file response).
Hey, I have more of a conceptual question than an issue, really. The current Entity mechanism is detached from the models I already have, right? There's a separate model I have to define, and then in a Grape method, I have to say present
my model with this Entity
model.
But before the Entity stuff, I was actually achieving a similar result just by making a method in my model that outputs a hash with the attributes I want, e.g.
# my model
class User
field :email
field :username
field :firstname
field :lastname
def api
{ email: self.email, username: self.username }
end
end
# my api
class API < Grape::API
version 'v1'
get '/users/:id' do
user = User.first
user.api.to_json
end
end
So my imagination is thinking, what if the Entity mechanism were more like:
# my model
class User
field :email
field :username
field :firstname
field :lastname
include ExposableAttributes
expose :email, :username
end
# my api
class API < Grape::API
version 'v1'
get '/users/:id' do
user = User.first
user.api.to_json
end
end
So, it could just be an includable Module, with the expose
method, that assembles a hash. It might be less code and have a prettier end result, but would there be any big downsides to something like that, as opposed to the current way?
Needs to be as lightweight and out-of-the-way as possible.
API#use seems to fail when used on another API if there are also resource/nested things. I'm not sure how common or not this is, but I was exploring having separate API things for different resources and composing them instead of having a monolithic API class. It is also quite possible I was missing something, but after digging around at it I was coming up blank.
Here is the simplest reproduction case I could come up with, set this as a config.ru and run rackup to see the error:
class Contained < Grape::API; end
class Container < Grape::API
use Contained
resource :container do
get '' do
'container'
end
end
end
run Container
And here is the specific error I was seeing:
/Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/rack-1.2.1/lib/rack/builder.rb:54:in `initialize': wrong number of arguments (1 for 0) (ArgumentError)
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/rack-1.2.1/lib/rack/builder.rb:54:in `new'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/rack-1.2.1/lib/rack/builder.rb:54:in `use'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/rack-1.2.1/lib/rack/builder.rb:73:in `call'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/rack-1.2.1/lib/rack/builder.rb:73:in `to_app'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/grape-0.1.3/lib/grape/api.rb:224:in `inject'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/rack-1.2.1/lib/rack/builder.rb:73:in `each'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/rack-1.2.1/lib/rack/builder.rb:73:in `inject'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/rack-1.2.1/lib/rack/builder.rb:73:in `to_app'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/grape-0.1.3/lib/grape/api.rb:228:in `build_endpoint'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/grape-0.1.3/lib/grape/api.rb:141:in `route'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/grape-0.1.3/lib/grape/api.rb:154:in `get'
from config.ru:23
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/grape-0.1.3/lib/grape/api.rb:208:in `instance_eval'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/grape-0.1.3/lib/grape/api.rb:208:in `nest'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/grape-0.1.3/lib/grape/api.rb:208:in `each'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/grape-0.1.3/lib/grape/api.rb:208:in `nest'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/grape-0.1.3/lib/grape/api.rb:162:in `resource'
from config.ru:22
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/rack-1.2.1/lib/rack/builder.rb:46:in `instance_eval'
from /Users/geemus/.rvm/gems/ruby-1.8.7-p330/gems/rack-1.2.1/lib/rack/builder.rb:46:in `initialize'
from config.ru:1:in `new'
from config.ru:1
Trying to use either https://github.com/collectiveidea/rack-ssl or https://github.com/tobmatth/rack-ssl-enforcer to require api calls to use https and redirect if not. Mostly works except the redirect drops the version from the path in the redirect (Location header). Any ideas?
When I want to open http://0.0.0.0:3000/api/v1.0/items
I can see in the chrome console, 2 requests One with method GET
and HEAD
http://dl.dropbox.com/u/1067690/Screen%20shot%202011-07-21%20at%2011.26.02%20PM.png
When add .json
at the end, everything is fine!
Also, when I tried to access http://0.0.0.0:3000/api/v1.0/items/4e2324c857a3c0d7b500001a.json
this message thrown in the console !! Unexpected error while processing request: illegal ObjectId format
even when I remove .json
it works but it has the first problem
I am working on semi-automatic documentation for our API based on Grape. I'd like to be able to enumerate registered versions and for each version existing paths, routes, methods and whatever other meta information I can get.
Maybe it's already possible? Maybe this needs new code?
Does anyone know of an OS Rails app that uses Grape?
Please see this line:
https://github.com/intridea/grape/blob/master/lib/grape/endpoint.rb#L33
It will leak since people will throw random params at your server. And you will keep all those keys as symbols in memory. I can intentionally bring a server down to it's knees by just repeatedly sending random params.
From line 20, of api.rb, the logger is initialized with $STDOUT
. That global doesn't exist. You appear to be conflating $stdout
and STDOUT
. :)
Assume I have 2 models: User and Preference. User has_one
preference.
And here's Grape entities:
module Entities
class PreferenceEntity < Grape::Entity
expose :logo, :background_color
end
class UserEntity < Grape::Entity
expose :full_name
expose :email
expose :preference, :as => :preferences, :using => PreferenceEntity
end
end
Now, with
get "me" do
present current_user, :with => Entities::UserEntity
end
Throws this error:
{
error: "wrong number of arguments(0 for 2)",
backtrace: [
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/entity.rb:145:in `autoload'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/entity.rb:145:in `value_for'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/entity.rb:124:in `block in serializable_hash'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/entity.rb:123:in `each'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/entity.rb:123:in `inject'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/entity.rb:123:in `serializable_hash'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/json/encoding.rb:55:in `block in as_json'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/json/encoding.rb:78:in `check_for_circular_references'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/json/encoding.rb:54:in `as_json'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/json/encoding.rb:245:in `block in as_json'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/json/encoding.rb:245:in `each'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/json/encoding.rb:245:in `map'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/json/encoding.rb:245:in `as_json'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/json/encoding.rb:47:in `block in encode'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/json/encoding.rb:78:in `check_for_circular_references'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/json/encoding.rb:46:in `encode'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/json/encoding.rb:31:in `encode'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/activesupport-3.1.1/lib/active_support/core_ext/object/to_json.rb:20:in `to_json'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/multi_json-1.0.3/lib/multi_json/engines/json_gem.rb:17:in `encode'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/multi_json-1.0.3/lib/multi_json.rb:72:in `encode'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/base.rb:115:in `encode_json'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/formatter.rb:79:in `call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/formatter.rb:79:in `block in after'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/formatter.rb:78:in `collect'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/formatter.rb:78:in `after'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/base.rb:26:in `call!'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/base.rb:19:in `call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/base.rb:25:in `call!'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/base.rb:19:in `call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/base.rb:25:in `call!'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/base.rb:19:in `call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/error.rb:44:in `block in call!'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/error.rb:43:in `catch'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/error.rb:43:in `call!'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/middleware/base.rb:19:in `call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/rack-mount-0.8.3/lib/rack/mount/route_set.rb:152:in `block in call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:96:in `block in recognize'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:68:in `optimized_each'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/rack-mount-0.8.3/lib/rack/mount/code_generation.rb:95:in `recognize'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/rack-mount-0.8.3/lib/rack/mount/route_set.rb:141:in `call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bundler/gems/grape-ece183048418/lib/grape/api.rb:32:in `call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/warden-1.1.0/lib/warden/manager.rb:35:in `block in call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/warden-1.1.0/lib/warden/manager.rb:34:in `catch'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/warden-1.1.0/lib/warden/manager.rb:34:in `call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/rack-1.3.5/lib/rack/session/abstract/id.rb:195:in `context'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/rack-1.3.5/lib/rack/session/abstract/id.rb:190:in `call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/rack-1.3.5/lib/rack/reloader.rb:44:in `call'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/thin-1.3.1/lib/thin/connection.rb:80:in `block in pre_process'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/thin-1.3.1/lib/thin/connection.rb:78:in `catch'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/thin-1.3.1/lib/thin/connection.rb:78:in `pre_process'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/thin-1.3.1/lib/thin/connection.rb:53:in `process'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/thin-1.3.1/lib/thin/connection.rb:38:in `receive_data'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/eventmachine-1.0.0.beta.4/lib/eventmachine.rb:179:in `run_machine'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/eventmachine-1.0.0.beta.4/lib/eventmachine.rb:179:in `run'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/thin-1.3.1/lib/thin/backends/base.rb:61:in `start'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/thin-1.3.1/lib/thin/server.rb:159:in `start'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/thin-1.3.1/lib/thin/controllers/controller.rb:86:in `start'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/thin-1.3.1/lib/thin/runner.rb:185:in `run_command'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/thin-1.3.1/lib/thin/runner.rb:151:in `run!'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/gems/thin-1.3.1/bin/thin:6:in `<top (required)>'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bin/thin:19:in `load'",
"/Users/amr/.rvm/gems/ruby-1.9.2-p290@api-new/bin/thin:19:in `<main>'"
]
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.