-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Organization with blocks of methods #1487
Comments
I'm also interested in this as it seems pretty messy to have these separated. |
We've always thought of |
See also: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6330/diffs You end up with things like this: module API
# Projects variables API
class Variables < Grape::API
before { authenticate! }
before { authorize! :admin_build, user_project }
resource :projects do
desc 'Get project variables' do
success Entities::Variable
end
params do
requires :id, type: Integer, desc: 'The ID of a project'
optional :page, type: Integer, desc: 'The page number for pagination'
optional :per_page, type: Integer, desc: 'The value of items per page to show'
end
get ':id/variables' do
variables = user_project.variables
present paginate(variables), with: Entities::Variable
end
desc 'Get specific variable of a project' do
success Entities::Variable
end
params do
requires :id, type: Integer, desc: 'The ID of a project'
requires :key, type: String, desc: 'The key of the variable'
end
get ':id/variables/:key' do
key = params[:key]
variable = user_project.variables.find_by(key: key.to_s)
return not_found!('Variable') unless variable
present variable, with: Entities::Variable
end
desc 'Create a new variable in project' do
success Entities::Variable
end
params do
requires :id, type: Integer, desc: 'The ID of a project'
requires :key, type: String, desc: 'The key of the variable'
requires :value, type: String, desc: 'The value of the variable'
end
post ':id/variables' do
variable = user_project.variables.create(key: params[:key], value: params[:value])
if variable.valid?
present variable, with: Entities::Variable
else
render_validation_error!(variable)
end
end
desc 'Update existing variable of a project' do
success Entities::Variable
end
params do
requires :id, type: Integer, desc: 'The ID of a project'
optional :key, type: String, desc: 'The key of the variable'
optional :value, type: String, desc: 'TNew value for `value` field of the variable'
end
put ':id/variables/:key' do
variable = user_project.variables.find_by(key: params[:key].to_s)
return not_found!('Variable') unless variable
attrs = attributes_for_keys [:value]
if variable.update(attrs)
present variable, with: Entities::Variable
else
render_validation_error!(variable)
end
end
desc 'Delete existing variable of a project' do
success Entities::Variable
end
params do
requires :id, type: Integer, desc: 'The ID of a project'
requires :key, type: String, desc: 'The key of the variable'
end
delete ':id/variables/:key' do
variable = user_project.variables.find_by(key: params[:key].to_s)
return not_found!('Variable') unless variable
variable.destroy
present variable, with: Entities::Variable
end
end
end
end Without careful spacing it's not immediately obvious which descriptions/parameters are related to one another. |
@connorshea That's exactly my problem. I've got a pretty big codebase, and it gets messy like that quickly. |
To be clear, I don't want it to modify the path (like an additional |
Exactly the same for me, would be ideal to have a wrapper block to organize things together. |
We have created a directory structure that avoids the big block mess and has worked quite well for us. We put each discrete endpoint in its own file and include that into a main API file (e.g. The directory structure is something like the following. We currently have 14 categories of endpoints (e.g. apples, bananas, and samples in the tree below), each with their own set of discrete actions for a mostly RESTful API. This organizational structure supports nested resources as well as top-level resources. The biggest file we have within this structure is 175 lines long (including blank lines for visual queues) -- that file is a Our I think this type of organization helps with code reading, maintenance, consistency, and a small host of other things. As for code folding, well the file browser of your favorite editor will essentially do that for you. I hope this helps. (Disclaimer: the names of (most) files and directories have been altered to protect the guilty.)
|
Both @tibbon and @connorshea raise valid concerns. Also @connorshea should contribute to "who uses grape" at http://www.ruby-grape.org/users/ :) I do like what @jason-uh is doing. I prefer That said, I am open to a meaningless block that doesn't modify path, if we can find a good name for it. I suggest |
@dblock we're already listed under Examples, should we do both? :) |
It doesn't hurt thanks @connorshea! I wonder if we should combine examples and users or reference one to another. |
@tibbon any progress/thoughts on what'd work best as a name for these blocks? |
I like the Another solution might be to put the description and params inside the method block, though I can understand why you wouldn't (or couldn't?) want to do that. |
On the GitLab-CE issue tracker we've discussed this too, as @connorshea mentioned. We were thinking about a block called |
|
Hi @dblock |
Feel free to implement and PR something, @blackst0ne. |
Is there a simple way, to organize the methods with blocks for code folding, organization, etc?
What I'm thinking of using a short version of the example in the README, but wrapping methods and blocks in
group
blocks:I'm finding the only way I can get this right now is to use Ruby's open classes, and then having a separate definition for each one. It feels weird for
desc
andparams
to not be block based, but rather order based.The text was updated successfully, but these errors were encountered: