API Gateway calls returning HTML, direct calls returning JSON

0

Hi everyone,

I have an EC2 instance running a python FastAPI HTTP API (that I developed, so can alter), with an API Gateway acting as the access point for that HTTP API to serve a frontend application. When making calls to the HTTP API on the EC2 instance directly via a browser, it returns the expected JSON with data from the associated database.

However when making the same call via the API Gateway instead, the call is returning HTML, presumably due to an error somewhere. I can see on the EC2 instance that the call via API Gateway successfully initiates the python backend functions to retrieve the data from the database, however the backend function isn't completed - but no error is thrown by the backend (or at least it isn't shown in the EC2 terminal). CloudWatch log shows no errors.

As specific examples:

http://<EC2 public IP>:8000/models/list - returns correct data

https://<api_id>.execute-api.ap-southeast-2.amazonaws.com/<stage>/models/list - returns HTML, whether through Test on API Gateway dashboard or through the frontend app making the call. The GET method on that resource has been defined as HTTP, HTTP Proxy, with and without authorization, but in all cases creates the same issue.

This was working fine a week ago before I attempted to setup a VPC Link to a Network Load Balancer in front of the EC2 instance in order to better secure calls to that HTTP backend API. I have attempted deleting the API Gateway API and building a new one, deleting all NLBs, VPC Links, Endpoints, etc, that I setup during that effort, but the issue persists. I have also not modified the python backend code since this was all working previously.

Could someone suggest some settings or configurations to check, or tests to run to better understand the issue here?

2 Answers
1
Accepted Answer

I have managed to figure this out myself (stupid mistake):

I had configured the Endpoint URL field in the Integration request settings incorrectly. I had specified just the domain (http://<EC2 public IP>:8000), incorrectly thinking that the additional URL path (http://<EC2 public IP>:8000/models/list) was appended according to the Methods and Resources setup in API Gateway. API Gateway does append those to the Method Request URL (https://<api_id>.execute-api.ap-southeast-2.amazonaws.com/<stage>/models/list), but not to the Endpoint URL.

A basic beginner mistake, but hopefully this helps someone else out!

answered 22 days ago
profile picture
EXPERT
reviewed 22 days ago
1

The issue you're experiencing, where API Gateway calls return HTML instead of the expected JSON while direct calls to the EC2 instance work correctly, could be caused by several factors:

  1. API Gateway Configuration: Ensure that your API Gateway is correctly set up to proxy requests to your EC2 instance. Check that the integration type is set to HTTP Proxy and that the endpoint URL is correct.

  2. CORS (Cross-Origin Resource Sharing): If your frontend application is hosted on a different domain than your API, you may need to configure CORS settings in both API Gateway and your FastAPI application. Make sure that the appropriate CORS headers are being set, including 'Access-Control-Allow-Origin'.

  3. VPC Link and Network Load Balancer: Since you mentioned setting up a VPC Link and NLB, verify that these are configured correctly. Ensure that the security groups and network ACLs allow traffic between API Gateway, the NLB, and your EC2 instance.

  4. FastAPI Configuration: Check your FastAPI application code to ensure it's not inadvertently returning HTML instead of JSON under certain conditions. Look for any error handling or middleware that might be intercepting the request and returning HTML.

  5. API Gateway Stage Settings: Verify that your API Gateway stage is deployed correctly and that any stage variables or settings are properly configured.

  6. CloudWatch Logs: Enable detailed CloudWatch logging for your API Gateway and examine the logs for any error messages or unexpected behavior.

  7. Network Path: Ensure that the network path from API Gateway to your EC2 instance is clear and that all necessary ports are open.

  8. HTTP vs HTTPS: Check if there's any mismatch in the protocol (HTTP/HTTPS) being used between API Gateway and your EC2 instance.

  9. Response Transformation: If you're using any response transformation in API Gateway, ensure it's not inadvertently converting your JSON to HTML.

  10. Timeout Settings: Check if there are any timeout issues. If your backend function isn't completing, it might be hitting a timeout limit in API Gateway or the NLB.

To troubleshoot:

  1. Test your API directly from the API Gateway console to isolate if the issue is with the Gateway or your client application.
  2. Use tools like Postman to make requests to both your EC2 instance directly and through API Gateway, comparing the responses.
  3. Enable and review CloudWatch logs for both API Gateway and your EC2 instance to identify where the process is breaking down.
  4. Temporarily simplify your API to return a basic JSON response to rule out issues with database interactions or complex processing.

By systematically checking these areas, you should be able to identify the root cause of the discrepancy between direct calls and those routed through API Gateway.
Sources
What causes the API response differences between my local setup and EC2, despite using the same database URL? | AWS re:Post
AWS API gateway routing | AWS re:Post
Cors policy with cloudfront + Api Gateway (VPC Links) | AWS re:Post
CORS Access-Control-Allow-Origin Header missing - Api Gateway HTTP / EC2 | AWS re:Post

profile picture
answered 22 days ago
profile picture
EXPERT
reviewed 22 days ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions