/ Node.js

Cómo servir tu API REST en Node.js a través de Nginx

Si seguimos los pasos del desarrollo web moderno, separando nuestro Frontend de nuestro Backend, realizando autenticación basada en token, utilizando un API RESTFul que sirva JSON, etc... llega un momento en que tenemos que servir nuestro API desde nuestro dominio. ¿Cómo podemos hacerlo?

Una opción es usar Nginx, no solo como servidor web o balanceador de carga, si no también como Proxy inverso para redirigir las peticiones según la URL.

Imaginemos que nuestra aplicación frontend está almacenada en el directorio de nuestro servidor /var/www/ y que tenemos nuestra API en Node.js corriendo en localhost:3000

Ahora lo que queremos que la parte cliente y todas las rutas del frontend (que pueden ser servidas con AngularJS) se sirvan a través de la ruta /. Y que nuestra API en Node.js se sirva a través de la ruta /api, en plan que si escribimos http://midominio.com/ sirva el frontend y http://midominio.com/api sirva el API y podamos hacer las peticiones AJAX a esa URL.

Esto lo conseguimos con el siguiente fichero de configuración de Nginx:

# HTTP proxy
server {
	listen 80;
	server_name midominio.com;

	access_log /var/log/nginx/nginx.access.log;
	error_log /var/log/nginx/nginx.error.log;

	client_max_body_size 5M;

	location / {
		add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";

		# Ruta de los ficheros estáticos
		root /var/www;
		try_files $uri $uri/ /index.html =404;
	}

	location /api {
		proxy_set_header 'Access-Control-Allow-Origin' 'http://midominio.com';
		proxy_set_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
		proxy_set_header 'Access-Control-Allow-Headers' 'X-Requested-With,Accept,Content-Type, Origin';

		proxy_pass http://127.0.0.1:3000;
		proxy_redirect off;
		proxy_buffering on;

		proxy_set_header	Host		$host;
		proxy_set_header	X-Real-IP	$remote_addr;
		proxy_set_header	X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header	origin		'http://midominio.com';
	}
}

Es importante, además de indicar para cada URL, que ruta tomar, los siguientes campos:

try_files $uri $uri/ /index.html =404;

Esto nos permite que el HTML5Pushstate que en ocasiones usamos en AngularJS, nos funcione. De otra manera es posible que tengamos fallos y errores cuando sirvamos las vistas del Frontend en Angular.js

proxy_set_header 'Access-Control-Allow-Origin' 'http://midominio.com';
proxy_set_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
proxy_set_header 'Access-Control-Allow-Headers' 'X-Requested-With,Accept,Content-Type, Origin';

Esto habilita CORS para nuestro API. Aunque lo tengamos habilitado en nuestra configuración de Express dentro de Node, es conveniente configurarlo en NGINX, ya que es la primera barrera que pasan nuestras peticiones HTTP y así no entramos en conflicto

proxy_redirect off;
proxy_buffering on;
proxy_set_header	origin	'http://midominio.com';

También es importante declarar estos campos, ya que si no nuestro API puede no funcionar correctamente, con redirect a off y buffering a on nos evitamos sustos.

Por último indicar la cabecera origin con la URL de nuestro dominio, para que el Cross-Origin no se vea afectado.

Carlos Azaustre

Carlos Azaustre

CTO y Cofundador de Chefly. Formador en tecnologías web: JavaScript, Node, Firebase, React y Vue.

Leer más