Skip to content

Commit

Permalink
Refactor API URL route and middleware, add Prisma errors
Browse files Browse the repository at this point in the history
  • Loading branch information
pheralb committed Mar 30, 2024
1 parent 4922551 commit 883aa2a
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 50 deletions.
75 changes: 41 additions & 34 deletions src/app/api/url/route.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { NextRequest } from "next/server";

import { Prisma } from "@prisma/client";
import { NextResponse } from "next/server";
import { db } from "@/server/db";

export const GET = async (req: NextRequest) => {
const params = req.nextUrl.searchParams.get("slug");
export const GET = async (req: Request) => {
const url = new URL(req.url);
const params = url.searchParams.get("slug");
const newHeaders = new Headers(req.headers);

// If no slug provided (500):
Expand All @@ -15,38 +15,45 @@ export const GET = async (req: NextRequest) => {
);
}

// Search for the slug in the database:
const getLinkFromServer = await db.links.findUnique({
where: {
slug: params,
},
});
try {
const getLinkFromServer = await db.links.findUnique({
where: {
slug: params,
},
});

if (!getLinkFromServer) {
return NextResponse.json(
{ error: "Error: Slug not found or invalid." },
{ status: 404 },
);
}

await db.links.update({
where: {
id: getLinkFromServer.id,
},
data: {
clicks: {
increment: 1,
},
},
});

newHeaders.set("cache-control", "public, max-age=31536000, immutable");

// If no link found (404):
if (!getLinkFromServer) {
return NextResponse.json(
{ error: "Error: Slug not found or invalid." },
{ status: 404 },
{ message: "Link already exists.", url: getLinkFromServer.url },
{ headers: newHeaders, status: 200 },
);
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
console.log(`🚧 Error: ${error.message}`);
return NextResponse.json({ message: error.message }, { status: 400 });
}
return NextResponse.json(
{ message: "Something went wrong." },
{ status: 500 },
);
}

// Increment the clicks in the database:
await db.links.update({
where: {
id: getLinkFromServer.id,
},
data: {
clicks: {
increment: 1,
},
},
});

// Cache:
newHeaders.set("cache-control", "public, max-age=31536000, immutable");

// Redirect to the URL:
return NextResponse.json(getLinkFromServer, {
headers: newHeaders,
});
};
39 changes: 23 additions & 16 deletions src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import NextAuth from "next-auth";
import authConfig from "@/auth.config";

import { NextResponse } from "next/server";

import {
DEFAULT_LOGIN_REDIRECT_URL,
apiAuthPrefix,
Expand Down Expand Up @@ -33,14 +35,16 @@ export default auth(async (req) => {
// ⚙️ Is Auth Route. First, check is authenticated:
if (isAuthRoute) {
if (isLoggedIn) {
return Response.redirect(new URL(DEFAULT_LOGIN_REDIRECT_URL, nextUrl));
return NextResponse.redirect(
new URL(DEFAULT_LOGIN_REDIRECT_URL, nextUrl),
);
}
return;
}

// ⚙️ If Slug contains ``c``, redirect to /check/:slug:
if (slugRoute && slugRoute.endsWith("&c")) {
return Response.redirect(
return NextResponse.redirect(
new URL(`/check/${slugRoute.replace("&c", "")}`, nextUrl),
);
}
Expand All @@ -52,29 +56,32 @@ export default auth(async (req) => {
callbackUrl += nextUrl.search;
}
const encodedCallbackUrl = encodeURIComponent(callbackUrl);
return Response.redirect(
return NextResponse.redirect(
new URL(`/auth?callbackUrl=${encodedCallbackUrl}`, nextUrl),
);
}

// ⚙️ Redirect using slug:
// If not public route and not protected route:
if (!isPublicRoute && !isProtectedRoute && !isCheckRoute) {
const data = await fetch(`${req.nextUrl.origin}/api/url?slug=${slugRoute}`);

if (data.status === 404) {
return;
}

const dataToJson = await data.json();

if (dataToJson.url) {
return Response.redirect(new URL(dataToJson.url as string).toString());
try {
const getDataApi = await fetch(
`${req.nextUrl.origin}/api/url?slug=${slugRoute}`,
);

if (getDataApi.status === 404) {
return;
}

const getDataUrl = await getDataApi.json();

if (getDataUrl?.url) {
return NextResponse.redirect(new URL(getDataUrl.url as string));
}
} catch (error) {
console.error("🚧 Error fetching slug: ", error);
}

return;
}

return;
});

Expand Down

0 comments on commit 883aa2a

Please sign in to comment.