Build awareness and adoption for your software startup with Circuit.

GraphQL File Uploads Server Side with NestJS

GraphQL file upload using NestJS, Firebase, NuxtJS 3, and Apollo Client.

GraphQL File Uploads Server Side with NestJS

Ever been in that coding struggle where you’re trying to make GraphQL play nice with file uploads, and it feels like the info you need is scattered all over the place? Been there, and felt that frustration. So, guess what? I decided to fix it.

In this two-part tutorial, we’re diving into the nitty-gritty of GraphQL file uploads, using NestJS, Firebase, NuxtJS 3, and a bit of Apollo Client magic. It’s the guide I wished I had when I was elbow-deep in the code. Let’s turn that frustration into a coding victory together! Ready to simplify the whole process? Let’s roll! 🚀

Alright, fellow devs, buckle up! We’re diving into the practical side of things, and we will be using graphql-upload. This nifty package is our ticket to smoothly handling file uploads in GraphQL.

Step 1: Initiating Your NestJS GraphQL Adventure

Create a New NestJS Project

Use the Nest CLI to set up a fresh NestJS project. Open your terminal and execute:

npx @nestjs/cli new graphQlFileUpload

Configure GrapghQL, Typeorm and PostgreSQL

To configure GraphQL with TypeORM and PostgreSQL in your NestJS project, refer to the NestJS GraphQL documentation for setting up the GraphQL module. Follow the TypeORM documentation for configuring TypeORM.

Step 2: Configure Middleware for graphql-upload

The only version that worked for me was v14. Install graphql-upload install it by running:

npm install graphql-upload@14

Now, in src/main.ts, configure the middleware for graphql-upload:

import { NestFactory } from ''@nestjs/core'';
import { AppModule } from ''./app.module'';
import { Logger } from ''@nestjs/common'';
import * as graphqlUploadExpress from ''graphql-upload/graphqlUploadExpress.js'';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors();
  app.use(graphqlUploadExpress({ maxFileSize: 100000, maxFiles: 10 }));
  await app.listen(process.env.SERVER_PORT || 3000);
  Logger.log(
    `Server Running on http://localhost:${process.env.SERVER_PORT}/graphql`,
    ''Bootstrap'',
  );
}
bootstrap();

Step 3: Create the Upload Service

we’re introducing the UploadService to handle file uploads and deletions. This service utilizes Firebase Storage for efficient file management. Below is the code for your UploadService:

You can easily replace the Firebase implementation with other services like AWS S3

Step 4: Scaffold the blog entity, resolvers, and services

Scaffold the blog entity, resolvers, and services in your NestJS project by generating a Blog entity, along with corresponding resolvers and services using the Nest CLI. Define GraphQL operations in blog.resolver.ts and implement the necessary methods in blog.service.ts to interact with the Blog entity.  Code here: https://gist.github.com/eadortsu/a9b715369ace30d2cef1df547911da10

In your CreateBlogInput, include a GraphQL field decorator specifying the type as GraphQLUpload and the class as Upload.

//create-blog.input.ts

import { InputType, Field } from ''@nestjs/graphql'';
import * as GraphQLUpload from ''graphql-upload/GraphQLUpload.js'';
import * as Upload from ''graphql-upload/Upload.js'';

@InputType()
export class CreateBlogInput {
  @Field(() => GraphQLUpload, {
    nullable: true,
    description: ''Images file'',
  })
  imageFile: Upload;

/*
rest of your code
*/
In the blog service, you can effortlessly handle image uploads like this:
// Check if an image is provided
if (imageFile) {
  // Retrieve the image
  const image = await imageFile;
// Upload the image to Firebase and update the blog input
  blogInput.image = await this.uploadService.uploadToFirebase({
    file: image,
    path: `blog`,
    fileName: blogInput.slug, // You can customize the file name
  });
}

Step 5: Test in Playground

When it comes to testing GraphQL file uploads, the default GraphQL Playground and Postman may not be the ideal choices. In my experience, Altair GraphQL Client has proven to be effective.

Set Apollo-Require-Preflight Header

Ensure you set a header Apollo-Require-Preflight: true in your requests to avoid CORS errors.

You can now test creating a blog by using the “Add Files” feature to select and attach an image file.

The complete code implementation is available on GitHub at this repository. Stay tuned for the second part, where we’ll delve into the client-side implementation using NuxtJS 3 and Apollo Client.

GitHub - eadortsu/nestJsGraphQlFileUpload




Continue Learning