왜? 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());
인자로는 requestListener가 들어간다.
http.Server를 리턴한다.
http.createServer([options][, requestlistener])
options
* 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
Returns: <http.Server>
Returns a new instance of http.Server.
app.listen() koa -> http.listen() http nodejs -> server.listen () Net
https://nodejs.org/api/net.html#net_server_listen
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]));
});
});