Gorilla-Kim/Project

[MEMO APP] Back-end/ λΌμš°νŒ… (2)

Kim_gorilla 2020. 3. 15. 01:58

 

πŸ‘¨‍πŸ’» λΌμš°νŒ… (2)

 

πŸ“Œ λΌμš°νŒ… (2)

μ €λ²ˆ ν¬μŠ€νŒ…κΉŒμ§€ λ‚΄μš©μ„ κ°„λ‹¨νžˆ μš”μ•½ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€. 

 

  • κΉƒν—ˆλΈŒμ— μ—…λ‘œλ“œλ₯Ό μ›ν™œν•˜κ²Œ(+λ³΄μ•ˆλ‚΄μš©μ€ 가리기) μœ„ν•΄μ„œ gitignore을 μ„€μ •ν•΄ μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.
  • Koa-routerλ₯Ό μ΄μš©ν•΄μ„œ '/' 경둜둜 μ ‘κ·Όμ‹œ νŠΉμ • λ©”μ‹œμ§€κ°€ 보이게 ν•˜μ˜€μŠ΅λ‹ˆλ‹€. 

 

μ΄λ²ˆμ—λŠ” μ €λ²ˆμ— ν•˜λ˜ routingμž‘μ—…μ„ λ§ˆμ € μ™„λ£Œν•˜λ„λ‘ ν• κ»€λ°μš”. κ·Έ 전에 μš°λ¦¬κ°€ μ•Œμ•„μ•Όν•  νŒλ“€μ΄ μžˆμŠ΅λ‹ˆλ‹€.

 

μ € λΏλ§Œμ€ μ•„λ‹ˆκ² μ§€λ§Œ κ°œλ°œμ„ ν•˜λ‹€λ³΄λ©΄, 폴더 ν˜Ήμ€ νŒŒμΌμ •λ¦¬κ°€ 정말이지 μ€‘μš”ν•˜κ²Œ λŠκ»΄μ§‘λ‹ˆλ‹€.

λΉ„μŠ·ν•œ μ—­ν• μ„ν•˜λŠ” νŒŒμΌλ“€μ„ ν•˜λ‚˜μ˜ 폴더에 λ¬ΆλŠ”λ‹€κ±°λ‚˜ μ—¬λŸ¬κ°€μ§€ 역할을 ν•˜λŠ” μ†ŒμŠ€μ½”λ“œ 덩어리듀을 각각의 역할을 μˆ˜ν–‰ν•˜λŠ” μ—¬λŸ¬κ°œμ˜ μ†ŒμŠ€μ½”λ“œλ‘œ λΆ„λ¦¬μ‹œμΌœ λ³„λ„μ˜ 파일둜 λ§Œλ“œλŠ” μž‘μ—…μ€ μƒν™œν™”κ°€ λ˜μ–΄μžˆμ–΄μ•Ό λ‚˜μ€‘μ— ν”„λ‘œμ νŠΈ 규λͺ¨κ°€ μ»€μ Έκ°ˆλ•Œ κ·Έλ‚˜λ§ˆ.. κ·Έ!λ‚˜!마! μœ μ§€λ³΄μˆ˜λ₯Ό 쑰금 νŽΈν•˜κ²Œ λ§Œλ“€μ–΄μ€λ‹ˆλ‹€.

(μ•„ 이건 μ‚¬λžŒλ°”μ΄ μ‚¬λžŒ 그리고 μ‹€λ ₯바이 μ‹€λ ₯인것 κ°™μ•„μš”. 제 μ½”λ“œλŠ” μœ μ§€λ³΄μˆ˜κ°€ μ–΄λ ΅κ²Œλ§Œ λŠκ»΄μ§€λŠ”κ±΄... )

 

routingμž‘μ—…μ„ ν• λ•Œμ—λ„ 이 경둜λ₯Ό 잘 ꡬ뢄지어 μž‘μ—…ν•˜λŠ”κ²ƒ λ˜ν•œ! 같은 λ§₯락으둜 μ€‘μš”ν•©λ‹ˆλ‹€.

 

μ•žμœΌλ‘œ μš°λ¦¬λŠ” REST API μ„œλ²„λ₯Ό λ§Œλ“€κΊΌκΈ° λ•Œλ¬Έμ— λ‹€μŒμ„ μœ μ˜ν•˜λ©° λ§Œλ“€μ–΄μ•Ό ν•©λ‹ˆλ‹€.

  1. API 버전별 관리

  2. λΉ„μŠ·ν•œ 역할을 μˆ˜ν–‰ν•˜λŠ” κΈ°λŠ₯끼리 관리

  3. 각 κ²½λ‘œλ³„ μˆ˜ν–‰ν•˜λŠ” ν•¨μˆ˜λ“€(Controller) 관리

자 첫번째 쑰건뢀터 클리어 ν•˜κΈ°μ „μ— λΌμš°νŒ… 경둜λ₯Ό μœ„ν•œ 폴더λ₯Ό λ§Œλ“€μ–΄ κ·Έκ³³μ—μ„œλ§Œ λΌμš°νŒ… μž‘μ—…μ„ μ²˜λ¦¬ν•˜λ„λ‘ apiλΌλŠ” μƒˆλ‘œμš΄ 폴더λ₯Ό 생성해 λ³΄κ² μŠ΅λ‹ˆλ‹€.

( κ²½λ‘œλŠ” src 폴더 μ•ˆμ— λ§Œλ“€μ–΄μ£Όμ„Έμš” )

 

이제 첫번째 쑰건을 클리어 ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

버전별 관리λ₯Ό ν•˜κΈ°μœ„ν•΄ 각 λ²„μ „λ§ˆλ‹€ 폴더λ₯Ό ν•˜λ‚˜ λ§Œλ“€μ–΄μ£Όκ² μŠ΅λ‹ˆλ‹€. 폴더 이름은 v1.0으둜 ν• κ²Œμš”.

(처음 λ§Œλ“œλŠ” 버전이기에 v1.0으둜 ν•©λ‹ˆλ‹€. κ²½λ‘œλŠ” api 폴더 μ•ˆμ— λ§Œλ“€μ–΄μ£Όμ„Έμš”.)

 

그리고 각 버전별 폴더듀을 관리해쀄 수 μžˆλ„λ‘ μ†ŒμŠ€μ½”λ“œλ₯Ό μž‘μ„±ν•΄μ•Ό ν•¨μœΌλ‘œ api ν΄λ”μ•ˆμ— index.js νŒŒμΌλ„ 같이 생성해 주도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

( μ΄κ³³μ—μ„œ 각 버젼별 λΌμš°νŒ… 연결을 ν•΄μ€„κ±°μ—μš” )

자 μž˜λ”°λΌμ™”μŠ΅λ‹ˆλ‹€. 근데 μ—¬κΈ°μ„œ μš°λ¦¬κ°€ 빠뜨린게 ν•˜λ‚˜ μžˆμ–΄μš”. 그게 무엇이냐면 이 api 폴더λ₯Ό μ •ν™•νžˆλŠ” api폴더 μ•ˆμ— μžˆλŠ” νŒŒμΌλ“€μ„ routing 해쀄 api/index.js λ₯Ό μš°λ¦¬κ°€ λ§Œλ“  μ„œλ²„νŒŒμΌ src/index.js 와 연결을 ν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.

 

λ‹€μŒ μž‘μ—…μœΌλ‘œ λ„˜μ–΄κ°€κΈ°μ „μ— 이 μž‘μ—…μ„ λ¨Όμ € ν•΄μ£Όκ³  가도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

src/index.js νŒŒμΌμ„ μ—΄μ–΄μ£Όμ„Έμš”.

 

μš°λ¦¬κ°€ μ΄μ „μ—λŠ” router객체 λ‚΄μž₯ λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν• λ•Œ get만 μ‚¬μš©ν•΄ λ³΄μ•˜λŠ”λ°μš”. 이 router객체에도 app객체에 미듀웨어λ₯Ό μ—°κ²°ν–ˆλ˜κ²ƒμ²˜λŸΌ λ˜λ‹€λ₯Έ router객체λ₯Ό μ—°κ²°ν•˜λŠ”κ²ƒμ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.

( appκ°μ²΄μ—μ„œμ™€ 같이 use λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. ex/ routes.use('/api ', api.routes()) ) 

 

λ°”λ‘œ use λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜κΈ°μ „μ— μš°λ¦¬κ°€ λ§Œλ“  api/index.jsνŒŒμΌμ„ λ¨Όμ € src/index.js 상단에 λΆˆλŸ¬μ™€μ£Όλ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

이제 api μ•ˆμ— index.jsλ₯Ό λΆˆλŸ¬μ™”μœΌλ‹ˆ 연결을 해봐야겠죠?

 

μ‚¬μš©λ²•μ€ κ°„λ‹¨ν•©λ‹ˆλ‹€. μ•„λž˜μ˜ μ†ŒμŠ€μ½”λ“œμ²˜λŸΌ μž‘μ„±μ„ ν•΄μ£Όλ©΄ λ©λ‹ˆλ‹€.

// about routing
const router = new Router();

router.use('/api', api.routes());
router.get('/', (ctx) => {
  ctx.body = 'ν™ˆ';
});

μ—¬κΈ°μ„œ api 뒀에 routes에 λŒ€ν•˜μ—¬ μ•Œμ•„λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€. 

( 사진을 λ³΄λ©΄μ„œ μ•Œμ•„λ³Όκ²Œμš”. )

μš°λ¦¬λŠ” 이전 ν¬μŠ€νŒ…μ—μ„œ koa-router 객체λ₯Ό app에 μ μš©ν• λ•Œ ν•œλ²ˆ routesλ₯Ό μ‚¬μš©ν–ˆμ—ˆλŠ”λ°μš”.

routesλŠ” μš°λ¦¬κ°€ λ§Œλ“  koa-router 객체 (μœ„μ˜ 그림에선 routerκ°€ λ˜κ² λ„€μš”) 에 μ—°κ²°ν•œ λͺ¨λ“  κ²½λ‘œλ“€μ„ μ˜λ―Έν•©λ‹ˆλ‹€. 즉 μš°λ¦¬λŠ” get을 μ΄μš©ν•œ '/'의 경둜만 μžˆμ—ˆκ² μ£ ? 

 

λ‹€μ‹œ λŒμ•„μ™€μ„œ router.use()의 κ΄„ν˜Έμ•ˆμ— 또라λ₯Έ router객체의 routesλ₯Ό 집어 λ„£λŠ”κ²ƒμ€ νŠΉμ •κ²½λ‘œ(μ—¬κΈ°μ„  '/api')둜 λ“€μ–΄μ™”μ„λ•Œ λͺ¨λ‘ μƒˆλ‘­κ²Œ 집어넣은 rotuer객체둜 연결함을 μ˜λ―Έν•©λ‹ˆλ‹€.

 

뭐 이런λͺ¨μŠ΅μΌκΉŒμš”?

 

μœ„μ˜ μ‚¬μ§„μ—μ„œ μ˜ˆλ‘œλ“€μ–΄ '/auth' κ²½λ‘œλŠ” μœ„μ˜ '/api 'κ²½λ‘œμ™€ ν•©μ³μ Έμ„œ '/api/auth' κ°€ λ˜μ–΄μ§€κ² λ„€μš”.

 

μ΄λ ‡κ²Œ μ™ΈλΆ€μ—μ„œ λΌμš°νŒ… μž‘μ—…μ„ ν•˜κ³  λ©”μΈμœΌλ‘œ μ‚¬μš©ν•˜λŠ” λΌμš°νŒ… 객체에 ν•©μΉ˜λŠ” 것이 κ°€λŠ₯ν•΄μ§‘λ‹ˆλ‹€.

일단 μš°λ¦¬κ°€ 처음으둜 λ§Œλ“€ λΌμš°νŒ…μ€ REST APIλ₯Ό μœ„ν•œ κ²ƒμž„μœΌλ‘œ apiλΌλŠ” 경둜둜 λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

 

λ”°λΌμ„œ 같이 μ½”λ”©μž‘μ—…μ„ 계속 μ΄μ–΄λ‚˜κ°€ λ³Όκ²Œμš”.

 

μ΄λ ‡κ²Œ 연결은 ν–ˆμ§€λ§Œ... 사싀 μš°λ¦¬λŠ” api/index.js에 아무 μ†ŒμŠ€μ½”λ“œλ„ 넣지 μ•Šμ•˜μŠ΅λ‹ˆλ‹€ γ…Žγ…Ž

μœ„μ™€ 같이 μž‘μ„±ν•˜κΈ° μœ„ν•΄μ„œ api λ₯Ό router 객체둜 λ§Œλ“€μ–΄μ£Όμ–΄μ•Ό κ² μ£ ? 

그럼 λ‹€μ‹œ api/index.js 파일둜 κ°€μ„œ μž‘μ—…μ„ 진행해 λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

src/index.js의 apiλ₯Ό router 객체둜 λ§Œλ“€μ–΄μ€€λ‹€λŠ” 것은 api/index.jsμ—μ„œ router객체λ₯Ό λ°–μœΌλ‘œ λ‚΄λ³΄μ€€λ‹€λŠ”κ²ƒμ„ μ˜λ―Έν•©λ‹ˆλ‹€. 고둜 μ΄κ³³μ—μ„œλ„ router 객체λ₯Ό μƒˆλ‘­κ²Œ λ§Œλ“€μ–΄μ£Όλ„λ‘ ν• κ²Œμš”.

const Router = require('koa-router');
const ver1 = require('./v1.0');

const api = new Router();
/* /api/... */
api.use('/v1.0', ver1.routes());

module.exports = api;

 ( μ—¬κΈ°μ„œ λ°–μœΌλ‘œ λ‚΄λ³΄λ‚΄μ£ΌλŠ” μ†ŒμŠ€μ½”λ“œλŠ” module.exports μž…λ‹ˆλ‹€. )

 

μ•„λ§ˆ μ•žμ„  λ‚΄μš©μ„ μ΄ν•΄ν•˜μ…¨λ‹€λ©΄ λˆˆμΉ˜μ±„μ…¨μ„ κ²λ‹ˆλ‹€. μ—¬κΈ°μ„œλŠ” 버전별 관리λ₯Ό ν•˜κΈ°λ•Œλ¬Έμ— μš°λ¦¬κ°€ 미리 μƒμ„±ν•œ ver1κ³Ό api λΌλŠ” μ΄λ¦„μ˜ router 객체와 또 연결을 ν•΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€. μ΄λŸ°μ‹μœΌλ‘œ κ³„μΈ΅ν˜•μ‹μœΌλ‘œ 연결을 ν•΄μ£Όμ–΄ 관리λ₯Ό ν•΄μ£Όλ©΄ λ‚˜μ€‘μ— νŠΉμ • λΌμš°ν„°μ—μ„œ 였λ₯˜κ°€ λ‚˜λ„ μ‰½κ²Œ μ°Ύμ•„κ°€ 였λ₯˜λ₯Ό μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

근데 velopertλ‹˜ κ°•μ’Œλ₯Ό λ³΄λ‹ˆκΉ 버전관리 μœ μ§€λ³΄μˆ˜λ₯Ό μœ„ν•΄μ„œ ver1λ³€μˆ˜μ²˜λŸΌ 쓰지 μ•Šκ³  배열을 λ§Œλ“€μ–΄μ„œ 관리λ₯Ό ν•˜λ”κ΅°μš”. μš°λ¦¬λ„ κ³ μˆ˜λ‹˜μ˜ κ°€λ₯΄μΉ¨μ„ μ†ŒμŠ€μ½”λ“œμ— μ μš©μ‹œμΌœ λ³΄κ² μŠ΅λ‹ˆλ‹€.

const Router = require('koa-router');
// Version 관리 1.0
const versions = {
  'v1.0': require('./v1.0')
};

const api = new Router();
/* /api/... */
api.use('/v1.0', versions['v1.0'].routes());

module.exports = api;

4번째 μ€„μ—μ„œ 였λ₯˜κ°€ λ‚œλ‹€κ³  κ±±μ •ν•˜μ§€λ§ˆμ„Έμš”. : ) 였λ₯˜κ°€ λ‚˜λŠ” μ΄μœ λŠ” μš°λ¦¬κ°€ μ†ŒμŠ€μ½”λ“œλ₯Ό μž‘μ„±ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€ ^^

 

ν›„... μ΄μ œμ•Ό 첫번째 쑰건을 클리어 ν–ˆμŠ΅λ‹ˆλ‹€. 이제 λ‘λ²ˆμ§Έ 쑰건을 ν΄λ¦¬μ–΄ν•΄μ€„κ»λ‹ˆλ‹€.

 

λ‘λ²ˆμ§Έ 쑰건은 λΉ„μŠ·ν•œ κΈ°λŠ₯끼리 λ¬Άμ–΄μ£ΌλŠ”κ²ƒ μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

이λ₯Ό μœ„ν•΄μ„œ 각 κΈ°λŠ₯별 경둜λ₯Ό κ΄€λ¦¬ν•΄μ£ΌλŠ” v1.0/index.js νŒŒμΌμ„ 생성해 λ‚΄λΆ€ μ†ŒμŠ€μ½”λ“œλ₯Ό μž‘μ„±ν•΄ 보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

μ„€λͺ…은 μœ„μ™€ κ°™μŒμœΌλ‘œ μ„€λͺ…없이 μ†ŒμŠ€μ½”λ“œ μž‘μ„±μ„ μ΄μ–΄κ°ˆκ²Œμš”.

 

ν˜„μž¬κΉŒμ§€μ˜ 폴더ꡬ성을 κ³΅μœ ν•©λ‹ˆλ‹€.

v1.0/index.js μ•ˆμ— μ†ŒμŠ€λ„ κ³΅μœ λ“œλ¦΄κ²Œμš”.

const Router = require('koa-router');

const api = new Router();

/* /api/v1.0/... */

module.exports = api;

이제 2번째 쑰건도 클리어 ν–ˆμŠ΅λ‹ˆλ‹€. μ•žμœΌλ‘œ μƒˆλ‘œμš΄ apiμš”μ²­μ— λŒ€ν•œ κΈ°λŠ₯을 λ§Œλ“€λ•Œ κΈ°λŠ₯λ³„λ‘œ v1.0ν΄λ”μ•ˆμ— μƒˆλ‘œμš΄ 폴더λ₯Ό λ§Œλ“€μ–΄ κ·Έ μ•ˆμ—μ„œ router 경둜λ₯Ό κ΄€λ¦¬ν•˜κ³  μœ„μ˜ 사진6번째 μ€„μ—μ„œ use λ©”μ„œλ“œλ₯Ό 톡해 μ—°κ²°λ§Œ ν•΄μ£Όλ©΄ λ©λ‹ˆλ‹€.

 

마치 μ•„λž˜μ™€ 같은 μ‚¬μ§„μ²˜λŸΌ 말이죠.
( 곡뢀쀑인 개인 ν”„λ‘œμ νŠΈ μ‚¬μ§„μž…λ‹ˆλ‹€. )

 

였늘 ν¬μŠ€νŒ…μ€ μ—¬κΈ°κΉŒμ§€ μž‘μ„±ν• ν…λ°μš”, 사싀 λΌμš°νŒ… μž‘μ—…μ„ 얼릉 끝마치고 DB μ—°κ²°κΉŒμ§€ ν¬μŠ€νŒ…ν•  μ˜ˆμ •μ΄μ—ˆμ§€λ§Œ... 생각보닀 이뢀뢄에 λŒ€ν•œ λ‚΄μš©μ΄ λ§Žμ•„ ν¬μŠ€νŒ… 글이 κΈΈμ–΄μ§€κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

 

κ·Έλž˜μ„œ λ‹€μŒ ν¬μŠ€νŒ…μ—μ„œ λΌμš°νŒ…μž‘μ—… μš”μ•½ ν•˜κ³  DB 연결을 해주도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€. 

 

TodoList

  1. λΌμš°νŒ… μš”μ•½ν•˜κΈ°
  2. DB μ—°κ²°ν•˜κΈ° ( MongoDB )