Can the API Gateway evaluate requests and route or return errors (not 200 statuses) on specific parameters?
What I want to achieve here is to NOT have millions of requests hitting our backend API since we already know (by evaluating the parameters) that we are not interested in returning responses on all requests but only a few percent.
I gave set up an API Proxy in the API Gateway with a complete set of requests, responses and backend.
The proxy is fully operational and up and running with throttling etc. What I would like is for the API Gateway to evaluate the requests querystring and depending on the values of certain parameters take different actions?
Let's say the complete URL and querystring is:
https://abc123.execute-api.eu-central-1.amazonaws.com/prod?param1=a¶m2=b¶m3=c
Now depending on the values of param1, param2 and param3 I might want to:
Forward the request to my actual API and return a response back to the client.
Drop the request OR return an empty (or templated) response with a specific HTTP-status (404, 503 etc - exact value not that important).
Is this achievable with the API Gateway or do I need to actually set up a host with a reverse proxy and let that handle this logic?
Request parameter and model validation has been a longstanding feature request and we are actively working on it. We'll update this post with more details when the feature has launched.
Update: Request parameter and body validation is now available as of early April 2017. see more details on this blog post.
Related
i have api gateway with 3 simple backends:
2 basic api routes (/plus and /minus) backed by lambda functions
1 direct sqs queue (/sqs_send)
It means i can send via api call directly to my sqs queue.
2 lambda backend functions take 2 params 'a,b' from api call and add,subtract and show output.
https://86bwtlv5ya.execute-api.us-east-1.amazonaws.com/minus?a=10&b=20 # prints -10 in browser
https://86bwtlv5ya.execute-api.us-east-1.amazonaws.com/plus?a=10&b=20 # prints 30 in browser
The 3rd function is tricky for me. Via postman i managed to send directly to sqs like this via put request. Notice how i have to select "body" "raw" then input message. I did check the sqs queue - the msg from postman is there.
My question - what to type into my api gateway endpoint to send msg directly to sqs? Without using postman?
https://86bwtlv5ya.execute-api.us-east-1.amazonaws.com/sqs_send?mesagebody # what to type after sqs_send?
This did not work - returns {"message":"Not Found"}
https://86bwtlv5ya.execute-api.us-east-1.amazonaws.com/sqs_send?
Action=SendMessage&
MessageBody=This+is+a+test+message
Is it possible, my sqs_send api route does not work with parameters, because it is designed to only work with "messagebody" as per my settings? "Message attributes" is empty?
If I understood correctly, you want to call your API gateway endpoints by directly entering the URL into your browser's address bar.
Short answer:
Unfortunately you can't do this with your 3rd endpoint /sqs_send, because it is a PUT endpoint which the browser cannot call directly through the address bar.
Details:
Browsers usually support only HTTP GET and POST methods directly, through form submissions (which in turn is an HTML limitation, where form submissions only support these two methods). In GET method, parameters are appended to the end of the URL in the pattern example.com/?name1=value1&name2=value2. In POST method, parameters are included in the body of the request, so they're not visible in the URL itself. This means that you can only call GET endpoints by directly typing into the address bar of your browser. Your /plus and /minus are likely GET endpoints. POST endpoints must be called via HTML form submissions to include your parameters.
For calling other methods like PUT and DELETE (in addition to GET and POST), you will have to use XMLHttpRequest or the Fetch API, or some frontend framework method built around them. As your Postman screenshot shows, your third endpoint /sqs_send is a PUT, so you can't call it directly by entering the URL into the browser's address bar. If you must call it this way, you will have to convert your endpoint to a GET so that you can send your parameters via URL parameters.
I am trying to set-up API Gateway + Lambda Proxy + Cache and having issues with it.
Firstly it doesn't seem to be hitting the cache. Oddly when I use chrome dev tools to hit it and click 'disable' cache, it somehow does hit the cache! The difference is it sets the cache-control to 'none'. A normal requests it sets cache-control to 'max-age=0'.
Secondly when it does cache, its ignoring the URL parameter as a key so with different querystring values, it still returns the same response.
I have enabled the API Cache on the stage settings, I have also entered the 'querystrings' in the Method request settings as well and turned on the 'caching' checkbox for each querystring parameter.
Any thoughts on this? If this does not work I may have to resort to using Elasticache internally but it would have been great if API Gateway could handle this directly.
My API request are 'GET' requests with querystring parameters.
This should have been such a simple issue and I don't understand why it hasn't come up through all my searching (maybe it's just been a long day).
I have an API Gateway API setup, and I am adding a Body Mapping Template to my Integration Response for a 400* error group: see image -
All I would like to get is the StatusCode of the current response (as this is a 400* group - e.g. 401 / 403 / 404 etc.)
The closest I came was through this site: AWS help documentation and I thought I would be able to use something like $context.statusCode - but no luck.
Am I going crazy, or is this just not something required often?
PS - Making changes to any Lambda functions being called, is not an option.
Thanks
There's currently no mapping template variable in API Gateway dedicated to the integration response status code.
We will certainly add this as a feature request.
At current time you are limited to hardcoding the status code value in your response templates. You would either need to define generic status codes (i.e "4XX") or define integration responses for every status code you want to capture. While this seems tedious, this could be managed relatively easily in a Swagger template.
At current time the only way to see the integration response status code is via CloudWatch Logs.
Thanks,
Ryan / Amazon API Gateway
If you are sending error codes from your server then you can easily map them.
I have done something similar but I have used different trick to do. I used to send my own error entities and codes from server.
You have to map those error entities and error codes coming from server to the response that comes from amazon servers. I will try and explain what I mean by this. Api Gateway doesn't send response coming from your own server to the client automatically. You have to map those responses. For example, map 200 as a SUCESS and response entity will be default, that is whatever coming from server.
Now, we default success response is managed but what about error codes and error entities. You have to map them manually.
There are two ways you can do this,
One is manual, go to your api. Create error entities or models. Map them manually for each response code.
This one uses swaggger,
Solution is to import swagger specification of error entities. Add response templates to the swagger specification and let amazon do their job.
I can help you more with swagger. It depends how you are setting up your api on amazon.
Visit this for amazon extenstions to swagger,
http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions.html#api-gateway-swagger-extensions-integration-response
We are trying to build a REST interface that allows users to test the existence of a specific resource. Let's assume we're selling domain names: the user needs to determine if the domain is available.
An HTTP GET combined with 200 and 404 response codes seems sensible at first glance.
The problem we have is discriminating between a request successfully served by our lookup service, and a request served under exceptional behaviour from other components. For example:
404 and 200 can be returned by intermediary proxies that actually block the request. This can be due to proxy misconfiguration, or even external infrastructure such as coffee shop Wifi using poor forms-based authentication.
Clients could be using broken URLs. This could occur through deprecation or (again) by misconfiguration. We could combat the former through 301, however.
What is the current best practice for discriminating between responses that have been successfully fulfilled against the client's intention for that request, and responses served through exceptional behaviour?
The problem is eliminated by tunnelling responses through the response body, as we can ensure these are unique to our service. However, doesn't seem very RESTful!
Simply have your application add some content to its HTTP responses that will distinguish them from the responses thrown by intermediaries. Any or all of these would work:
Information about the error in the response content that is recognizable as your application's content (for example, Application error: Domain name not found (404))
A Content-Type header in the response that indicates that the response content should be decoded as an application error (for example, Content-Type: application/vnd.domain-finder.error+json)
A custom header in the response that indicates it is an application error
Once you implement a scheme like this, your API clients will need to be aware of the mechanism you choose if they want to react differently to application errors versus infrastructure errors, so just document it clearly.
I tend to follow the "do what's RESTful as long as it makes sense" line of thinking.
Let's say you have an API that looks like this:
/api/v1/domains/<name>/
Hitting /api/v1/domain/exists.com/ could then return a 200 with some whois information.
Hitting /api/v1/domain/doesnt.com/ could return a 404 with links to purchase options.
That would probably work. If the returned content follows a strict format (e.g. a JSON response with a results key) then your API's responses can be differentiated from your proxies' responses.
Alternatively, you could offer
/api/v1/domains/?search=maybe
/api/v1/domains/?lookup=maybe.com
This is now slightly less RESTful but it's still self-describing and (in my opinion) not that bad. Now every response can be a 200 and your content can reveal the results.
I'd like to put some kind of caching reverse proxy in front of a SOAP webservice
over HTTP to improve both performance and availability.
Is there some software that
performs this? (Preferably free and easy to install/use).
The idea is here: the responses of the webservice vary with the request, but
for each request the responses rarely change. So the proxy could
store the responses for each request for some time, and give the cached
response when the same request is sent again. There is only a limited number
of different requests.
The proxy does not need to parse and understand the request or response.
But it does need to understand HTTP POSTs and, say, construct a hash
of the request in order to find the correct response. Caching by the URL,
as done normally in HTTP Proxies, does not help here.
(Of course one can cache the webservice's results in the application
that calls the webservice, but I am looking for a solution that is
standalone, independent from the application.)
Try Ventus Proxy For Webservices. it does exactly what you need.
http://www.ventusproxy.com
I'm not sure if it works with SOAP or not, but check out Varnish. It's a very powerful cache/reverse proxy.