Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pattern match not working #110

Closed
petermarks12 opened this issue Oct 29, 2020 · 13 comments · Fixed by #121
Closed

Pattern match not working #110

petermarks12 opened this issue Oct 29, 2020 · 13 comments · Fixed by #121

Comments

@petermarks12
Copy link

I have created index.js file in api folder and using following code. I am getting 404 on both routes.

It works fine if I use dynamic routing by Next.js. Does this optional pattern really works? Because I want to have single file to handle routes like we do in Express.js instead of creating bunch of nested files.

Getting 404 on these routes

http://localhost:3000/api/user
http://localhost:3000/api/user/555

import nc from 'next-connect';
const handler = nc();

handler.get('/user', (req, res, next) => {
    res.send('User Route');
});

handler.get('/user/:id', (req, res, next) => {
    res.send(`User ${req.query.id} updated`);
});

export default handler;
@hoangvvo
Copy link
Owner

hoangvvo commented Oct 31, 2020

Create this file instead api/[[...slug]].js

doc: https://nextjs.org/docs/api-routes/dynamic-api-routes#optional-catch-all-api-routes

@Turanchoks
Copy link

Turanchoks commented Dec 5, 2020

Create this file instead api/[[...slug]].js

req.query will receive a Next.js query which is { slug: [] } in this case since params from trouter.find are never passed to req.

I've copied the source code locally and assigned assigned params to req.params here https://github.com/hoangvvo/next-connect/blob/master/lib/index.js#L60

@hoangvvo If this is fine I can send a PR. I'm not sure I want to mutate req.query which is assigned by Next.js but it's your call.

@hoangvvo
Copy link
Owner

hoangvvo commented Dec 6, 2020

Create this file instead api/[[...slug]].js

req.query will receive a Next.js query which is { slug: [] } in this case since params from trouter.find are never passed to req.

I've copied the source code locally and assigned assigned params to req.params here https://github.com/hoangvvo/next-connect/blob/master/lib/index.js#L60

@hoangvvo If this is fine I can send a PR. I'm not sure I want to mutate req.query which is assigned by Next.js but it's your call.

I do not want next-connect to do any url parsing tbh. However, perhaps it can live in the doc as a "recipe" as a middleware.

@Turanchoks
Copy link

url parsing is done internally by trouter anyways. Trouter.find returns both handlers and params but the params are ignored. I can't see a a way of doing it properly since the matched pattern is not passed to the handlers either so you can't create a middleware.

@smeijer
Copy link

smeijer commented Jan 31, 2021

I ran against this today. The docs seem to be incorrect in this area. The following example from the docs, does not work.

handler.put('/user/:id', (req, res, next) => {
  // https://nextjs.org/docs/routing/dynamic-routes
  res.end(`User ${req.query.id} updated`);
});

As mentioned above, the id will be available as item in the array req.query.slug.

A middleware example for how to fix that, would be welcome. But it would also require an update of the docs.

@smeijer
Copy link

smeijer commented Jan 31, 2021

For now, I'm using patch-package to add the functionality that I need. It merges the path params, together with next's query object.

For those interested, use patch-package, and add the following diff to /patches/next-connect+0.9.1.patch.

diff --git a/node_modules/next-connect/lib/index.js b/node_modules/next-connect/lib/index.js
index 9c5aac6..a4beb92 100755
--- a/node_modules/next-connect/lib/index.js
+++ b/node_modules/next-connect/lib/index.js
@@ -57,10 +57,11 @@ module.exports = ({
   nc.handle = function handle(req, res, done) {
     const idx = req.url.indexOf("?");
     const pathname = idx !== -1 ? req.url.substring(0, idx) : req.url;
-    const { handlers } = this.find(
+    const { handlers, params } = this.find(
       req.method,
       this.baseUrl ? pathname.substring(this.baseUrl.length) : pathname
     );
+    req.query = Object.assign({}, req.query, params);
     let i = 0;
     const len = handlers.length;
     const next = (err) => {

@kotsh23
Copy link

kotsh23 commented Feb 5, 2021

i created file [[...slug]] in api folder

and i try to post from postman by this url : localhost:3000/api/users
its give error's

if i remove base ("/users",
its give me not found as result at postman

const app = require("next-connect")();
const helmet = require("helmet");
const cors = require("cors");

app.use(helmet());
app.use(cors());

app.post("/users", (req, res, next) => {
  res.end("User created");
});

export default app;

Please tell me if it can be fixed soon i wont move to express as spare backend

@kotsh23
Copy link

kotsh23 commented Feb 5, 2021

maybe its will help someone if it helped you please give me Like to know thats help you 👍

create dynamic file in api folder [[...slug]] for example and add /api to the pattern
will be for example /api/users maybe the owner can skip it in the Code 🍡

function onError(err, req, res, next) {
  res.status(500).end(err.toString());
}

function onNoMatch(req, res) {
  res.status(404).end("Page Not Found");
}

import lol from "next-connect";
const helmet = require("helmet");
const cors = require("cors");

const app = lol({ onError, onNoMatch });

app.use(helmet());
app.use(cors());

app.use("/api/users", (req, res, next) => {
  console.log(req.url);
  res.end("User created");
});

export default app;

@kotsh23
Copy link

kotsh23 commented Feb 5, 2021

I ran against this today. The docs seem to be incorrect in this area. The following example from the docs, does not work.

handler.put('/user/:id', (req, res, next) => {
  // https://nextjs.org/docs/routing/dynamic-routes
  res.end(`User ${req.query.id} updated`);
});

As mentioned above, the id will be available as item in the array req.query.slug.

A middleware example for how to fix that, would be welcome. But it would also require an update of the docs.

[[...slug]].js
app.use("/api/users/:id", (req, res) => {
res.end(user ${req.query.slug[1]} created :D);
});

@hoangvvo
Copy link
Owner

It is now possible to use req.params by setting attachParams to true.

I also add a recipe for quickly migrating from Express that uses the mentioned optional catch-all route feature here

@Igor2122
Copy link

setting attachParams to true

this does not work for me

@hoangvvo
Copy link
Owner

setting attachParams to true

this does not work for me

Please create a new issue on this. Thanks!

@heinwaiyanhtet
Copy link

heinwaiyanhtet commented Aug 14, 2023

import nc from "next-connect";
import onError from "../../../middlewares/errors";
import { getStreaming, postStreaming } from "../../../controller/StreamingController";

// Initiate next-connect with error middleware
const handler  = nc ({ onError });

// Define routes using the handler's methods
handler.get(getStreaming);

handler.post(postStreaming);

export default handler; 

this code got error - - error pages/api/Streaming/streaming.tsx (6:21) @ eval

  • error Error [TypeError]: next_connect__WEBPACK_IMPORTED_MODULE_0___default(...) is not a function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants