ruby-on-railsgrape-api

How to get pretty Grape API routes to a nested collection


In the swagger pic below, my endpoint for listing a project's campaigns is returning the intended data, but the url has unwanted segments.

How can I structure the code in order to have nested collections or such endpoints come as appendages to the parent model's id: /api/v1/projects/{id}/campaigns ?

enter image description here

module API                                                                                                                                                                                                         
  module V1                                                                                                                                                                                                        
    class Projects < Grape::API                                                                                                                                                                                    
      include API::V1::Defaults                                                                                                                                                                                    

      resource :projects do                                                                                                                                                                                        
        desc "Return all projects"                                                                                                                                                                                 
        get "", root: :projects do                                                                                                                                                                                 
          Project.all                                                                                                                                                                                              
        end                                                                                                                                                                                                        

        desc "Return a project"                                                                                                                                                                                    
        params do                                                                                                                                                                                                  
          requires :id, type: String, desc: "ID of the project"                                                                                                                                                    
        end                                                                                                                                                                                                        

        get ":id", root: "project" do                                                                                                                                                                              
          Project.where(id: permitted_params[:id]).first!                                                                                                                                                          
        end                                                                                                                                                                                                        

        resource :campaigns do                                                                                                                                                                                     
          desc "Return all campaigns for a project"                                                                                                                                                                
          get ":id/campaigns", root: "project" do                                                                                                                                                                  
            Project.find(params[:id]).campaigns                                                                                                                                                                    
          end                                                                                                                                                                                                      
        end                                                                                                                                                                                                        

      end                                                                                                                                                                                                          
    end                                                                                                                                                                                                            
  end                                                                                                                                                                                                              
end  

Solution

  • Removing the resource block and duplicating the params for the nested resource worked fine as follows:

    module API                                                                                                                                                                                                         
      module V1                                                                                                                                                                                                        
        class Projects < Grape::API                                                                                                                                                                                    
          include API::V1::Defaults                                                                                                                                                                                    
    
          resource :projects do                                                                                                                                                                                        
            desc "Return all projects"                                                                                                                                                                                 
            get "", root: :projects do                                                                                                                                                                                 
              Project.all                                                                                                                                                                                              
            end                                                                                                                                                                                                        
    
            desc "Return a project"                                                                                                                                                                                    
            params do                                                                                                                                                                                                  
              requires :id, type: String, desc: "ID of the project"                                                                                                                                                    
            end                                                                                                                                                                                                        
    
            get ":id", root: "project" do                                                                                                                                                                              
              Project.where(id: permitted_params[:id]).first!                                                                                                                                                          
            end                                                                                                                                                                                                        
    
            desc "Return all campaigns for a project"                                                                                                                                                                  
            params do                                                                                                                                                                                                  
              requires :id, type: String, desc: "ID of the project"                                                                                                                                                    
            end                                                                                                                                                                                                        
    
            get ":id/campaigns", root: "project" do                                                                                                                                                                    
              Project.find(params[:id]).campaigns                                                                                                                                                                      
            end                                                                                                                                                                                                        
    
          end                                                                                                                                                                                                          
        end                                                                                                                                                                                                            
      end                                                                                                                                                                                                              
    end