Basit Minhas
Basit Minhas

Reputation: 317

How can I create API end point in Next.js with query string

I need to create the following API end point using Next.js:

/api/products/[name]?keyword=${anykeyword}.

I know I need to create it inside pages/api/products/[name] directory in index.js. But how can I access keyword.

req.query only contains name.

following is my code:

import { connectToDatabase } from "../../../../util/mongodb";
import validate from "../../../../validation/product";
//capitalize first letter only to avoid errors
import capitalize from "lodash.capitalize";

export default async function productsHandler(req, res) {
const {
  query: { name, keyword }, // here i cannot access keyword//
  method,
} = req,
Name = capitalize(name),
{ db } = await connectToDatabase(),
searchCriteria = keyword ? keyword : "price";

switch (method) {
case "GET":
  // @route GET api/products/[name]
  // @desc get products of [name] from data base
  // @access public
  {
    const products = await db
      .collection("products")
      .find({ category: Name })
      .sort({ [searchCriteria]: 1 })
      .toArray();

    if (!products.length)
      return res.status(404).json({ error: "no such category" });

    res.status(200).json(products);
  }

  break;

Upvotes: 19

Views: 48959

Answers (6)

Daniel Tonon
Daniel Tonon

Reputation: 10512

TypeScript strongly typed example of getting name and keyword from this url:

/api/products/productName?keyword=anykeyword

Note that the file needs to be placed in this directory for it to work:

{ROOT}/app/api/products/[name]/route.ts

{ROOT} is the project root folder.

[name] needs to actually be called that with the brackets and everything.

// {ROOT}/app/api/products/[name]/route.ts

import { NextRequest, NextResponse } from 'next/server'
import { getApiQueryParams } from '../path/to/utils.ts'

type QueryKey = 'keyword'
type Response = { params: { name: string } }

export async function GET(request: NextRequest, response: Response) {
    const { name } = response.params
    const { keyword } = getApiQueryParams<QueryKey>(request)

    return NextResponse.json({ name, keyword })
}

These can go into a seperate file to be reusable:

// utils.ts

export function getApiQueryParams<ExpectedParamKeys extends string>(
    request: NextRequest,
): UrlParams<ExpectedParamKeys> {
    const urlParams: UrlParams<ExpectedParamKeys> = {}
    request.nextUrl.searchParams.forEach((value, key) => {
        urlParams[key as ExpectedParamKeys] = value
    })
    return urlParams
}


export type UrlParams<ExpectedKeys extends string = string> = Partial<
    Record<ExpectedKeys, string>
>

Upvotes: 0

Ponsakthi Anand
Ponsakthi Anand

Reputation: 345

Below code might help the people who started learning nextjs api calls. to get dynamic routing id.

app/api/events/[event]/route.js
export async function GET(request, { params }) {
  const slug = (await params).event //event id
}

this slug will return to get [event] value

Upvotes: 0

ethanLiu
ethanLiu

Reputation: 21

import { type NextRequest } from 'next/server'
 
export function GET(request: NextRequest) {
  const searchParams = request.nextUrl.searchParams
  const query = searchParams.get('query')
  // query is "hello" for /api/search?query=hello
}

I found this link
https://nextjs.org/docs/app/building-your-application/routing/route-handlers#url-query-parameters
which can solve your problem.

Upvotes: 2

theshubhagrwl
theshubhagrwl

Reputation: 1026

To get the search parameters you can simply use req.nextUrl.searchParams.get("keyword")

async function GET(req:NextRequest){
 console.log(req.nextUrl.searchParams.get("keyword"))
}

Upvotes: 15

GorvGoyl
GorvGoyl

Reputation: 49600

this worked for me:

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const qs = getQSParamFromURL("qs", req.url);
  return new Response(
    JSON.stringify({
      data: {
        hello: qs,
      },
    }),
    {
      status: 200,
      headers: {
        "content-type": "application/json",
        "cache-control": "public, s-maxage=1800, stale-while-revalidate=600",
      },
    }
  );
}

export function getQSParamFromURL(
  key: string,
  url: string | undefined
): string | null {
  if (!url) return "";
  const search = new URL(url).search;
  const urlParams = new URLSearchParams(search);
  return urlParams.get(key);
}

Upvotes: 1

mahieyin-rahmun
mahieyin-rahmun

Reputation: 1657

It probably has to do with how the request is being sent to the server side from the client. You probably need to revise that. I just tried out the example using Postman, and it correctly parsed the parameters:

import { NextApiRequest, NextApiResponse } from "next";

export default async (request: NextApiRequest, response: NextApiResponse) => {
  const {
    query: { name, keyword },
    method,
  } = request;
  console.log(name, keyword, method);

  // do nothing fancy and simply return a string concatenation
  return response.status(200).json({ query: name + " " + keyword });
};

Postman:

enter image description here

Upvotes: 16

Related Questions