Reputation: 3396
I am attempting to add a custom middleware route to an existing Loopback application, but seeing strange errors using my local domain mapping, but everything works fine on localhost:3000.
My setup is using nginx as a proxy server using
location /api {
proxy_pass http://localhost:3000;
}
I have added the example server/boot/aroutes.js file from the Add a custom Express Route docs page:
module.exports = function(app) {
// Install a "/ping" route that returns "pong"
app.get('/ping', function(req, res) {
res.send('pong');
});
}
My server/boot looks like this, so aroutes.js is alphabetically first:
server/boot/
aroutes.js
authentication.js
rest-api.js
My app and the /api same domain proxy work as intended for the app when called by AngularJS, but I can't seem to get a custom Express route to work when called via https://domain.com/api/ping, but it works fine when I use http://localhost:3000/ping.
Using http://localhost:3000/ping
I get
But using the full mock domain over the nginx ssl proxy, it does not take the same route:
{
"error": {
"name": "Error",
"status": 404,
"message": "There is no method to handle GET /ping",
"statusCode": 404,
"stack": "Error: There is no method to handle GET /ping
at restUrlNotFound (/Users/notbrain/src/proteus/node_modules/loopback/node_modules/strong-remoting/lib/rest-adapter.js:332:17)
at Layer.handle [as handle_request] (/Users/notbrain/src/proteus/node_modules/loopback/node_modules/express/lib/router/layer.js:82:5)
at trim_prefix (/Users/notbrain/src/proteus/node_modules/loopback/node_modules/express/lib/router/index.js:302:13)
at /Users/notbrain/src/proteus/node_modules/loopback/node_modules/express/lib/router/index.js:270:7
at Function.proto.process_params (/Users/notbrain/src/proteus/node_modules/loopback/node_modules/express/lib/router/index.js:321:12)
at next (/Users/notbrain/src/proteus/node_modules/loopback/node_modules/express/lib/router/index.js:261:10)
at jsonParser (/Users/notbrain/src/proteus/node_modules/loopback/node_modules/body-parser/lib/types/json.js:96:40)
at Layer.handle [as handle_request] (/Users/notbrain/src/proteus/node_modules/loopback/node_modules/express/lib/router/layer.js:82:5)
at trim_prefix (/Users/notbrain/src/proteus/node_modules/loopback/node_modules/express/lib/router/index.js:302:13)
at /Users/notbrain/src/proteus/node_modules/loopback/node_modules/express/lib/router/index.js:270:7"
}
}
Is this expected behavior? How can I get the two to be equivalent? Seems like two issues here
UPDATE 6/24: More explicit nginx config used here:
http {
# ...snip logging etc... #
upstream api {
# loopback api on port 3000
server localhost:3000;
}
upstream app {
# browser-sync frontend for dev on port 3001
server localhost:3001;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl;
server_name dev.app.proteus.com;
ssl_certificate ssl/dev.app.proteus.com.crt;
ssl_certificate_key ssl/dev.app.proteus.com.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
# ----- PFS ----- #
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
location / {
# proxy_pass to connect server spawned by gulp browserSync ------------
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /api {
proxy_pass http://api;
}
}
}
Upvotes: 0
Views: 3609
Reputation: 4879
You may want to use the upstream
in nginx config.
In your loopback config for that environment, change host
parameter to server name. Then in your nginx config upstream, instead of localhost:{port}
, change to the same server name.
For example in server/config.test.js
for test environment (export NODE_ENV=test
before starting server), you could override the default host:
module.exports = {
host: "app3",
...
}
Then in your etc/nginx/conf.d/{app-name}.conf
file (good to create one per app), you can have something like this:
upstream my-app {
server app3:3000;
}
server {
listen 80;
server_name your-server-domain.com;
# custom handlers for internal apps
# add stuff as needed below
#
location ^~ / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://my-app;
}
}
Now you could always change the location
param to not be global and just use /api
but same handling. The trick is the Loopback config host
param must match the host declared in your upstream of nginx config.
Upvotes: 1
Reputation: 2692
This does not appear to be a Loopback specific issue, but more related to Nginx and how its setup. To verify this, try creating a simple Hello World app in Node.js to see if you get the same error.
Upvotes: 1