I work with React.js and Node.js+Express to create a website. I use Google App Engine and Google Datastore for a database.
Everything works fine on my local machine:
React front end is able to access the API link served by Node. Node app is able to access the Datastore that runs on the cloud.
On local machine I use Proxy to port 8080 of Node so that React would be able to access the API links.
from package.json file:
"proxy": "http://localhost:8080/"
from React I make API calls using URLs:
axios.get('/api/XXX'
I use HTTP server in Express.
When I deploy my code to Google App Engine, I am not sure what changes I need to do so that React app would be able to access Node API links. Do I need a proxy in Prod? How to get SSL key and certificate from App Engine to put into Express? Should I switch right away to use HTTPS or can I still work with HTTP till I tune the rest of the building blocks to work together?
When I try to access links like:
axios.get('https://my_custom_domain/api/XXX'
then my React app is not able to access any of the API links. In Chrome console I see that React gets back 404 errors.
I use a custom domain and I see Google App Engine shows that my domain SSL security is "Google-managed, auto-renewing". In Node I use HTTP server. I would like to switch to use HTTPS, but I don't understand how I can get the Private Key and the Certificate from App Engine console to put into the Express app.
Is there a way to get the Certificate and Private key from the App Engine Console? Or should I buy a new SSL certificate from a different party/company and use it in my Express app and upload it into App Engine ?
Here is my yaml file: (server.js is my Node app)
runtime: nodejs8
handlers:
- url: /
static_files: build/index.html
upload: build/index.html
- url: /
static_dir: build
- url: /api/*
script: server.js
404 errors were about HTTPS. So I also switched from HTTP to HTTPS server. However, I have to initiate the HTTPS server without credentials, because Google App Engine doesn't allow me to see these creds.
here is what I do:
var httpsServer = https.createServer(/*credentials,*/ app);
However, I still have a 404 error:
> Failed to load https://www.XXXXX.XXX/api/v1/list: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://XXXXXXXXX.appspot.com' is therefore not allowed access. The response had HTTP status code 404.
>
I used the CORS library var cors = require('cors'); app.use(cors());
Yet, it still doesn't help and I get the cross origin error.
I also tried to introduce the following line in the App.Yaml:
http_headers:
Access-Control-Allow-Origin: https://xxxxxx.appspot.com
Yet, when I try to deploy the code, gcloud app deploy
gcloud doesn't like this header, even though it is from its official documentation :) I think because API is considered a dynamic handler and hence I can't add http_headers to it.
the error of gcloud console is:
An error occurred while parsing file: [/xxxxxx/app.yaml]
Unexpected attribute "http_headers" for mapping type script.
in "/Users/xxxxxx/app.yaml"
So I'm not sure how to fix the cross domain issue.
(I find it strange that there is no website that explains how to setup React + Node/Express in PROD for Google app engine. It is a pretty typical architecture )
js Foundation, Google develops the V8 JavaScript engine which powers Chrome and Node. js. The V8 team is working on infrastructural changes to improve the Node. js development workflow, including making it easier to build and test Node.
If you're using a custom domain with Google-managed SSL certificates, you should be able to issue HTTPS requests to your production app automatically, without dealing with any SSL keys yourself. Given that you're seeing 404's in the logs, it looks like the requests are reaching your application alright, but not being routed to the desired handler code.
There are a few issues with your app.yaml
configuration:
1. For the Node.js App Engine environment, the only valid value for the script
key of an entry under the handlers
key of the app.yaml
file is auto
(see this documentation). Also, the script
key is optional.
2. - url: /api/*
should be - url: /api/.*
See the section for the url
key in the same documentation.
3. Since App Engine attempts to match incoming requests against entries in handlers
from first to last, and since entries with static_dir
will match any request that starts with the value in url
(see the same documentation: "All URLs that begin with this prefix are handled by this handler, using the portion of the URL after the prefix as part of the file path"), a request to, for instance, /api/v1/list
will match this handler:
- url: /
static_dir: build
Thus, App Engine will try to serve a static file at build/api/v1/list
in the app code, find no such file, and return a 404
. You should re-order your handlers so that requests starting with /api
will find the API handler first.
Try this updated app.yaml
:
runtime: nodejs8
handlers:
- url: /api/.*
script: auto
- url: /
static_files: build/index.html
upload: build/index.html
- url: /
static_dir: build
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