Mathias Riis Sorensen
Mathias Riis Sorensen

Reputation: 850

How would an Astro Endpoint (API route) look like converted from Next.js?

I'm trying to convert the following API from Next.js to Astro.build:

import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "lib/prisma";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    // @ts-ignore
    const slug = req.query.slug.toString();
    const contentType = req.body.contentType;

    if (req.method === "POST") {
      const newOrUpdatedViews = await prisma.view.upsert({
        where: { slug },
        create: {
          slug,
          contentType: contentType,
        },
        update: {
          count: {
            increment: 1,
          },
        },
      });

      return res.status(200).json({
        total: newOrUpdatedViews.count.toString(),
      });
    }

    if (req.method === "GET") {
      const views = await prisma.view.findUnique({
        where: {
          slug,
        },
      });

      // @ts-ignore
      return res.status(200).json({ total: views.count.toString() });
    }
  } catch (e) {
    // @ts-ignore
    return res.status(500).json({ message: e.message });
  }
}

I tried editing it with the help of https://docs.astro.build/en/core-concepts/endpoints/ and ended up with loose ends. So far the API looks like this but I don't know where I get the response from:

import type {APIRoute} from "astro"

export const get: APIRoute = async function get({params, request}) {
  try {
    const slug = request.query.slug.toString()
    const contentType = request.body.contentType

    if (request.method === "POST") {
      const newOrUpdatedViews = await prisma.view.upsert({
        where: {slug},
        create: {
          slug,
          contentType: contentType,
        },
        update: {
          count: {
            increment: 1,
          },
        },
      })

      return res.status(200).json({
        total: newOrUpdatedViews.count.toString(),
      })
    }

    if (request.method === "GET") {
      const views = await prisma.view.findUnique({
        where: {
          slug,
        },
      })

      // @ts-ignore
      return res.status(200).json({total: views.count.toString()})
    }
  } catch (e) {
    // @ts-ignore
    return res.status(500).json({message: e.message})
  }
}

VS code tells me that query doesn't exists on from the following line:

const slug = request.query.slug.toString() 

And the same for contentType from this line:

const contentType = request.body.contentType

How would the API look like for Astro?

Upvotes: 1

Views: 1602

Answers (1)

Lazar Nikolov
Lazar Nikolov

Reputation: 1028

You would export a different handler for each method. You already export a handler for the GET method. Do the same for the POST as well.

import type {APIRoute} from "astro"

export const get: APIRoute = async function get({params, request}) {
  try {
    const slug = request.query.slug.toString()
 
    const views = await prisma.view.findUnique({
      where: {
        slug,
      },
    })

    // @ts-ignore
    return res.status(200).json({total: views.count.toString()})
  } catch (e) {
    // @ts-ignore
    return res.status(500).json({message: e.message})
  }
}

export const post: APIRoute = async function get({params, request}) {
  try {
    const slug = request.query.slug.toString()
    const contentType = request.body.contentType
 
    const newOrUpdatedViews = await prisma.view.upsert({
      where: {slug},
      create: {
        slug,
        contentType: contentType,
      },
      update: {
        count: {
          increment: 1,
        },
      },
    })

    return res.status(200).json({
      total: newOrUpdatedViews.count.toString(),
    })
  } catch (e) {
    // @ts-ignore
    return res.status(500).json({message: e.message})
  }
}

You can read more on the Endpoints page in the docsite.

Upvotes: 1

Related Questions