4주 프로젝트 DAY 8

  • koa router를 클래스로 빼달라?
  • http.createServer?

koa router를 fileApiRouter클래스로 빼달라?

왜? router 내부에서 사용하는 메서드들이 강한 결합으로 연결되어있는데,
fileApiRouter는 IStorageService 인터페이스의 구현체이고
모든 IStorageService 인터페이스의 구현체들로 확장할 수 있게 바꾸고 싶다~

기존 코드

const router = new Router();
const storageService = new StorageService();

router.get("/fileMetadataList", async (ctx: Koa.Context, next) => {
  ctx.body = await storageService.listFiles();
  ctx.status = 200;
});

router에서 storageService와의 강한 결합을 떼어 놓은 코드
IStorageService인터페이스로 구현된 인스턴스를 FileApiRouter에 넣음으로써
router와 storageService의 관계를 약하게 끊어놓은 결과를 가져왔다.

const router = new KoaRouter();
const storageService = new StorageService();
const fileApiRouter = new FileApiRouter(storageService);

router.get("/fileMetadataList", fileApiRouter.listFiles());
router.post("/uploadFile", fileApiRouter.writeFile());
router.get("/downloadFile", fileApiRouter.readFile());

http.createServer?

nodejs 공식문서

인자로는 requestListener가 들어간다.
http.Server를 리턴한다.

http.createServer([options][, requestlistener])

  • options <Object>

    • IncomingMessage <http.IncomingMessage> Specifies the IncomingMessage class to be used. Useful for extending the original
      IncomingMessage. Default: IncomingMessage.

    • ServerResponse <http.ServerResponse> Specifies the ServerResponse class to be used. Useful for extending the original ServerResponse. Default: ServerResponse.

  • requestListener <Function>

  • Returns: <http.Server>

Returns a new instance of http.Server.

app.listen ?

app.listen() koa -> http.listen() http nodejs -> server.listen () Net
https://nodejs.org/api/net.html#net_server_listen

  • Start a TCP server listening for connections on the given port and host.

에러

import uuid from "uuid/v4";
import { uploadFile, downloadFile } from "./uploadAndDownloadFile.test";
import { getFileMetadataList } from "./uploadAndGetFileMetadataList.test";
import http, { Server } from "http";
import app from "../index";

let server: Server;

server = app.listen(4002, () => {
  console.log(`server is listening to port ${4002}`);
});

describe(`upload and download and listFileMetadata test from StrageClass`, () => {

  beforeAll(async () => {
    console.log("서버 열어요~");
  });

  afterAll(() => {
    server.close();
    console.log("서버 닫아요~");
  });

  it(`should upload file and get FileMetadatalist from server and check it in downloads files`, async () => {
    const imageInBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==";
    const imageBuffer = Buffer.from(imageInBase64, "base64");
    const filename = uuid();

    await uploadFile(filename, imageBuffer);

    const fileMetadataList = await getFileMetadataList();
    const filenameFromApi = fileMetadataList.map((fileMetadata) => {
      return fileMetadata.filename;
    });

    const downloadFiles: string[] = await Promise.all(filenameFromApi.map(async (filenameToBeDownloaded: string) => {
      const downloadedFile = await downloadFile(filenameToBeDownloaded);
      const downloadedFileInBase64 = downloadedFile.toString("base64");
      return downloadedFileInBase64;
    }));

    expect(downloadFiles).toEqual(expect.arrayContaining([imageInBase64]));
  });
});

image.png