Ошибка 404 при вызове маршрутов API после развертывания

Я развертываю приложение Nextjs / Express на Vercel, и у меня возникают проблемы при вызове маршрутов / api. Примером может служить эта страница, которая пытается получить продукты через redux с сервера при загрузке. Это нормально работает в dev, но после развертывания я получаю ошибку 404 на всех маршрутах api.

index.js

const express = require('express');
const next = require('next');
const mongoose = require('mongoose');
const cookieSession = require('cookie-session');
const passport = require('passport');
const bodyParser = require('body-parser');
const keys = require('../config/keys');
require('../models/User');
require('../services/passport/passport');



const PORT = process.env.PORT || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

mongoose.Promise = global.Promise;
mongoose.connect(keys.mongoURI, { useUnifiedTopology: true, useNewUrlParser: true, useCreateIndex: true });

app
    .prepare()
    .then(() => {
        const server = express();

        server.use(bodyParser.json({limit: '50mb'}));
        server.use(
        cookieSession({
            maxAge: 30 * 24 * 60 * 60 * 1000,
            keys: [keys.cookieKey]
        })
        );
        server.use(passport.initialize());
        server.use(passport.session());

        const getRoutes = require('./routes/index.js');
        server.use('/api', getRoutes);
        // const routes = getRoutes();

        server.get("*", (req, res) => {
            return handle(req, res);
        })

        server.listen(PORT, err => {
            if (err) throw err;
            console.log(`> Ready on ${PORT}`);
        })
    })
    .catch(ex => {
        console.error(ex.stack);
        process.exit(1);
    })

services.js

import React from 'react';
import Head from 'next/head';
import Link from 'next/link';
import Nav from '../components/Navbar/ColorNav';
import Selector from '../components/Custom/Presentation/MapSelector';
import AppointmentMobile from '../components/Custom/Presentation/Mobile-AppointmentPresentation';
import Footer from '../components/Footer/alt-footer';
import SelService from '../components/Custom/Presentation/Presentation-service.js';

const Services = () => {
    return (
        <React.Fragment>
            <div className="services-page">
            <Head>
                <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
                <link rel="preconnect" href="https://fonts.gstatic.com" />
                <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300&display=swap" rel="stylesheet"></link>
                <title>Vohnt | Services</title>
                <meta name="keywords" content="Vohnt"/>
            </Head>
            <div className="service-header">
            <Nav popBox="services"/>
            <div className="service-selector">
            <Selector />
            </div>
            {/* <div className="mobile-service-selector">
            <AppointmentMobile />
            </div> */}
            </div>
            <div className="service-section-1">
                <div className="service-sec-1-container">
                    <h2 >Vohnt’s service offerings</h2>
                    <p className="serv-1-p">Creating a world where you have immediate, convenient, and affordable access to car care.</p>
                    <div className="serv-1-button">
                    <Link href="/how-it-works">
                    <button className="learn-more-button" id="no-border-radius">Learn More</button>
                    </Link>
                    </div>
                </div>
                <div className="vohnt-product-offerings">
                    <div className="product-list-left">
                        <SelService simpleHeight='600px' buttons="services"/>
                    </div>
                    <div className="product-list-left-small">
                        <SelService simpleHeight='420px' buttons="services"/>
                    </div>
                    <div className="product-list-left-small2">
                        <SelService simpleHeight='400px' buttons="services"/>
                    </div>
                    <div className="product-list-left-small3">
                        <SelService simpleHeight='350px' buttons="services"/>
                    </div>
                </div>
            </div>
            <div className="alt-footer-2">
            <Footer />
            </div>
            </div>
        </React.Fragment>
    )
}

export default Services;

служба презентации сообщает redux о вызове при загрузке страницы

    useEffect(() => {
        dispatch(loadProducts());
    }, [])

person Jason Maynard    schedule 23.04.2021    source источник


Ответы (1)


Вы не можете разместить приложение Next / Express на Vercel, потому что сервер Express должен работать все время, но Vercel предназначен для бессерверных функций.

Два возможных решения:

  1. Разместите свое приложение на Heroku или vps
  2. Удалите Express, просто используйте маршруты Next api, и вы легко развернете его на Vercel.

Справочная информация

person enoch    schedule 24.04.2021
comment
Не понимал, что Vercel полностью бессерверный, спасибо! смог без проблем развернуть heroku, и сейчас я изучаю, стоит ли прилагать усилия для перехода с express на nextjs api. - person Jason Maynard; 26.04.2021