How To Upload Files With GraphQl And NestJs
Tags: node, graphql, api, nest
Published: 2022-07-29 21:54:00

#Quick demonstration on using GraphQL and Nestjs to upload files (NestJs Code First Approch)

###Overview

Hi 👋 You, Today, I'm going to discuss how to upload files using graphql. You may already be familiar with how to upload files using the Rest API, but now you tried Graphql and you're wondering how to upload your cat pictures.

If you're using Nest Js and the Code-first GraphQL approch this guide is for you

###Setup

Let's start by installing our dependencies

```
npm i @nestjs/graphql @nestjs/apollo graphql apollo-server-express graphql-upload@14
yarn add @nestjs/graphql @nestjs/apollo graphql apollo-server-express graphql-upload@14
```

Now everything is installed go to your **app.module.ts** file and import ApolloDriver, ApolloDriverConfig & GraphQLModule.

```
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { GraphQLModule } from '@nestjs/graphql';
```

Then add GraphQLModule config to the App module imports.

```
@Module({
imports: [
  GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
 }),
],
```

Lets generate our graphql code now by using nest cli in our terminal.

```
nest g resource cats
```

Now Select GraphQL (code first)

```
? What transport layer do you use?
  REST API
  GraphQL (code first)
  GraphQL (schema first)
  Microservice (non-HTTP)
  WebSockets
```

This will create a folder inside you **src** Directory called **cats**.

###Let's Code

Now let's start by writing our mutation to create a cat object with an image

let's start by editing our **createCatInput** which is imported by our **createCatmutation**

```
@InputType()
export class CreateCatInput {
  @Field(() => Int, { description: 'Example field (placeholder)' })
  exampleField: number;
}
```

Our cat will have these properties name, breed & image

Create a file upload type that we can use for our image field which look like this

```
import { Stream } from 'stream';

export interface FileUpload {
  filename: string;
  mimetype: string;
  encoding: string;
  createReadStream: () => Stream;
}
```

Now Add The Fields With GraphQLUpload Scalar Type wich is imported from our package **graphql-upload** which gives us support for GraphQL multipart requests.

```
import * as GraphQLUpload from 'graphql-upload/GraphQLUpload.js';

@InputType()
export class CreateCatInput {
  @Field(() => String)
  name: string;
  @Field(() => String)
  breed: string;
  @Field(() => GraphQLUpload)
  image: Promise<FileUpload>;
}
```

Then head to the cat entity and create a similar type and modify the image field as string so we can return just the filename

```
@ObjectType()
export class Cat {
  @Field(() => String)
  name: string;
  @Field(() => String)
  breed: string;
  @Field(() => String)
  image: string;
}
```

Ok now we go to our **cats.service.ts** where we can handle our image.

```
create({ breed, name, image }: CreateCatInput) {
  // your code goes here
}
```

We will return the breed and name precisely as we received them. **readable stream ( image )** go ahead and create a new folder, you can name it **upload**,we will save our images inside it.

```
async create({ breed, name, image }: CreateCatInput) {
  const { createReadStream, filename } = await image;
  return new Promise(async (resolve) => {
  createReadStream()
   .pipe(createWriteStream(join(process.cwd(), `./src/upload/${filename}`)))
   .on('finish', () =>
     resolve({
      breed,
      name,
      image: filename,
     }),
   )
   .on('error',() => {
       new HttpException('Could not save image', HttpStatus.BAD_REQUEST);
    });
  });
}
```

Finally go to **app.module.ts** and add GraphQLUpload Middleware

```
import * as graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.js';

const app = await NestFactory.create(AppModule);
app.use(graphqlUploadExpress({ maxFileSize: 1000000, maxFiles: 10 }));
await app.listen(4000);
```

Complete Reading on my [portfolio](https://elbarryamine.com/blog/how-to-upload-files-with-nest-js-and-graphql)