Better explanation of when "given" and "mounted" should be used.

177 views
Skip to first unread message

Edward Rudd

unread,
Mar 11, 2020, 6:47:12 PM3/11/20
to Grape Framework Discussion
In working on upgrading our API from Grape 1.2.3 -> 1.3.1 I'm having to make some changes related to mounting endpoints and the mount parameters.


What I have right now are mount like this.

class MyAPI < Grape::API
  resource configuration[:path] || :integration_links do
    nested = configuration[:nested]
    desc
"Retrieve blah for #{nested}" do
      detail <<~NOTE
        Returns a collection of blah for #{nested}
     
NOTE
    end
    get do
      p = declared(params)
     
case configuration[:nested]  # was options[:for].configuration[:nested] for v1.2.3
     
when :project
      when :integration
      else
        raise ArgumentError, 'Endpoint mounted incorrectly'
      end
    end
  end
end

I have this specific "endpoint" mounted 2 times

(inside my integrations endpoints)
mount Resources::IntegrationProjectLinks, with: {nested: :integration, path: :project_links}

(Inside my Projects endpoints)
mount Resources::IntegrationProjectLinks, with: {nested: :project}

We have many other endpoints that are mounted multiple times. e.g. a "Tasks" that is mounted 3 times. Once under project, once under orgs, and once at the root (for shallow) w/o any with: {} params.

class Tasks < Grape::API
  resource :tasks do
    nested = configuration[:nested]

   
if configuration[:nested].present?
      desc
"retreive tasks for #{nested}"
      params do
        use :user_ids_filter
      end
      get do
        case configuration[:nested]
       
when :organization
          scope = org_scope
       
when :project
          scope = project_scope
       
else
          raise ArgumentError, 'Endpoint mounted incorrectly'
        end
       
        # rest of logic + present
      end
    end
  end
end

class Project < Grape::API
  resource :projects do
    nested = configuration[:nested]

   
if configuration[:nested]
     
# nested routes
      get do
       
      end
    else
      # shallow routes
      params do
        requires :project_id, type: Integer
      end
      resource ':project_id' do
        # shallow get/update/etc.
     
        mount Resources::Tasks, with: {nested: :project}
     
end
    end
  end
end

My question is.. All of this seems to work fine on Grape 1.3.x so far (we have many other things we are fixing in the upgrade to grape 1.3.x still)
But the documentation seems to imply I should be using mounted/given.
So is there something I'm missing in the documentation as to when/why I should be using given/mounted?


Daniel D.

unread,
Mar 12, 2020, 12:44:31 PM3/12/20
to Grape Framework Discussion
Given and mounted are synonyms, except that given evaluates a condition. See https://github.com/ruby-grape/grape/blob/002280415a46b1cabea565533141298781a48553/lib/grape/api/instance.rb#L17. These create a block that is evaluated lazily, later.

Resource is an alias for namespace, https://github.com/ruby-grape/grape/blob/002280415a46b1cabea565533141298781a48553/lib/grape/dsl/routing.rb#L165. And only serves the purpose of introducing a prefix. 

I am not completely clear how these interact, looking forward to a better answer from someone on the list!



--
You received this message because you are subscribed to the Google Groups "Grape Framework Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-grape+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ruby-grape/badbda69-a05d-4fe6-ad48-b243c3f89790%40googlegroups.com.


--

Edward Rudd

unread,
Mar 12, 2020, 3:02:47 PM3/12/20
to Grape Framework Discussion
I guess my main concern is, by not using them is it going to cause problems in future grape release? (since all my mount params are fixed symbols) Or should I always be using them?  (e.g. it isn't very clear what problem given/mount are trying to solve to me)
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-...@googlegroups.com.

Daniel D.

unread,
Mar 12, 2020, 6:17:40 PM3/12/20
to Grape Framework Discussion
If you have time, dig deeper and help us understand the differences in the code, maybe find an example where it works with one and not the other. 

To unsubscribe from this group and stop receiving emails from it, send an email to ruby-grape+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ruby-grape/07cb861f-9ad5-4695-b49a-4b7ccb596e31%40googlegroups.com.

Nico Klein

unread,
Mar 13, 2020, 2:51:18 PM3/13/20
to ruby-...@googlegroups.com
Hi, let me weight in :D 

The configuration[:xyz] params will only have the correct param on MOUNT time rather than LOAD time (there's a subtle, but important difference!)

When we are preparing and endpoint to be remounted, we make an attempt to figure out which stuff depends on configuration params (and cannot be resolved on class load time)

If the arguments to the method are JUST configuration (like in your case) `i.e. resource configuration[:blahblah] do ....`
The setup prepare will know not to load that right away, so you dont need the `given` or `mounted` blocks.

However, if you were doing string interpolation, or any other operations on the result of the configuration (i.e. "resource_name#{configuration[:foo]}" ), we can't wait until the configuration value is resolved to execute it (as ruby will attempt to execute right away). Therefore, in those cases it is suggested you use a quick block, like `mounted {  "resource_name#{configuration[:foo]}" }` which will be not be evaluated right away, but rather, when the endpoint is actually mounted.

TLDR
```
class API < Grape::API
  resource configuration[:foo] do
   ...
  end
end
```
is FINE

However,
```
class API < Grape::API
  resource method_that_runs_immediately(configuration[:foo]) do
   ...
  end
end
```
requires you to switch for a block like
```
class API < Grape::API
  resource(mounted { method_that_runs_immediately(configuration[:foo]) }) do
   ...
  end
end
```

Hope that clarifies things,

Best,

Nicolas Klein

Edward Rudd

unread,
Mar 16, 2020, 1:23:30 PM3/16/20
to Grape Framework Discussion
Nico,

Thanks for the response. that does help better explain things. Ill ponder on this some more  and see if I can submit a PR to make the docs more clear.
Reply all
Reply to author
Forward
0 new messages