I have 2 microservices: frontend with next.js and a backend with node.js from where I fetch data via REST-APIs from the frontend.
I now have the problem, that my 2 services don't seem to communicate directly to eachother, the thing is, it works when I fetch the data at the beginnning with the getinitialProps() Method with the fetch-API. My server-side frontend finds the backend via its service-name. However, when I am doing a http-request from the client to the backend (e.g via browser form inputs). It cannot find the backend anymore? Why is that?
here is my docker-compose.yml:
version: '3'
services:
dcbackend:
container_name: dcbackend
build:
context: ./dcbackend
dockerfile: Dockerfile
image: dcbackend
hostname: dcbackend
ports:
- '7766:7766'
dcfrontend:
container_name: dcfrontend
build:
context: ./dcfrontend
dockerfile: Dockerfile
image: dcfrontend
volumes:
- /app/node_modules
- ./dcfrontend:/app
hostname: dcfrontend
ports:
- '6677:6677'
Here is one of my browser-client side methods to send data to the backend (via the browser, my url is http:dcbackend... so normally it should find the other docker environment where the backend is, but it does not...
if (environment == 'dev') {
url_link = `http://localhost:${port}`;
} else {
url_link = `http://dcbackend:${port}`;
}
let doublettenListe_link = `${url_link}/doubletten/`;
finishDocumentHandler = (anzeige,index) => {
let thisDocumentID = anzeige.id;
const requestOptions = {
method: 'PUT'
};
fetch(doublettenListe_link + thisDocumentID, requestOptions)
.then((response) => {
this.setState({finishSuccess: 'Dubletten in Datenbank eintragen erfolgreich!'});
this.setState({finishFail: ''});
this.processDocumentArray(index);
console.log(response);
})
.catch((error) => {
this.setState({finishSuccess: ''});
this.setState({finishFail : `Error beim Erzeugen des Eintrags! Eintrag wurde nicht in Datenbank gespeichert. Bitte prüfen, ob der Server läuft. ${error}`});
});
}
Response from network tab from my request is:
Request URL: http://dcbackend:7766/doubletten/304699981
Referrer Policy: no-referrer-when-downgrade
Provisional headers are shown
Access-Control-Request-Method: PUT
Origin: http://localhost:6677
Referer: http://localhost:6677/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
does it have something to do with docker-configuration, or with CORS() or with anything else? I can't do a client http request to backend, however, the initial fetch from the backend to get some data works...
You have to separate the server side and the client side requests. You need to use your host address for the client side requests (eg. http://localhost:7766), because your browser will not be able to reach the backend via docker alias.
You can define the server-only and public runtime config with next.config.js
.
For example:
// next.config.js
module.exports = {
serverRuntimeConfig: {
// Will only be available on the server side
apiUrl: 'http://dcbackend:7766'
},
publicRuntimeConfig: {
// Will be available on both server and client
apiUrl: 'http://localhost:7766'
}
}
Then you need get the apiUrl
from nextjs with getConfig()
// pages/index.js
import getConfig from 'next/config';
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();
const apiUrl = serverRuntimeConfig.apiUrl || publicRuntimeConfig.apiUrl;
const Index = ({ json }) => <div>Index</div>;
Index.getInitialProps = async () => {
try {
const res = await fetch(`${apiUrl}/doubletten/304699981`);
const json = await res.json();
return { json };
} catch(e) {
console.log('Failed to fetch', e);
return { json: null };
}
}
export default Index;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With