By using AWS re:Post, you agree to the AWS re:Post Terms of Use

Express JS 404 API Gateway/Lambda Function

0

Hello all,

I have been stuck with this error for a few days and have reached the end of my rope. I am brand new to AWS so I apologize if this is an obvious solution.

I am building a simple react app that calls my API Gateway sending a POST with the endpoint /submit-form

I get 200 status code for the preflight CORS and the same 200 for the request in devtools but return JSON of a 404 in Lambda/Dev tools console

I'm not sure if this is necessary but I did zip my lambda function with my node_modules

Response

{
  "statusCode": 404,
  "headers": {
    "x-powered-by": "Express",
    "access-control-allow-origin": "*",
    "content-security-policy": "default-src 'none'",
    "x-content-type-options": "nosniff",
    "content-type": "text/html; charset=utf-8",
    "content-length": "139"
  },
  "isBase64Encoded": false,
  "body": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot GET /</pre>\n</body>\n</html>\n"
}

Lambda Function

const express = require("express");
const serverless = require("serverless-http");
const cors = require("cors");
const fs = require("fs");
const OpenAI = require("openai").default;
const pdfService = require("./service/pdf-service");
require("dotenv").config({ path: ".env.local" });
const app = express();
const openai = new OpenAI({
	apiKey: process.env.OPENAI_API_KEY,
});

// Middleware
// app.use(cors());
app.use(express.json());

// Form Submit Action
app.post("/submit-form", async (req, res) => {
	const { goals, height, age, gender } = req.body;
	const formData = { goals, height, age, gender };
	console.log(formData);
	// Creates the custom workout call to OpenAI
	const response = await openai.chat.completions.create({
		model: "gpt-3.5-turbo",
		messages: [
			{
				role: "system",
				content: "You are a online personal trainer",
			},
			{
				role: "user",
				content: `Define a workout/nutrition regimen based on the provided data. Also, before giving a regimen, provide a health disclaimer that users should consult a physician and proceed at their own risk. This is only a health AI project. Goals: '${goals}', Height: '${height}'Age: '${age}', Gender: '${gender}'`,
			},
			{
				role: "assistant",
				content:
					"Health Disclaimer: ...",
			},
		],
		temperature: 1,
		max_tokens: 3050,
		top_p: 1,
		frequency_penalty: 0,
		presence_penalty: 0,
	});
	console.log("OpenAI Object", response);
	// Form response
	console.log("OpenAI Response:", response.choices[0].message.content);
	// Generate Form into a PDF
	const stream = fs.createWriteStream("TrAIner-workout.pdf");
	pdfService.buildPDF(response.choices[0].message.content, stream);
	stream.on("finish", () => {
		res.setHeader("Content-Type", "application/pdf");
		res.setHeader(
			"Content-Disposition",
			"inline; filename=TrAIner-workout.pdf"
		);

		fs.createReadStream("TrAIner-workout.pdf").pipe(res);
	});
});

module.exports.handler = serverless(app);
1 Answer
0

Hi,

Since you are starting out on AWS, you could build a serverless api on Lambda-NodeJs runtime without ExpressJS using an API Gateway. Pls look at the relevant examples in this [guide].(https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-with-lambda-integration.html)

You should then be able to build a light Lambda layer containing only the pdf utility and the OpenAI client.

P.S: You could also consider using Amazon Bedrock for your use-case. Pls refer the invokemodel examples here

Thanks, Rama

profile pictureAWS
EXPERT
answered 8 months ago
profile picture
EXPERT
reviewed 8 months 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