DEV Community

Emmanuel R
Emmanuel R

Posted on

πŸš€ Build a Resume Parser API with NestJS and OpenAI in 30 Minutes.

Intro:

In the world of recruitment tech, parsing resumes and extracting structured data (skills, experience, etc.) is a high-demand use case.

In this article, you’ll learn how to build a Resume Parser API using:

  • NestJS (TypeScript framework)
  • pdf-parse (to extract text from PDF)
  • OpenAI API (for structured JSON output)

Let’s dive in! πŸŠβ€β™‚οΈ

Step 1: Project Setup

npm i -g @nestjs/cli
nest new resume-parser-api
cd resume-parser-api
Enter fullscreen mode Exit fullscreen mode

Install dependencies:

npm install pdf-parse openai multer @nestjs/platform-express
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure OpenAI

In .env:

OPENAI_API_KEY=your_api_key_here
Enter fullscreen mode Exit fullscreen mode

Create openai.service.ts:

import { Injectable } from '@nestjs/common';
import { Configuration, OpenAIApi } from 'openai';

@Injectable()
export class OpenAIService {
  private openai: OpenAIApi;

  constructor() {
    const config = new Configuration({
      apiKey: process.env.OPENAI_API_KEY,
    });
    this.openai = new OpenAIApi(config);
  }

  async parseResumeText(text: string) {
    const prompt = `Extract the following from this resume text and return it in JSON:
- Name
- Email
- Skills
- Experience

Resume:
${text}`;

    const res = await this.openai.createChatCompletion({
      model: 'gpt-4',
      messages: [{ role: 'user', content: prompt }],
    });

    return res.data.choices[0].message.content;
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Create File Upload & Parser Controller

// resume-parser.controller.ts
import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import * as pdf from 'pdf-parse';
import { OpenAIService } from './openai.service';

@Controller('resume')
export class ResumeParserController {
  constructor(private readonly openAIService: OpenAIService) {}

  @Post('upload')
  @UseInterceptors(FileInterceptor('file'))
  async handleUpload(@UploadedFile() file: Express.Multer.File) {
    const dataBuffer = file.buffer;
    const resumeText = (await pdf(dataBuffer)).text;
    const parsed = await this.openAIService.parseResumeText(resumeText);
    return JSON.parse(parsed);
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Setup Multer for File Uploads

// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as multer from 'multer';
import * as express from 'express';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(express.json({ limit: '10mb' }));
  await app.listen(3000);
}
bootstrap();
Enter fullscreen mode Exit fullscreen mode

Step 5: Test the API

Use Postman or curl:

Endpoint: POST /resume/upload
Form-data: file = your_resume.pdf

Sample Response

{
  "name": "John Doe",
  "email": "johndoe@example.com",
  "skills": ["JavaScript", "Node.js", "NestJS"],
  "experience": [
    {
      "company": "TechCorp",
      "role": "Fullstack Developer",
      "duration": "2019-2023"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Wrap-up

You now have a working resume parser powered by AI! πŸŽ‰
You can extend this by:

  • Saving parsed data in PostgreSQL
  • Building a frontend with Angular
  • Offering this as a paid API (hint: a micro SaaS πŸ˜‰)

If you enjoyed this post, follow me for more fullstack dev tips and projects.

Top comments (0)