#wdaadw

1 messages · Page 1 of 1 (latest)

cerulean sluice
#

create server route api endpoint that can take the file uplaoded and pass or send it to an exernal api

const [files, setFiles] = useState<File[]>([]);
const handleFileUpload = async (files: File[]) => {
setFiles(files);
};

const upload = async () => {
try {
await fetch("/api/file/upload", {
method: "POST",
body: JSON.stringify({ files }),
});
} catch (error) {
console.error(error);
}
};

dreamy harborBOT
#

Hi @cerulean sluice. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To create a server route API endpoint that can handle file uploads and send it to an external API, you can use Next.js API routes. Here's an example of how you can do it:

First, you need to create a server upload page. This page will upload files to your server. The files will then be sent to Vercel Blob. Here's an example of how you can do it:

'use client';
 
import type { PutBlobResult } from '@vercel/blob';
import { useState, useRef } from 'react';
 
export default function AvatarUploadPage() {
  const inputFileRef = useRef<HTMLInputElement>(null);
  const [blob, setBlob] = useState<PutBlobResult | null>(null);
  return (
    <>
      <h1>Upload Your Avatar</h1>
 
      <form
        onSubmit={async (event) => {
          event.preventDefault();
 
          if (!inputFileRef.current?.files) {
            throw new Error('No file selected');
          }
 
          const file = inputFileRef.current.files[0];
 
          const response = await fetch(
            `/api/avatar/upload?filename=${file.name}`,
            {
              method: 'POST',
              body: file,
            },
          );
 
          const newBlob = (await response.json()) as PutBlobResult;
 
          setBlob(newBlob);
        }}
      >
        <input name="file" ref={inputFileRef} type="file" required />
        <button type="submit">Upload</button>
      </form>
      {blob && (
        <div>
          Blob url: <a href={blob.url}>{blob.url}</a>
        </div>
      )}
    </>
  );
}

(Source: Vercel Docs (https://vercel.com/docs/storage/vercel-blob/server-upload#create-a-server-upload-page))

Next, you need to create a server upload route. This route forwards the file to Vercel Blob and returns the URL of the uploaded file to the browser. Here's an example of how you can do it:

#
import { put } from '@vercel/blob';

(Source: Vercel Docs (https://vercel.com/docs/storage/vercel-blob/server-upload#create-a-server-upload-route))

Please note that the above examples are using Vercel Blob for file storage. If you want to send the file to a different external API, you would need to replace the Vercel Blob specific code with the appropriate code for your external API.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@cerulean sluice kapa.ai is still learning and improving, please let us know how it did by reacting below

cerulean sluice
#

@dreamy harbor i want to keep existing front end and just create an api route. not server action

dreamy harborBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Sure, you can create an API route in Next.js without affecting your existing front-end. API routes provide a solution to build your API with Next.js. Any file inside the folder pages/api is mapped to /api/* and will be treated as an API endpoint instead of a page.

Here's a basic example of how you can create an API route:

// pages/api/hello.js
export default function handler(req, res) {
  res.status(200).json({ text: 'Hello' })
}

This API route can be accessed at <http://localhost:3000/api/hello.> You can use any HTTP method in your API route, like GET, POST, etc.

If you want to send a file to an external API, you can do something like this:

// pages/api/upload.js
export default async function handler(req, res) {
  const file = req.body.file;
  
  // Send the file to an external API
  const response = await fetch('<https://external-api.com/upload',> {
    method: 'POST',
    body: file,
  });

  // Handle the response from the external API
  if (response.ok) {
    res.status(200).json({ text: 'File uploaded successfully' });
  } else {
    res.status(500).json({ text: 'File upload failed' });
  }
}

In this example, the API route receives a file in the request body and sends it to an external API using the fetch function. The response from the external API is then handled and an appropriate response is sent back from the API route.

Please note that this is a simplified example and error handling should be added for a production-ready application.

(Source: Next.js Docs (https://nextjs.org/docs/api-routes/introduction))

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@cerulean sluice kapa.ai is still learning and improving, please let us know how it did by reacting below

cerulean sluice
#

@dreamy harbor import { unstable_cache } from "next/cache";

import { errorResponse, successResponse } from "@/server/helpers/api";
import { query } from "@/server/database";
import { getNameEffects } from "@/server/utils/get-name-effects";
import { RankingUser } from "@/types";

interface RankingUserRow {
id: number;
username: string;
link: string;
premium: number;
nameColor: string;
nameEffect: string;
name: string;
totalViews: number;
}

export const dynamic = "force-dynamic";
export const revalidate = 3600;

export async function GET(request: Request) {
try {
const topUsers = await query(
WITH recent_views AS ( SELECT b.user_id, COUNT(*) AS totalViews FROM user_views v JOIN biolinks b ON v.biolink_id = b.id WHERE v.created_at >= CURDATE() - INTERVAL 1 DAY AND v.created_at < CURDATE() GROUP BY b.user_id ORDER BY totalViews DESC ) SELECT u.id, u.username, b.link, b.premium, b.name_color AS nameColor, b.name_effect AS nameEffect, COALESCE(b.name, u.username) AS name, recent_views.totalViews FROM recent_views JOIN users u ON recent_views.user_id = u.id JOIN biolinks b ON u.id = b.user_id ORDER BY recent_views.totalViews DESC LIMIT ? OFFSET ? ,
[10, 0]
);

return successResponse({
  message: "Successfully fetched trending users.",
  data: topUsers.map((row: RankingUserRow, idx: number) =>
    format(row, idx, 0)
  ),
});

} catch (e) {
console.error;
return errorResponse({
message: "Failed to fetch trending users.",
status: 500,
});
}
}

how use unstable_cache here

dreamy harborBOT
#

Let me check the knowledge base for you. One moment! :books:

#

You can use unstable_cache from Next.js to cache the results of your database query. This can be particularly useful if the query is expensive and you want to reuse the results across multiple requests. Here's how you can modify your GET function to use unstable_cache:

import { unstable_cache } from "next/cache";

// ...

export async function GET(request: Request) {
  try {
    const getCachedTopUsers = unstable_cache(
      async () => {
        return await query(
          `
          WITH recent_views AS (
            SELECT b.user_id, COUNT(*) AS totalViews
            FROM user_views v
            JOIN biolinks b ON v.biolink_id = b.id
            WHERE v.created_at >= CURDATE() - INTERVAL 1 DAY
              AND v.created_at < CURDATE()
            GROUP BY b.user_id
            ORDER BY totalViews DESC
          )
          SELECT 
            u.id, 
            u.username, 
            b.link, 
            b.premium, 
            b.name_color AS nameColor,
            b.name_effect AS nameEffect,
            COALESCE(b.name, u.username) AS name,
            recent_views.totalViews
          FROM 
            recent_views
          JOIN users u ON recent_views.user_id = u.id
          JOIN biolinks b ON u.id = b.user_id
          ORDER BY recent_views.totalViews DESC
          LIMIT ? OFFSET ?
          `,
          [10, 0]
        );
      },
      ['topUsers'], // add the cache key
      {
        tags: ['users'],
        revalidate: 3600,
      }
    );

    const topUsers = await getCachedTopUsers();
#

return successResponse({
message: "Successfully fetched trending users.",
data: topUsers.map((row: RankingUserRow, idx: number) =>
format(row, idx, 0)
),
});
} catch (e) {
console.error;
return errorResponse({
message: "Failed to fetch trending users.",
status: 500,
});
}
}


In this example, `unstable_cache` is used to cache the results of the `query` function. The second argument to `unstable_cache` is an array that serves as the cache key. The third argument is an options object where you can specify tags for the cache and a revalidation interval in seconds. In this case, the cache will be revalidated every 3600 seconds (1 hour).

Please note that `unstable_cache` is currently an unstable API and may change in the future.

(Source: **Next.js Docs** (<https://nextjs.org/docs/app/api-reference/functions/unstable_cache>))
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------