How to fetch data from an external api (Heroku) with Next JS? - api

I'm currently developing a web application with its server and the web application deployed separately. I've deployed my server and the database on Heroku, whilst I used Vercel to deploy my Next JS application.
My problem is when I make a request from Vercel using isomorphic-unfetch, it adds the address of my application in the request (https://myapp.vercel.app/myapp.herokuapp.com/). I only want http://myapp.herokuapp.com to be the request.
This is how I wrote the code for it.
import fetch from 'isomorphic-unfetch'
const host = process.env.API_ENDPOINT -- in this case, it was myapp.herokuapp.com
const myFunction = async(data) => {
const request = host.concat('/postSomething');
const res = await fetch(
request,
{
body: JSON.stringify({
variableA: data.variableA,
variableB: data.variableB
}),
headers: {
'Content-Type': 'application/json'
},
method: 'POST'
}
);
return await res.json();
}

Apparently, it was just a syntax error in my next.config.js file.
I included 'https://' before 'myapp.herokuapp.com' when I declared the API_ENDPOINT, and now it works.

Related

Frontend to Backend POST request is not yielding the data I want

I'm currently working on a project using a React frontend and an Express backend. Currently, when I make a GET request to retrieve data from the backend, everything is working fine. However, I'm unable to POST data to the backend and gain access to the data that's being sent. I'm getting an OK message so the request is going through, but when I log the request data in the backend, I get a message like this which is a jumble of random fields.
Here is the code snippit in the front end for the POST request
const makePost = (data) => {
fetch('http://localhost:5000/api', {
method: 'POST',
headers: {"Content-Type": "application/json", "Access-Control-Allow-Origin": "*"},
body: JSON.parse(JSON.stringify(data))
}).then(function(response){
console.log(response.text())
})
}
Here is my backend which handles the POST request
const express = require('express');
const app = express();
const cors = require('cors');
app.use(cors({
origin: '*'
}));
app.get('/api', (req,res) => {
res.json(menuItems);
});
app.post('/api', (req,res) => {
console.log(req)
})
app.listen(5000, () => console.log("server started on port 5000"));
In the code snippit above, console.log(req) is what was logged in the screenshot linked above.
In your Express server POST API, you are not returning any data, it may cause problems. This is a sample POST API using Axios, Express, React, and MongoDB.Hope it would help you.
//POST API
app.post('/services',async(req,res)=>{
const service = req.body;
const result = await servicesCollection.insertOne(service);
console.log(result);
res.send(result)
});
In client-side POST api:
const onSubmit = data => {
axios.post('http://localhost/services', data)
.then(res=>{
if(res.data.insertedId){
alert('data added successfully');
reset();
}
})
sample post API:
app.post('/book', (req, res) => {
const book = req.body;
// Output the book to the console for debugging
console.log(book);
books.push(book);
res.send('Book is added to the database');
});
Pls take a look at this link: https://riptutorial.com/node-js/example/20967/post-api-using-express

Access request body in ServerMiddleware in NUXT

Im building a simple interface to SeaTable. For security reasons, I'm not storing the DB and user keys in the code but instead set up a very lightweight API in NUXT using Server Middle wear. All is working as expected except for my login API endpoint.. I need to capture req.data but it's not available. All examples I have seen add body-phraser and Express. I don't wanna use express as I want to keep this as light as possible.
import fetch from 'node-fetch';
export default {
path: 'api/auth/login',
handler: async (req, res) => {
let requestOptions = {
method: "POST",
headers: {
"username": usr,
"password": psw
}
}
const url = 'https://MY_URL.com/api2/auth-token/'
const request = await fetch(url, requestOptions)
const data = await request.json()
res.end( JSON.stringify(data) )
}
}
I suppose since this call does not contain any keys i could just make the call on the front end capture the user token and send it to the backend to be stored. Id prefer not to expose even the URL to my seatable instance.

React Native fetch POST variables not received on server

I have tried different ways with fetch or axios to POST to my server but it seems that the post body turns empty . My initial code is this.
So the connection to the server is good. I have configured server to respond with $_POST variables received but the $_POST return empty. This happens when I use JSON.stringify on body. I have also tried with FormData and it works fine but only on iOS. On my Android device and emulator I get Possible Unhandled Promise: Network request failed error (both https and http).
And I want to make it work on both iOS and Android. So till now I have manage to send post with formData only on iOS.
Any Solutions that works on Android and iOS?
import FormData from "FormData";
export const login = (emailUsername, password) => {
var formData = new FormData();
formData.append("emailUsername", emailUsername);
formData.append("password", password);
return async dispatch => {
const response = await fetch(
"https://myserver.net/api/app/auth.php",
{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
emailUsername:emailUsername,
password:password
})
}
);
if (!response.ok) {
throw new Error("Something went wrong!");
}
const resData = await response.json();
console.log(resData);
};
};
Thanks to #bug I have find a solution. I was expecting to receive POST content to my $_POST or $_REQUEST variables on my server, but instead I had to get them this way.
$post_data = json_decode(file_get_contents('php://input'));

How to properly use passport-github for REST API authentication?

I am building a vue.js client which needs to be authenticated through github oauth using an express server. It's easy to do this using server side rendering but REST API has been troublesome for me.
I have set the homepage url as "http://localhost:3000" where the server runs and I want the authorization callback url to be "http://localhost:8080" (which hosts the client). I am redirecting to "http://localhost:3000/auth/github/redirect" instead, and in its callback redirecting to "http://localhost:8080". The problem I am facing is that I am unable to send user data to the vuejs client through res.redirect. I am not sure if I am doing it the right way.
router.get("/github", passport.authenticate("github"));
router.get(
"/github/redirect",
passport.authenticate("github", { failureRedirect: "/login" }),
(req, res) => {
// res.send(req.user);
res.redirect("http://localhost:8080/"); // req.user should be sent with this
}
);
I have implemented the following approach as a work around :-
A route that returns the user details in a get request :
router.get("/check", (req, res) => {
if (req.user === undefined) {
res.json({});
} else {
res.json({
user: req.user
});
}
});
The client app hits this api right after redirection along with some necessary headers :
checkIfLoggedIn() {
const url = `${API_ROOT}auth/check/`;
return axios(url, {
headers: { "Content-Type": "application/json" },
withCredentials: true
});
}
To enable credentials, we have to pass the following options while configuring cors :
var corsOption = {
origin: true,
credentials: true
};
app.use(cors(corsOption));

Post to /upload from react native

I'm trying to upload a picture to strapi from react native.
async function uploadPicture(uri) {
var data = new FormData();
data.append('files', {
uri: uri.replace('file://', ''),
name: uri,
type: 'image/jpg'
});
// Create the config object for the POST
// You typically have an OAuth2 token that you use for authentication
const config = {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data;'
},
body: data
};
const fetchPromise = fetch('http://<host>:1337/upload', config)
console.log(fetchPromise)
return await fetchPromise
}
I get a 200 status code but no new picture is listed on the uploads page.
Oh! I figured it out using simple-http-upload-server to test the uploads. The problem was that I was setting the name of the file to be the uri. This would probably cause an error on strapi when creating the file on the server folder. It should return an error code nonetheless.