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

Added support to API proxies. #21

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

leods92
Copy link
Contributor

@leods92 leods92 commented Nov 1, 2014

API Proxies are services that work in the middle between your clients and your API server.
They are useful for handling some API-exclusive logic so that you don't have to such as usage statistics, authentication, etc.
Some examples of API Proxies are: Apigee, 3scale and Mashery.

Current version of api-pagination generates links based on request.url but when we use a proxy that generate direct links to the API server which we don't want to expose (and which you probably made it unaccessible to outsiders anyway).

My approach to solve this problem was pretty simple: provide the option to generate relative links.
Relative links are allowed according to the Web Linking RFC5988.
So there's now an option :relative_uri which should be set to true if user so desires.

Another issue that I've stumbled upon was the base path.
Many APIs probably set a different domain such as api.example.com which makes all paths the same when using a proxy (unless you set something else in the proxy).
Other APIs though are nested in the main domain (e.g. example.com/api), maybe to be able to use SSL without new or expensive certificates.
That said, we should be able to hide such "/api" base path because from the client perspective (accessing through the proxy) that base path doesn't exist. More details in code comments.
I made that possible through the option exclude_base_path.

I've also added proper tests and they all pass.
This solution is already successfully being used in a production app of mine.

Hope this helps everyone.

@davidcelis
Copy link
Owner

Hey @leods92, sorry it's taken me a while to respond. Thanks for this contribution! To be totally honest, though, I'm not sure I follow what issue this patch is fixing. I don't suppose you have a really specific case you could walk me through, and maybe how your code would look given your patch?

@leods92
Copy link
Contributor Author

leods92 commented Dec 5, 2014

Hey, @davidcelis.
It's really okay, thank you for maintaining this great gem. :)

If someone is using an API proxy the URL a consumer actually hits is the proxy one not the application one. That said, pagination URLs cannot be generated based on incoming requests but based on proxy's request. As each proxy work differently and we want to keep things simple, I simply removed the domain. So we don't have to find out proxy's base URL.

Example:
My application has an API URL:
mycoolwebsite.example.com/api/v1/locations.json

But that resource is private and only accessible through a proxy whose URL is:
mycoolwebsite.apigee.net/v1/locations.json

Consumer expects pagination URLs to be mycoolwebsite.apigee.net/v1/locations.json?p=2, mycoolwebsite.apigee.net/v1/locations.json?p=3, etc.
But without my patch the gem returns mycoolwebsite.example.com/api/v1/locations.json?p=2, mycoolwebsite.example.com/api/v1/locations.json?p=3, which are resources only accessible by proxy.

With my patch people can simply not include the base API path and yet get valid URL paths that they can mount with host on their end. To get the relative and not absolute URL I added the : relative_uri option.

I also added the :exclude_base_path which allows us to change the base path of an API which may change when one uses API proxies.

@davidcelis
Copy link
Owner

Okay, that use-case makes sense. But that does make me wonder how your application currently generates its own URLs... Wouldn't they also be incorrect and include the api/ fragment instead of generating URLs for the proxy? I wonder if there's a more portable way for me to take advantage of Grape here?

Also, does this not also need changes on the Rails side of the gem?

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

Successfully merging this pull request may close these issues.

2 participants