타입스크립트 전면 도입기

회사 개발팀에 사정이 있어서 지난 3월 말부터 개발팀을 이끌게 되었다. 첫 번째 임무는 기존 백엔드의 C#, CQRS, Event-Sourcing, DDD를 걷어내는 일이었다. 좋은 디자인 패턴과 개발방법론과 언어긴 하지만 현 개발팀 아니 한국에서는 좀 쉽지 않은 결정이다. 이유는 많지만 한 마디로 얘기하자면 현 개발팀에 안맞는 옷이었다.

변화가 생긴 개발팀은 Javascript 기반 프론트 1명, 풀스택 2명이었고 C#/Java Entry Level 1명 그리고 나까지 5명이었다. 마음 먹은대로 하자면 백엔드는 Python 혹은 Go로 하고 싶었지만 작은 회사일수록 테크 스택을 통일해야 한다는게 나의 지론이기 때문에 백엔드는 Express를 도입하기로 했다.

Express 도입과 함께 한 가지 도입한 테크 스택은 Typescript다. 현재 웹 프론트엔드인 vue.js와 백오피스 프론트엔드인 react.js는 이미 Typescript였다. 이 참에 Express도 Typescript를 도입하기로 했고 최종적으로 Typescript Rest을 선택했다.

프론트엔드와 백엔드를 모두 Typescript로 통일하고 그 장점을 극대화 하기 위해서 양쪽 사이의 API에서 사용하는 인터페이스나 Enum을 모아놓은 프로젝트를 만들었다. 예를 들어 Item 정보를 만드는 POST API가 있다고 가정하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { POST, Path } from 'typescript-rest';

interface ItemBody {
name: string;
quantity: number;
}

@Path('/item')
export class ItemController {
/**
* 아이템을 만든다.
*/
@Path('')
@POST
public postItem(body: ItemBody){
// .....
}
}

그리고 프론트엔드에서 axios.js로 해당 API를 쓴다면 아래와 같겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface ItemBody {
name: string;
quantity: number;
}

//// 생략
class APIs {
public async doSend(item: ItemBody) {
try {
await axios.post(`${BASE_URL}/item`, item);
} catch (e) {
// ....
}
}
}
//// 후략

두 프로젝트에서 공통으로 쓰는 인터페이스인 ItemBody를 별도의 프로젝트로 분리, Private NPM 저장소를 만들고 이걸 import를 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { POST, Path } from 'typescript-rest';
import { ItemBody } from '@mycompany/interface';

/* 이 부분을 없앨 수 있다.
interface ItemBody {
name: string;
quantity: number;
}*/

@Path('/item')
export class ItemController {
/**
* 아이템을 만든다.
*/
@Path('')
@POST
public postItem(body: ItemBody){
// .....
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { ItemBody } from '@mycompany/interface';
/* 아래 코드를 없앨 수 있다.
interface ItemBody {
name: string;
quantity: number;
}*/

//// 생략
class APIs {
public async doSend(item: ItemBody) {
try {
await axios.post(`${BASE_URL}/item`, item);
} catch (e) {
// ....
}
}
}
//// 후략

여기서는 프로퍼티가 단순히 2개인 인터페이스만 대상으로 했지만, 프로퍼티가 많아질 수록, 그 인터페이스가 많아질 수록 강력한 효과를 발휘했다. 프론트엔드에서 힘들게 Swagger를 보고 인터페이스를 정의할 필요가 없었고,만들다가 생기는 휴먼 에러도 방지할 수 있었다. 단순히 npm을 업데이트함으로서 API와 싱크를 맞추기도 쉬웠다. 무엇보다 각각의 프로젝트에서 각각 관리하던 인터페이스 코드를 통합관리 할 수 있어서 굉장히 생산성이 높아졌다.

필요성을 느껴서 만들었기 때문에 다른 프로젝트에서는 이렇게 쓰는지는 잘 모르겠지만 프론트엔드와 백엔드 모두 타입스크립트를 쓴다면 한 번 도입해보면 좋겠다.

P.S 두 달 반만에 성공적으로 C#에서 자바스크립트로 이전했다.

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×