การทำ Interceptor ใน NestJS เพื่อจัดการ Response API

Oct. 13, 2024 · boychawin

วันนี้พามาทำตัวจัดการ response เป็นรูปแบบหนึ่งที่ผมใช้งานอยู่ให้เป็นระบบระเบียบ คือการใช้ Interceptor สามารถนำไปใช้งานการเขียนลง log ได้เลย

Response Interceptor คืออะไร?

มีหน้าที่เป็น middleware ที่ทำงานก่อนและหลังการส่ง response ไปยัง client โดยมีหน้าที่หลักคือการจัดรูปแบบ response ให้เป็นมาตรฐานเดียวกัน เช่น การเพิ่มค่าต่างๆ ใน header ของ response หรือการกำหนดรูปแบบข้อมูลที่จะถูกส่งกลับไปยัง client

โค้ดตัวอย่าง


@Injectable()
export class ResponseInterceptor<T>
  implements NestInterceptor<T, IStandardResponse<T>> {
  constructor(
    private readonly cls: ClsService,
  ) { }

  intercept(
    context: ExecutionContext,
    next: CallHandler,
  ): Observable<IStandardResponse<T>> {
    const now = DateUtil.nowMillis();
    const request = context.switchToHttp().getRequest<Request>();
    const response = context.switchToHttp().getResponse<Response>();
    const reqId =
      DateUtil.nowMillis().toString(36) + crypto.randomBytes(6).toString('hex');
    const apiReqId = request.headers['request-id'];

    response.header('time', String(now));
    this.cls.set('reqId', reqId);
    this.cls.set('apiReqId', apiReqId);

    console.log(response)

    return next.handle().pipe(
      map((data: T) => {
        const responseData = {
          resultCode: '20000',
          resultDescription: 'Success',
          developerMessage: 'Success',
          data,
        };
        return responseData;
      }),
    );
  }
}

รายละเอียดของ ResponseInterceptor

จากโค้ดตัวอย่างนี้ ResponseInterceptor ทำหน้าที่ในการจัดรูปแบบการตอบกลับ (response)

  1. การตั้งค่าหัวข้อ (Header): เราสามารถเพิ่มข้อมูลลงใน header ของ response ได้ เช่น time หรือ reqId ที่ถูกสร้างขึ้นโดยการใช้เวลาปัจจุบันรวมกับค่าแบบสุ่ม
  2. การจัดการข้อมูลส่วนกลาง (CLS - Context Local Storage): ใช้ ClsService เพื่อเก็บข้อมูล เช่น reqId และ apiReqId ซึ่งสามารถเรียกใช้ได้ใน service อื่นๆ ที่เกี่ยวข้องภายใน request เดียวกัน
  3. การจัดรูปแบบ Response: Interceptor จะทำการจัดรูปแบบข้อมูลที่ถูกส่งกลับไปยัง client ให้อยู่ในรูปแบบมาตรฐาน เช่น การระบุ resultCode, resultDescription, และ data เพื่อให้นักพัฒนาสามารถมั่นใจได้ว่ารูปแบบ response จะคงที่และชัดเจนทุกครั้ง

การนำไปใช้งานจริง

การนำ ResponseInterceptor ไปใช้งานสามารถทำได้ง่ายๆ โดยการกำหนดให้เป็น global interceptor ในโมดูลที่ต้องการ เช่น


@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: ResponseInterceptor,
    },
  ],
})
export class CommonModule {}

ประโยชน์

  1. ช่วยให้นักพัฒนาสามารถควบคุมและกำหนดรูปแบบการตอบกลับ API ได้อย่างเป็นมาตรฐาน
  2. ทำให้ง่ายต่อการติดตามและดีบักในระบบที่มีการร้องขอหลายครั้ง
  3. ช่วยให้นักพัฒนาสามารถจัดการข้อมูลที่เชื่อมโยงกับการร้องขอหนึ่งๆ ได้อย่างมีประสิทธิภาพ ผ่านการใช้ ClsService

สรุป

ResponseInterceptor ใน NestJS เป็นเครื่องมือที่ช่วยจัดการการตอบกลับ API ให้อยู่ในรูปแบบมาตรฐาน และยังสามารถเพิ่มข้อมูลในส่วนของ header เพื่อติดตามและจัดการข้อมูลใน request ได้อย่างง่ายดาย