๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๋ฐฑ์—”๋“œ/ORM

[TypeORM] ์™œ ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค ํ”„๋กœํผํ‹ฐ๋ฅผ private์œผ๋กœ ํ•  ์ˆ˜ ์—†์„๊นŒ?

๋ฌธ์ œ ์ƒํ™ฉ

 

  • TypeORM ์‚ฌ์šฉ ์ค‘ Entity ํด๋ž˜์Šค์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ private์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ๋”๋‹ˆ ์ด๋Ÿฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
    "Property "id" was not found in "Expense". Make sure your query is correct."
  • ์ฒ˜์Œ์—๋Š” ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„ ์•ž์— ์–ธ๋”์Šค์ฝ”์–ด๋ฅผ ๋ถ™์—ฌ์„œ ๋งคํ•‘์ด ์•ˆ ๋˜๋Š” ๊ฑด๊ฐ€ ํ–ˆ๋Š”๋ฐ, ํ”„๋กœํผํ‹ฐ๋ฅผ public์œผ๋กœ ํ•ด์•ผ๋งŒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๊ฐ์ฒด๊ฐ€ ์ž๋™์œผ๋กœ ๋งคํ•‘๋˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.
  • JPA๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์—”ํ‹ฐํ‹ฐ์˜ ๋ชจ๋“  ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ private์œผ๋กœ ์„ ์–ธํ•˜๊ณ  getter & setter๋ฅผ ๋‘์–ด ์บก์Аํ™”๋ฅผ ํ•˜์—ฌ, ์—”ํ‹ฐํ‹ฐ์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋‹ด์€ public ๋ฉ”์„œ๋“œ๋ฅผ ๋‘์–ด ์„œ๋น„์Šค์—์„œ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„์˜ ์ •์„(?)์ด๋ผ๊ณ  ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค... TypeORM์—์„œ๋„ ์ด์™€ ๋น„์Šทํ•˜๊ฒŒ ํ•ด๋ณด๊ณ  ์‹ถ์—ˆ์œผ๋‚˜ ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค์˜ private ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์˜€์Šต๋‹ˆ๋‹ค.

 

์™œ TypeORM์—์„œ๋Š” ์—”ํ‹ฐํ‹ฐ์˜ private ํ”„๋กœํผํ‹ฐ๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š์„๊นŒ?

์™œ์ธ์ง€ ๊ถ๊ธˆํ•ด์ ธ์„œ ๊ตฌ๊ธ€๋ง ํ•ด๋ณด์•˜๋Š”๋ฐ, TypeORM GitHub issue์—์„œ ์ด์™€ ๊ด€๋ จํ•œ TypeORM ๊ฐœ๋ฐœ์ž์˜ ์ƒ๊ฐ์„ ์—ฟ๋ณผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น ์ด์Šˆ๋Š” "Support for private entity attributes"๋ผ๋Š” ์ œ๋ชฉ์œผ๋กœ ์—”ํ‹ฐํ‹ฐ์˜ private ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ์ œ์•ˆ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

 

์ด์Šˆ๋ฅผ ์ž‘์„ฑํ•œ ๋ถ„์˜ ์ƒ๊ฐ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„์—์„œ๋Š” Getter/Setter๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹ , ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค.
  • ์ง€๊ธˆ๋„ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€๋งŒ, ํ”„๋กœํผํ‹ฐ๊ฐ€ public์ด๋ฉด ์‹ค์ˆ˜๋กœ ์—”ํ‹ฐํ‹ฐ์˜ ์ƒํƒœ๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์—”ํ‹ฐํ‹ฐ ํ”„๋กœํผํ‹ฐ๋ฅผ private์œผ๋กœ ์„ ์–ธํ•˜๋ฉด repository์—์„œ ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ ํƒํ•  ์ˆ˜๊ฐ€ ์—†๋‹ค.
  • ๋”ฐ๋ผ์„œ ์—”ํ‹ฐํ‹ฐ ํ”„๋กœํผํ‹ฐ๋ฅผ private์œผ๋กœ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ repository์—์„œ ์ ‘๊ทผํ•ด ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆด ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ์•ˆํ•œ๋‹ค.

 

์ด์— ๋Œ€ํ•œ ๋‹ต๋ณ€์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์—”ํ‹ฐํ‹ฐ์˜ ์†์„ฑ์„ private์œผ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์ด ์œ ์ผํ•œ ์บก์Аํ™” ๋ฐฉ์‹์€ ์•„๋‹ˆ๋‹ค.
  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด๋‚˜ ์†์„ฑ ์ ‘๊ทผ ์ œ์–ด๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” ๊ทธ ๋ชฉ์ ์— ๋งž๋Š” ๋ณ„๋„์˜ ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ผ ์ˆ˜ ์žˆ๋‹ค.
  • ์—”ํ‹ฐํ‹ฐ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ ์ •์˜์šฉ์œผ๋กœ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • ์บก์Аํ™”๊ฐ€ ๋ถ€์กฑํ•˜๋‹ค๋Š” ์ฃผ์žฅ์—๋Š” ๋™์˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋„๋ฉ”์ธ ์ฃผ๋„ ๊ฐœ๋ฐœ์„ ๋”ฐ๋ฅด๋Š” ๋Œ€๊ทœ๋ชจ ์‹œ์Šคํ…œ์—์„œ TypeORM์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์บก์Аํ™”์— ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ๋‹ค. 
  • ์บก์Аํ™”๋ฅผ ์ถ”๊ตฌํ• ์ˆ˜๋ก ์˜ค๋ฒ„์—”์ง€๋‹ˆ์–ด๋ง์ด ๋  ์ˆ˜ ์žˆ๋‹ค. ์‹œ์Šคํ…œ์— ์ •๋ง ๊ทธ ์ •๋„์˜ ์บก์Аํ™”๊ฐ€ ํ•„์š”ํ•œ์ง€ ๋‹ค์‹œ ํ•œ ๋ฒˆ ์ƒ๊ฐํ•ด๋ณด๋ผ.

 

๋‚˜์˜ ์ƒ๊ฐ

TypeORM ๊ฐœ๋ฐœ์ž์˜ ์ฝ”๋ฉ˜ํŠธ๋ฅผ ๋ณด์•˜์„ ๋•Œ ํ•ต์‹ฌ ๋‚ด์šฉ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

  1. ์บก์Аํ™” ์ˆ˜์ค€์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋งก๊ธด๋‹ค.
  2. ์—”ํ‹ฐํ‹ฐ๋Š” ์Šคํ‚ค๋งˆ ์ •์˜์šฉ์œผ๋กœ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค.

ํด๋ฆฐ ์ฝ”๋“œ 6์žฅ์˜ ๋‚ด์šฉ์„ ์กฐ๊ธˆ ์ฐธ๊ณ ํ•ด๋ณด์ž๋ฉด '์ž๋ฃŒ ๊ตฌ์กฐ'์™€ '๊ฐ์ฒด'๋Š” ๋‹ค๋ฅด๋‹ค๊ณ  ์ด์•ผ๊ธฐ ํ•ฉ๋‹ˆ๋‹ค.

ํด๋ฆฐ ์ฝ”๋“œ์—์„œ ์ด์•ผ๊ธฐํ•˜๋Š” ์ž๋ฃŒ ๊ตฌ์กฐ๋Š” ๊ณต๊ฐœ ๋ณ€์ˆ˜๋งŒ ์žˆ๊ณ  ํ•จ์ˆ˜๊ฐ€ ์—†๋Š” ํด๋ž˜์Šค, ๊ฐ์ฒด๋Š” ๋น„๊ณต๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋งŒ ๊ณต๊ฐœํ•ฉ๋‹ˆ๋‹ค.

์ด ๋‘˜์ด ํ˜ผํ•ฉ๋œ ๊ตฌ์กฐ์˜ ํ•œ ๊ฐ€์ง€ ์‚ฌ๋ก€๋กœ ORM์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ๋˜๋Š” Active Record ํŒจํ„ด์ด ์žˆ๋Š”๋ฐ, ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ์™€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ฒ˜๋ฆฌ์˜ ๋‘ ๊ฐ€์ง€ ์—ญํ• ์„ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•˜์—ฌ ๋‹จ์ผ ์ฑ…์ž„ ์›์น™์„ ๋”ฐ๋ฅด์ง€ ์•Š๊ฒŒ ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

TypeORM ๊ฐœ๋ฐœ์ž๊ฐ€ ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ๋”ฐ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์ถ”์ฒœํ•œ ์ ๊ณผ ์—”ํ‹ฐํ‹ฐ๋Š” ์Šคํ‚ค๋งˆ ์ •์˜์šฉ์œผ๋กœ๋งŒ ์‚ฌ์šฉํ•˜๋ผ๋Š” ์ด์•ผ๊ธฐ๋ฅผ ํ•œ ๊ฒƒ์œผ๋กœ ๋ณด์•„, ๋‘ ๊ฐ€์ง€ ์šฉ๋„๋ฅผ ํ•˜๋‚˜์˜ ๊ฐ์ฒด์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๋™์˜ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์˜€์Šต๋‹ˆ๋‹ค. 

 

๊ฐœ์ธ์ ์œผ๋กœ๋Š”... ์บก์Аํ™”๋ฅผ ํ• ์ˆ˜๋ก ์˜ค๋ฒ„ ์—”์ง€๋‹ˆ์–ด๋ง์ด ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ง์—๋Š” ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. TypeORM์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ public์ธ ๋งŒํผ ์–ด๋””๊นŒ์ง€, ์–ด๋–ป๊ฒŒ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์บก์Аํ™”ํ•  ๊ฒƒ์ธ์ง€ ๋งŽ์€ ๊ณ ๋ฏผ์ด ํ•„์š”ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

 

์ฐธ๊ณ  

https://cupeanimus.tistory.com/87

https://www.reddit.com/r/Nestjs_framework/comments/ih9hfd/nestjs_typeorm_how_to_enforce_encapsulation/

https://github.com/typeorm/typeorm/issues/3548

https://jojoldu.tistory.com/251