Ссылка next.js на mongodb с экспресс-api

#node.js #reactjs #mongodb #express #next.js

#node.js #reactjs #mongodb #экспресс #next.js

Вопрос:

Я только что попал в Next.js и я не могу понять, как подключить мой next.js приложение с моим экспресс-API. Я смог заставить это работать, но я почти уверен, что это неправильный способ его реализации, поскольку в моем компоненте Index я жестко закодировал URL-адрес выборки, и я знаю, что в рабочей среде, если порт не тот, он не будет работать.

Я пытался указать только маршрут, но fetch API не позволяет мне этого сделать.

Моя индексная страница выглядит так

 import Link from "next/link";
import fetch from "isomorphic-unfetch";

const Index = props => (
  <>
    <h1>Youtubers</h1>
    <ul>
      {props.youtubers.map(youtuber => (
        <li key={youtuber._id}>
          <Link as={`/p/${youtuber._id}`} href={`/post?id=${youtuber.id}`}>
            <a>{youtuber.name}</a>
          </Link>
        </li>
      ))}
    </ul>
  </>
);

Index.getInitialProps = async function() {
  //                this url I think is wrong ↓
  const res = await fetch("https://localhost:5000/youtuber");
  const data = await res.json();

  return {
    youtubers: data.youtubers
  };
};

export default Index;
  

И в моем server.js У меня есть это внутри приложения.prepare().then()

 server.use(bodyParser.urlencoded({ extended: false }));
    server.use(bodyParser.json());

    mongoose.connect(process.env.MONGODB_PASSWORD, {
      useNewUrlParser: true,
      useCreateIndex: true
    });

    mongoose.connection.on("open", function() {
      console.log("mongodb is connected!!");
    });

     mongoose.connection.on(
      "error",
      console.error.bind(console, "MongoDB connection error:")
    );

    //CORS handler
    server.use((req, res, next) => {
      res.header("Access-Control-Allow-Origin", "*");
      res.header(
        "Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept, Authorization"
      );
      if (req.method === "OPTIONS") {
        res.header(
          "Access-Control-Allow-Methods",
          "PUT, POST, PATCH, DELETE, GET"
        );
        return res.status(200).json({});
      }
      next();
    });

    //Question Route
    server.use("/youtuber", youtuberRoutes);

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

    server.listen(port, err => {
      if (err) throw err;
      console.log(`> Ready on http://localhost:${port}`);
    });
  

Комментарии:

1. Похоже, что вы fetch используете https , но я не вижу https настройки в вашем приложении Express. Не видя, как youtuberRoutes определяется, невозможно увидеть, будет ли соответствующий URL-адрес соответствовать каким-либо маршрутам.

Ответ №1:

какую версию Nextjs вы используете? если это версия 9, вы можете использовать этоhttps://nextjs.org/docs#api-middlewares чтобы указать вашу конечную точку.

Надеюсь помочь вам.

@Jonney Shih вы можете создать HOC и использовать его следующим образом:

 import mongoose from 'mongoose'

const withConnect = handler => async (req, res) => {
  if (!mongoose.connection.readyState) {
    const uri = 'mongodb srv://YOUR-CONNECTION'
    await mongoose.connect(uri, {
      useNewUrlParser: true,
      autoIndex: false
    })
  }

  return handler(req, res)
}

export default withConnect
  

и используйте его в pages / api / YOUR-ENDPOINT-ЗДЕСЬ

 import withConnect from '../../../../hoc/withConnect'
import YOUR-SCHEMA from '../../../../models/SCHEMA-NAME.schema'

const handler = async (req, res) => {
  // check req method
  if (req.method === 'POST') {
    // Use your schema here e.g:
    const users = await User.find().exec()

    return SOMETHING
  }

  return SOMETHING
}

export default withConnect(handler)
  

ПРИМЕЧАНИЕ: Возможно, вам нужно проверить, существует ли такая модель:

 const User: IUserModel = models.User || model('User', userSchema)
  

Получайте удовольствие

Комментарии:

1. Как это использовать, пожалуйста, я потерял

Ответ №2:

Я смог заставить это работать, но я почти уверен, что это неправильный способ его реализации, поскольку в моем компоненте Index я жестко закодировал URL-адрес выборки, и я знаю, что в рабочей среде, если порт не тот, он не будет работать.

Чтобы сделать URL динамическим, чтобы он работал в dev и production, вы можете записать полный URL в _app.js Получите исходные данные, а затем передайте их в getInitialProps вашего индексного компонента для использования.

_app.js

 import get from 'lodash/get';

...

static async getInitialProps({ Component, ctx }) {
    const serverUrl = ctx.req ? `${ctx.req.protocol}://${ctx.req.get('Host')}` : '';

...

   if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps({ serverUrl });
    }

   return { pageProps };
}

...
  

index.js

 ...

static async getInitialProps({ serverUrl }) {
    const res = await fetch((`${serverUrl}/youtuber`);

...