Getting a POST 404 error on back-end server (MERN STACK) - reactjs

I'm attempting to send a complete form to back-end server (decoupled MERN application in localhost).
The request is reaching the server, but not posting to the database.
This is seen in server console...
POST /contracts 404 1.371 ms - 19
The data to be sent in form is logging in console as an object (as intended).
This is the service function making post request from the frontend to the backend ...
const BASE_URL = `${process.env.REACT_APP_BACKEND_SERVER_URL}/contracts`
export const createContract = async (formData) => {
try {
const res = await fetch(BASE_URL, {
method: 'POST',
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${tokenService.getToken()}`
},
body: JSON.stringify(formData)
})
return await res.json()
} catch (error) {
console.log(error)
throw error
}
}
this is the backend routes... (already set up as /contracts in server.js)
import { Router } from 'express'
import * as contractsCtrl from '../controllers/contracts.js'
const router = Router()
router.post('/', contractsCtrl.create)
router.get('/all', contractsCtrl.index)
export { router }
create controller function on the backend...
function create(req, res) {
console.log(req.body)
Contract.create(req.body)
.then(contract => res.json(contract))
.catch(err => res.json(err))
}
Any help you have would be appreciated!!

Related

NextJS API Endpoint Error - 'API resolved without sending a response for /api/foo, this may result in stalled requests.'

This is the code I am using
// function calling the api endpoint within a button onClick event handler
async () => {
const response = await fetch('/api/foo', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
})
const responseData = await response.json()
}
// /api/foo.js
import { ref, uploadString } from 'firebase/storage'
import { storage } from './firebase'
export default async function handler(req, res) {
const data = req.body
const storageRef = ref(storage, data.ID)
const uploadTask = uploadString(storageRef,
JSON.stringify(data.object)
).then(snapshot => {
res.status(200).json(
{ message: 'Saved!', severity: 'success' })
res.end()
}
)
}
When a request is sent to the above API endpoint, the console in vscode shows that a request was sent with this error: API resolved without sending a response for /api/foo, this may result in stalled requests.
What does this mean and how is it fixed?
Thanks in advance!
Edit - added async to handler function, but error still showing

CORS error while trying to post data with Axios on AWS REST API configuration using a node.js Lambda function

I'm posting data to a DynamoDB table with axios in a React front-end.
The API is set up through a serverless configuration with an API Gateway and Lambda on AWS.
While the request goes through and I see the added item on the database I still get a CORS error https://i.stack.imgur.com/m7yMG.jpg
This is the axios method:
import axios from "axios";
export const sendItemToDB = async (_data) => {
if (!_data) { return };
try {
const res = await axios({
method: "POST",
url: process.env.REACT_APP_QUERY_API,
data: _data,
headers: {
"Content-Type": "text/plain"
},
});
console.log("data returned from api", res);
} catch (error) {
console.log("Error sending File to db: ");
console.log(error);
}
};
And the API method on Lambda:
const createRecord = async (event) => {
const response = { statusCode: 200 };
try {
const body = JSON.parse(event.body);
const params = {
TableName: process.env.DYNAMODB_TABLE_NAME,
Item: marshall(body || {}),
};
const createResult = await db.send(new PutItemCommand(params));
response.body = JSON.stringify({
message: "Successfully created record.",
createResult,
});
} catch (e) {
console.error(e);
response.statusCode = 500;
response.body = JSON.stringify({
message: "Failed to create record.",
errorMsg: e.message,
errorStack: e.stack,
});
}
return response;
};
I based this configuration on this tutorial : https://github.com/jacksonyuan-yt/dynamodb-crud-api-gateway
I solved this following amazon documentation and reconfiguring the serveless deployment yml.
Serverless documentation on api gateway and lambda proxy integration here
Adding the missing headers to all lambda functions was essential.
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Headers" : "Content-Type",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET"
},
};
Also testing that OPTIONS is working for the preflight:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-test-cors.html
Just as Stavros noticed, the problem is that this is not a simple cross-origin POST method request (because it contains custom headers), so you need to tweak CORS settings of AWS API Gateway by adding
"POST, GET & OPTIONS" for Access-Control-Allow-Methods
"content-type" for Access-Control-Allow-Headers
You can do it through console like this
You also might need to add those headers in lambda like this
and it will work.

Frontend and backend url not matching

I have a problem with matching routes. I am runnning react app on port localhost:3000, and node/express server is running on port localhost:3001.
I am trying to create a club by firing this request on the frontend:
async addClub(club) {
try {
let postData = await fetch(`${this.backendUrl}/club`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({...club}),
});
this.backendUrl is correctly imported
Route on the backend file is:
router.post('/club', async (req, res) => {
try {
const body = req.body;
await new Club(body).save((err, club) => {
if (err) return console.log(err)
console.log('New club created');
res.status(200).send({ msg: 'Club created' });
});
} catch(err) {
res.status(400).json({
msg: 'Bad Request'
})
}
})
But for some reason frontend execution cannot find route specified on the backend.
I get an error: POST http://localhost:3001/club 404 (Not Found)
I have other routes through which I create other things and they work perfectly.

react admin returns Unauthorized 401 error upon CRUD operations

I am working on a react-admin project. The backend is written using Django rest framework which runs on a docker container. The authentication endpoints for access and refresh tokens are written using djangorestframework-simplejwt and served at http://localhost:8000/api/token/ and http://localhost:8000/api/token/refresh/ respectively.
I have written my own authProvider.js and dataProvider.js for react admin. The login and checkAuth functions for authProvider.js looks like this
// in src/authProvider.js
import jwt from "jsonwebtoken";
export default {
login: async ({ username, password }) => {
const request = new Request('http://localhost:8000/api/token/', {
method: 'POST',
body: JSON.stringify({ username, password }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
const response = await fetch(request);
if (response.status < 200 || response.status >= 300) {
throw new Error(response.statusText);
}
const { refresh, access } = await response.json();
localStorage.setItem('refreshToken', refresh);
localStorage.setItem('accessToken', access);
},
logout: ...
checkAuth: async () => {
const accessToken = localStorage.getItem('accessToken');
const refreshToken = localStorage.getItem('refreshToken');
if (accessToken && refreshToken) {
const { exp } = await jwt.decode(accessToken);
if (exp > (new Date().getTime() / 1000) - 10) {
return Promise.resolve();
} else {
const request = new Request('http://localhost:8000/api/token/refresh/', {
method: 'POST',
body: JSON.stringify({ "refresh": refreshToken }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
const response = await fetch(request)
.then(response => {
if (response.status !== 200) {
throw new Error(response.statusText);
}
return response.json();
})
.then(({ token }) => {
localStorage.setItem('accessToken', token);
return Promise.resolve();
});
return response;
}
}
return Promise.reject();
},
checkError: ...
getPermissions: () => Promise.resolve(),
}
Retrieving data works fine. But whenever I perform a create, edit and delete operation, I am automatically logged out with a 401 Unauthorized error. Error message from docker server log
Unauthorized: /api/products/2
"PUT /api/products/2 HTTP/1.1" 401
Error from browser console: PUT HTTP://localhost:8000/api/products/2 401 (Unauthorized)
Prior to adding authProvider and using docker container as backend, CRUD data mutations worked fine, using a local python venv as backend. So I assume the dataProvider.js is not responsible here.
I have not been able to figure this out for quite some time. Can anyone help me figure out what I might be doing wrong here? Thank you for your time.
EDIT 1: It seems the access token is not sent from the frontend during API request, hence the server returning 401 Unauthorized
You need to modify your dataProvider to include the token (in a token, a cookie, or in a GET parameter, depending on what your backend requires). This is explained in the react-admin auth documentation:
import { fetchUtils, Admin, Resource } from 'react-admin';
import simpleRestProvider from 'ra-data-simple-rest';
const httpClient = (url, options = {}) => {
if (!options.headers) {
options.headers = new Headers({ Accept: 'application/json' });
}
const { token } = JSON.parse(localStorage.getItem('auth'));
options.headers.set('Authorization', `Bearer ${token}`);
return fetchUtils.fetchJson(url, options);
};
const dataProvider = simpleRestProvider('http://localhost:3000', httpClient);
const App = () => (
<Admin dataProvider={dataProvider} authProvider={authProvider}>
...
</Admin>
);

Unable to fetch Data in Netlify Dev Proxy (React)

I've been having CORS error when deploying my app so I decided to try out Netlify Dev.
I followed all steps of the written tutorials but I keep getting errors without being able to identify whats wrong. I haven't even deployed it yet and right now I am having the 403 error, before this was the 500 internal server error.
Please let me know if you notice any obvious mistake on my part.
Here's the node-fetch code:
const fetch = require("node-fetch");
exports.handler = async function () {
const headers = {
"x-api-key": process.env.REACT_APP_MY_API_KEY,
"content-type": "application/json",
};
try {
const response = await fetch("https://api.crimeometer.com", { headers });
if (!response.ok) {
return { statusCode: response.status, body: response.statusText };
}
const data = await response.json();
return {
statusCode: 200,
body: JSON.stringify(data),
};
} catch (err) {
console.log(err);
return {
statusCode: 500,
body: JSON.stringify({ msg: err.message }),
};
}
};
Here's the frontend of my app (with the relevant code):
const initializeApp = useCallback(() => {
async function fetchData() {
try {
let req = new Request(
`./.netlify/functions/node-fetch?lat=${lat}&lon=${lon}&distance=10km&datetime_ini=${newdateyear}&datetime_end=${newdatenow}&page=1`);
const res = await fetch(req);
const info = await res.json();
setCrimes(info.incidents);
} catch (err) {
console.log(err);
}
}
}, [submit, lat, lon]);
useEffect(() => {
initializeApp();
}, [initializeApp]);
This is the error in my console:
This is where i am trying to fetch data from:
https://api.crimeometer.com/v1/incidents/raw-data?lat=${lat}&lon=${lon}&distance=10km&datetime_ini=${newdateyear}&datetime_end=${newdatenow}&page=1
It requires two headers to be set on frontend, which I have done in the netlify function
The API key is currently being added to the React side, where it sets a header and makes a call to the netlify function. But the API key is actually required at the netlify function to request the third party API.
So you have to move the request header from React to Netlify function with something like:
const headers = {
'x-api-key': API_KEY,
'content-type': 'application/json',
}
const response = await fetch(
"https://api.crimeometer.com/v1/incidents/raw-data",
{ headers }
);

Resources