Typesikre API'er fra frontend til backend med tRPC · Lektion

Filuploads med tRPC

Integrér funktionalitet til filuploads i Deres tRPC-mutationer ved hjælp af multipart/form-data og passende parsere.

Lektion 3 af 411 trin

Filuploads med tRPC er en gratis Typesikre API'er fra frontend til backend med tRPC-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Typesikre API'er fra frontend til backend med tRPC, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Typesikre API'er fra frontend til backend med tRPC-kurset indeholder 4 lektioner i alt.

Introduktion til filuploads

Velkommen til håndtering af filuploads med tRPC! I modsætning til simple JSON-data kræver filer som billeder eller dokumenter en særlig tilgang, fordi de ofte er binære data.

tRPC fokuserer selv på typesikre API-definitioner. Det håndterer ikke parsing på lavt niveau af filuploads direkte. I stedet integreres det problemfrit med den underliggende HTTP-serverramme, f.eks. Express eller Next.js, for at håndtere dette.

Forståelse af multipart/form-data

Når du uploader en fil via en webformular, sendes dataene typisk ved hjælp af kodningstypen multipart/form-data. Det adskiller sig fra application/json, som er almindelig for de fleste tRPC-anmodninger.

  • multipart/form-data: Gør det muligt at sende både tekstfelter og binære filer i én anmodning.
  • application/json: Bruges primært til strukturerede tekstdata og er ikke ideel til store binære filer.

Din server skal bruge en særlig "parser" for at fortolke multipart/form-data-anmodninger korrekt.

Opsætning på serversiden: Express og parsere

For at integrere filuploads med tRPC bruger vi en Express-server som backend. Express er en populær Node.js-ramme, der nemt kan hoste tRPC.

Til parsing af multipart/form-data bruger vi middleware som express-fileupload. Dette middleware behandler den indgående anmodning og gør de uploadede filer tilgængelige på objektet req.

Grundlæggende Express-server med fil-middleware

Først opsætter vi en grundlæggende Express-server og integrerer middlewaret express-fileupload. Det gør filer tilgængelige på objektet req, så de kan bruges senere.

Kør npm install express express-fileupload i dit projekt.

Prøv at køre dette eksempel:

const express = require('express');
const fileUpload = require('express-fileupload');
const app = express();
const port = 3000;

// Enable file upload middleware
app.use(fileUpload());

app.get('/', (req, res) => {
  res.send('Express server running!');
});

// Simple endpoint to show file access
app.post('/upload-test', (req, res) => {
  if (!req.files || Object.keys(req.files).length === 0) {
    return res.status(400).send('No files uploaded.');
  }
  
  // 'myFile' refers to the name attribute in the HTML input
  let uploadedFile = req.files.myFile;
  
  console.log('File received:', uploadedFile.name);
  res.send(`File '${uploadedFile.name}' received.`);
});

app.listen(port, () => {
  console.log(`Server on http://localhost:${port}`);
});

Integration af tRPC på serveren

Nu tilføjer vi tRPC oven på vores Express-server. Det er afgørende, at middlewaret express-fileupload kører før tRPC-middlewaret. Det sikrer, at req.files er udfyldt, før tRPC's funktion createContext kaldes.

Kør npm install @trpc/server @trpc/express zod.

import express from 'express';
import fileUpload from 'express-fileupload';
import * as trpcExpress from '@trpc/express';
import { initTRPC } from '@trpc/server';

// Initialize tRPC (we'll define context and router later)
const t = initTRPC.context<any>().create();
const appRouter = t.router({}); // Empty router for now

// tRPC context function
function createContext({ req, res }: { req: express.Request, res: express.Response }) {
  return { req, res, uploadedFiles: req.files }; // Files are here!
}

const app = express();
const port = 3000;

// 1. Enable file upload middleware FIRST
app.use(fileUpload());

// 2. Add tRPC middleware (after fileUpload)
app.use(
  '/trpc',
  trpcExpress.createExpressMiddleware({
    router: appRouter,
    createContext,
  })
);

app.get('/', (req, res) => {
  res.send('tRPC file upload server running!');
});

app.listen(port, () => {
  console.log(`Server on http://localhost:${port}`);
});

Definition af tRPC-kontekst med filadgang

Som vist i det foregående eksempel tilføjer middlewaret express-fileupload en egenskab med navnet files til objektet express.Request. Ved at returnere req.files i vores funktion createContext gør vi de uploadede filer let tilgængelige i enhver tRPC-procedure.

Vi har navngivet denne egenskab uploadedFiles i vores kontekst for at gøre det tydeligt.

import express from 'express';
import type { UploadedFile } from 'express-fileupload';

// Extend Express Request type (in a real project, this would be in a types file)
declare global {
  namespace Express {
    interface Request {
      files?: { [key: string]: UploadedFile | UploadedFile[] };
    }
  }
}

export function createContext({
  req,
  res,
}: { req: express.Request; res: express.Response }) {
  return {
    req,
    res,
    // This makes the files available in `ctx.uploadedFiles`
    uploadedFiles: req.files,
  };
}

Opbygning af filupload-mutationen

Nu kan vi definere en tRPC-mutation, der bruger uploadedFiles fra vores kontekst. Vi bruger Zod til grundlæggende inputvalidering, f.eks. en beskrivelse af filen.

  • Tilgå ctx.uploadedFiles.
  • Hent den specifikke fil ud fra dens feltnavn, f.eks. 'myFile'.
  • Brug filens mv()-metode til at gemme den på disken.
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
import type { UploadedFile } from 'express-fileupload';

// Assuming 't' is initialized with context containing 'uploadedFiles'
const t = initTRPC.context<any>().create(); // Replace 'any' with your actual context type

export const appRouter = t.router({
  uploadFile: t.procedure
    .input(z.object({
      description: z.string().optional(),
    }))
    .mutation(async ({ ctx, input }) => {
      const { uploadedFiles } = ctx;

      if (!uploadedFiles || Object.keys(uploadedFiles).length === 0) {
        throw new Error('No files found in request.');
      }

      // Access the file by the name given in FormData (e.g., 'myFile')
      const file = uploadedFiles.myFile as UploadedFile;

      if (!file) {
        throw new Error('File field "myFile" is missing.');
      }

      const savePath = `./uploads/${file.name}`; // Store temporarily
      await file.mv(savePath); // Move file to destination

      return {
        fileName: file.name,
        size: file.size,
        description: input.description || 'No description',
        message: 'File uploaded successfully!',
      };
    }),
});

På klientsiden: Oprettelse af FormData

På klienten bruger du typisk et HTML-element af typen <input type="file">, så brugerne kan vælge en fil. Hvis du vil sende filen, opretter du et FormData-objekt.

  • FormData: En web-API, der gør det nemt at opbygge nøgleværdi-par, som repræsenterer formularfelter og deres værdier, herunder filer.
  • Brug formData.append('fieldName', value) til at tilføje data. For filer er værdien selve File-objektet.
<!-- Example HTML snippet -->
<input type="file" id="fileInput" />
<script>
  const fileInput = document.getElementById('fileInput');
  
  function prepareFormData() {
    const file = fileInput.files[0];
    if (!file) {
      console.log('No file selected.');
      return null;
    }

    const formData = new FormData();
    // 'myFile' must match the field name expected by the server
    formData.append('myFile', file);
    formData.append('description', 'A document from the user.');

    console.log('FormData prepared!');
    return formData;
  }
</script>

Sende filer til tRPC-slutpunktet

Standardklientbiblioteket til tRPC er ikke designet til direkte at sende multipart/form-data i mutationer. I stedet bruger vi typisk den indbyggede fetch-API til at sende FormData-objektet til vores tRPC-slutpunkt.

Stien til slutpunktet er /trpc/yourProcedureName, og metoden er POST.

Prøv at køre dette eksempel (sørg for, at serveren fra Scene 5 & 7 kører):

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
  <title>Upload File</title>
</head>
<body>
  <input type="file" id="fileInput" />
  <button onclick="uploadFile()">Upload</button>

  <script>
    async function uploadFile() {
      const fileInput = document.getElementById('fileInput');
      const file = fileInput.files[0];

      if (!file) {
        alert('Please select a file first.');
        return;
      }

      const formData = new FormData();
      formData.append('myFile', file); // 'myFile' matches server's expected name
      formData.append('description', 'A file from client!');

      try {
        const response = await fetch('http://localhost:3000/trpc/uploadFile', {
          method: 'POST',
          body: formData,
        });

        const result = await response.json();
        if (response.ok) {
          alert('Upload successful: ' + JSON.stringify(result));
        } else {
          alert('Upload failed: ' + JSON.stringify(result));
        }
      } catch (error) {
        console.error('Error uploading file:', error);
        alert('An error occurred during upload.');
      }
    }
  </script>
</body>
</html>

Hurtigt tjek

Hvilke af følgende udsagn om håndtering af filuploads med tRPC er sande?

Opsummering og næste trin

Du har lært, hvordan du integrerer funktionalitet til filuploads i din tRPC-applikation!

  • Filuploads bruger multipart/form-data, hvilket kræver parsing på serversiden.
  • Middlewaret express-fileupload på en Express-server håndterer denne parsing.
  • Ved at anvende filupload-middlewaret før tRPC-middlewaret bliver req.files tilgængelig i din tRPC-kontekst.
  • Din tRPC-mutation kan derefter få adgang til og gemme de uploadede filer.
  • På klienten skal du bruge FormData og den indbyggede fetch-API til at sende filer til dit tRPC-slutpunkt.

Husk at overveje robuste løsninger til fillagring (f.eks. cloudlagring som S3) og korrekt fejlhåndtering i produktionsapplikationer.

Gratis at komme i gang

Lær Typesikre API'er fra frontend til backend med tRPC med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
10
Lektioner
40

Ofte stillede spørgsmål

Er lektionen “Filuploads med tRPC” gratis?

Ja — alle 3 lektioner i læringssporet Typesikre API'er fra frontend til backend med tRPC, inklusive “Filuploads med tRPC”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Typesikre API'er fra frontend til backend med tRPC-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Filuploads med tRPC”?

Integrér funktionalitet til filuploads i Deres tRPC-mutationer ved hjælp af multipart/form-data og passende parsere. Du øver dig i Typesikre API'er fra frontend til backend med tRPC med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Typesikre API'er fra frontend til backend med tRPC?

Der kræves ingen tidligere erfaring. Typesikre API'er fra frontend til backend med tRPC på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Filuploads med tRPC”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Typesikre API'er fra frontend til backend med tRPC-lektion?

Ja. Alle Typesikre API'er fra frontend til backend med tRPC-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Effektiv batching af requests
  2. Implementering af optimistiske opdateringer
  3. Filuploads med tRPC
  4. Infinite queries og cursor-baseret paginering
← Tilbage til Typesikre API'er fra frontend til backend med tRPC