[FastAPI] 11. Dependency Injector๋ฅผ ์ด์šฉํ•œ ์˜์กด์„ฑ ๊ด€๋ฆฌ

๋ฐ˜์‘ํ˜•

์„œ๋ฒ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•˜๋‹ค๋ณด๋ฉด ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๊ฒŒ ๋˜์–ด ์ด๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์ƒ๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด์— ์ ์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋Œ€ํ‘œ์ ์ธ ์•„ํ‚คํ…์ฒ˜์ธ Layered Architecture๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Layered Architecture๋Š” ์„œ๋ฒ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์šด์šฉํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ํ˜„๋Œ€ ๋Œ€ํ‘œ์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ, Application, Domain, Infrastructure์˜ 3๊ฐœ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋“ค์„ ์ „๋ถ€ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋˜๋ฉด ๊ฐ๊ฐ์˜ ์˜์กด์„ฑ์ด ๋Š˜์–ด๋‚˜๊ฒŒ ๋˜๊ณ , ๊ทธ ๋กœ์ง์ด ์ปค์ง€๋ฉด ์ด ์—ญ์‹œ ๊ด€๋ฆฌ๊ฐ€ ํž˜๋“ค์–ด์ง‘๋‹ˆ๋‹ค.

 

Python์—์„œ๋Š” ์ด๋Ÿฌํ•œ ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์–‘ํ•œ DI ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ, ๊ทธ ์ค‘์—์„œ๋„ Dependency Injector๋ฅผ ์‚ฌ์šฉ ํ•ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

 

Dependency Injector

Python์—์„œ Django ํ˜น์€ DRF(Django REST Framework)๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์‹  ๋ถ„๋“ค์ด๋ผ๋ฉด ๊ทธ๋“ค์— ๋‚ด์žฅ๋œ DI ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋ณด์…จ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. Django์˜ ๊ฒฝ์šฐ๋Š” Dictionary๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฃผ์ž…ํ•˜๊ณ , DRF์˜ ๊ฒฝ์šฐ๋Š” class๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฃผ์ž…ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ์š”. ๋ฌธ์ œ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ฐ•ํ•˜๊ฒŒ ์ข…์†์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

Dependency Injector๋Š” ์–ด๋Š ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์— ์ข…์†์ ์ด์ง€ ์•Š๊ณ , ์ผ๋ฐ˜ Python์—์„œ๋„ ์œ ์šฉํžˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” Python์˜ DI ํ”„๋ ˆ์ž„์›Œํฌ์ด๋ฉฐ Dependency Injector์˜ ์ฃผ ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

https://python-dependency-injector.ets-labs.org/introduction/di_in_python.html

 

Dependency injection and inversion of control in Python — Dependency Injector 4.36.0 documentation

Dependency injection and inversion of control in Python Originally dependency injection pattern got popular in the languages with a static typing, like Java. Dependency injection is a principle that helps to achieve an inversion of control. Dependency inje

python-dependency-injector.ets-labs.org

 

  • ์œ ์—ฐ์„ฑ (Flexibility)

    ๊ฐ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋Š์Šจํ•œ ๊ฒฐํ•ฉ์œผ๋กœ ๋˜์–ด ์žˆ์–ด ๊ธฐ๋Šฅ์˜ ๋ณ€๊ฒฝ๊ณผ ํ™•์žฅ์ด ์‰ฌ์›€.

  • ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ์„ฑ (Testability)

    ์ปดํฌ๋„ŒํŠธ์˜ ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  Mockingํ•˜์—ฌ ์ฃผ์ž…ํ•ด ํ…Œ์ŠคํŠธ์— ์šฉ์ด

  • ๋ช…ํ™•์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜ (Clearness and maintainability)

    ๋ช…์‹œ์  ์˜์กด์„ฑ ์ฃผ์ž…์„ ์ด์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์กฐ๋ฅผ ์‰ฝ๊ฒŒ ํŒŒ์•…ํ•ด ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์šฉ์ด

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

 

Python์—์„œ๋Š” Unittest๋ผ๋Š” ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์กด์žฌํ•˜๊ณ , ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” Mocking(๋ชจ์กฐํ’ˆํ™”) ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ Mocking์ด๋ž€, ์šฐ๋ฆฌ๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰์‹œ ์‚ฌ์šฉํ•˜๋Š” ์ธ์Šคํ„ด์Šค์˜ ์‹ค์ฒด๊ฐ€ ์•„๋‹Œ ๋ชจ์กฐํ’ˆ์„ ์ œ๊ณตํ•˜๋ฉฐ ์šฐ๋ฆฌ๊ฐ€ ์—ฌ๊ธฐ์„œ ๊ตฌํ˜„ํ•ด์•ผ ํ•  ๊ธฐ๋Šฅ์„ ๊ทธ๋Œ€๋กœ ์ œ๊ณตํ•ด์ฃผ์ง€ ์•Š๊ณ , ๊ทธ ๊ฒ‰๋ชจ์Šต๋งŒ์„ ์ œ๊ณตํ•˜์—ฌ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์–ด Flow ํ…Œ์ŠคํŠธ์— ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

 

๋งˆ์ง€๋ง‰์œผ๋กœ ๋ช…์‹œ์  ์˜์กด์„ฑ ์ฃผ์ž…(explicit dependency)์„ ์ด์•ผ๊ธฐํ–ˆ๋Š”๋ฐ, ์ž ๊น ์„ค๋ช…์„ ๋“œ๋ฆฌ์ž๋ฉด, ๋ช…์‹œ์  ์˜์กด์„ฑ ์ฃผ์ž…์€ ์˜์กด ๋Œ€์ƒ์„ ์ƒ์„ฑ์ž์˜ ์ธ์ž๋กœ ์ „๋‹ฌํ•˜์—ฌ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ์‹์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋Œ€๋ง๋กœ ์•”๋ฌต์  ์˜์กด์„ฑ(hidden dependency)์ด ์žˆ๋Š”๋ฐ, ์•”๋ฌต์  ์˜์กด์„ฑ์€ ์ƒ์„ฑ์ž ๋‚ด ๋˜๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด ์–ด๋–ค ๊ฒƒ์— ์˜์กดํ•˜๋Š”์ง€๋ฅผ ๊ฐ์ถ”๋Š” ์ฃผ์ž… ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

 

ํ›„์ž๋Š” ๋˜ ๋‹ค์‹œ ๊ทธ ์˜์กด์„ฑ์˜ ์ฝ”๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ๋Š”์ง€๋ฅผ ํŒŒ์•…ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์• ํ”Œ๋ฆฌ์ผธ์ด์…˜์ด ๋ณต์žกํ•ด์ง์— ๋”ฐ๋ผ ๊ทธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์กฐ๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ต๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ๊ทธ๋งŒํผ ์–ด๋ ค์›Œ์ง€๋ฏ€๋กœ ๋ช…์‹œ์  ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ†ตํ•ด ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฝ๋„๋ก ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

 

with FastAPI

Dependency Injector๋Š” FastAPI ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ํ•˜๊ธฐ ์•„์ฃผ ์ข‹์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ๋จผ์ € FastAPI์˜ ๊ธฐ๋ณธ ์• ํ”Œ๋ฆฌ์ผ€์•„์…˜ ๊ตฌ์กฐ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

src์—๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์†Œ์Šค, tests์—๋Š” ์ด์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค. Dependency Injector๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์— ์šฉ์ดํ•˜๋‹ค๋Š” ํŠน์ง•์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋‹ˆ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋„ ๊ฐ™์ด ์ž‘์„ฑํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์—”๋“œํฌ์ธํŠธ(API), ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง(Service), ์ธํ”„๋ผ์ŠคํŠธ๋Ÿญ์ณ(Repository ์ดํ•˜ DB) 3 Layer์˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์˜ Dependency Injector๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๋จผ์ € containers.py ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์˜์กด์„ฑ์„ ๊ด€๋ฆฌํ•  IoC๋ฅผ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

 

Declarative Container

Declarative Container๋Š” Dependency Injector์—์„œ ์˜์กด์„ฑ์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ๋ณธ ์ปจํ…Œ์ด๋„ˆ์ž…๋‹ˆ๋‹ค. ์ด ์ปจํ…Œ์ด๋„ˆ์—์„œ๋Š” ์˜์กด์„ฑ ๊ด€๋ฆฌ ๋ฟ ์•„๋‹ˆ๋ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ค์ •๋„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

DelclarativeContainer๋ฅผ ์ƒ์†ํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์—ฌ๊ธฐ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ค์ •์„ ์ถ”๊ฐ€ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ Provider ํŒจํ‚ค์ง€์— ์žˆ๋Š” Configuration ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Provider์—์„œ ์ œ๊ณตํ•˜๋Š” Configuration์—์„œ๋Š” ์•„๋ž˜์˜ 5๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

  • ini ํŒŒ์ผ
  • Python์˜ Dict ์ž๋ฃŒํ˜•
  • yaml ํŒŒ์ผ
  • Pydantic์˜ Settings ํด๋ž˜์Šค
  • OS Environment

 

Python์œผ๋กœ ๊ฐœ๋ฐœํ•ด๋ณด์‹  ๋ถ„๋“ค์ด๋ผ๋ฉด Pydantic์„ ์ž˜ ์•Œ๊ฒ ์ง€๋งŒ Pydantic์€ Python์—์„œ Type annotation์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์™€ ์„ค์ •์„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ FastAPI์—์„œ๋Š” ์š”์ฒญ๊ณผ ์‘๋‹ต ํด๋ž˜์Šค์˜ ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•ด ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ์ด ์™ธ์—๋„ ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•œ ํด๋ž˜์Šค๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด Python์—์„œ๋Š” ์ด๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์œ„ ์ฝ”๋“œ๋Š” Pydantic์˜ Settings ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„ค์ •ํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. Database ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ CORS, AUTH-KEY ๋“ฑ์˜ ์„ค์ •๋„ ํด๋ž˜์Šคํ™”ํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฝ๊ณ  ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— dotenv์™€ OS environment๋ฅผ ๊ฐ™์ด ์จ์„œ ์„ค์ •์„ ๊ด€๋ฆฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ์ปจํ…Œ์ด๋„ˆ๋“ค์ด ์žˆ์ง€๋งŒ Dependency Injector์—์„œ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ด๊ณ  ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ปจํ…Œ์ด๋„ˆ์ด๊ธฐ ๋•Œ๋ฌธ์— FastAPI๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์žˆ์–ด์„œ๋Š” ์„ ์–ธ์  ์ปจํ…Œ์ด๋„ˆ๊นŒ์ง€๋งŒ ์•„์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™๋„ค์š”.

 

์ž ๊ทธ๋Ÿผ ์ด์ œ ์—ฌ๊ธฐ์„œ ์˜์กด์„ฑ ์ฃผ์ž…์€ ์–ด๋–ป๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?

 

 

 

 

Dependency Injector๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์˜์กด์„ฑ ์ƒ์„ฑ ๋งค์ปค๋‹ˆ์ฆ˜ 

Dependency Injector์—์„œ๋Š” ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋งค์ปค๋‹ˆ์ฆ˜์„ Provider๋กœ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์˜์กด์„ฑ์„ ์ƒ์„ฑํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋ฉฐ ๊ทธ ์ข…๋ฅ˜๋Š” 10๊ฐ€์ง€๊ฐ€ ๋„˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์„œ 3๊ฐ€์ง€ ์ •๋„๋ฅผ ๋‹ค๋ฃฐ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋จผ์ € 1๊ฐ€์ง€๋Š” ์œ„์—์„œ ๋‹ค๋ฃฌ Configuration Provider์˜€์Šต๋‹ˆ๋‹ค.

 

๋‘ ๋ฒˆ์งธ๋Š” Singleton Provider์ž…๋‹ˆ๋‹ค. Singleton Provider๋Š” ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด ์•Œ๊ณ  ๊ณ„์‹œ๋Š” ์‹ฑ๊ธ€ํ„ด(Singleton) ํŒจํ„ด์„ ๋งํ•˜๋ฉฐ ๊ฐ์ฒด๋ฅผ ์‹ฑ๊ธ€ํ„ด์œผ๋กœ ์ƒ์„ฑํ•˜์—ฌ ์–ด๋Š ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋“  ๊ฐ™์€ ์˜์กด์„ฑ์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๊ฒ ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

providers์˜ Singleton์„ ์ด์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” Singleton ์ธ์ž์— ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ƒ์„ฑ์ž ์ธ์ž๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, kwargs๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋„ฃ์–ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋Š” ์‹ฑ๊ธ€ํ„ด์œผ๋กœ ๋™์ž‘ํ•˜์—ฌ ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ, ์–ด๋–ค ์ฃผ๊ธฐ์— ํ˜ธ์ถœํ•ด๋„ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.๋งŒ์•ฝ, ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•˜๊ธฐ ์›ํ•˜๋Š” ๊ฒฝ์šฐ, reset ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์„ธ ๋ฒˆ์งธ๋Š” Factory Provider์ž…๋‹ˆ๋‹ค. Factory Provider๋Š” Singleton๊ณผ๋Š” ๋ฐ˜๋Œ€๋กœ ๋งค๋ฒˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋งค์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. ํŒฉํ† ๋ฆฌ๋Š” ์‹ฑ๊ธ€ํ„ด์ฒ˜๋Ÿผ ์ƒ์„ฑ์ž์˜ ์ธ์ž๋ฅผ kwargs๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋”๋ถˆ์–ด Factory Provider Chaining ์ฆ‰, ์—ฐ๊ฒฐ ๊ณ ๋ฆฌ๋ฅผ ์ด์šฉํ•ด์„œ๋„ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ฐ„๋‹จํ•˜๊ฒŒ ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ณด๋„๋ก ํ•˜์ฃ .

 

MemoService ์ƒ์„ฑ์ž์—๋Š” Memo ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์ด ํ•„์š”ํ•˜๋ฉฐ ์ด๋ฅผ Factory๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ, argument ์ด๋ฆ„์„ ์ •์˜ํ•˜๊ณ  ๊ทธ ๋ชจ๋ธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

๋งŒ์•ฝ ์ƒ์„ฑ์ž์— ๋“ค์–ด๊ฐ€๋Š” ์˜์กด์„ฑ ๋˜ํ•œ Factory๋กœ ์ƒ์„ฑํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ, ์ด๋“ค์„ Factory๋กœ ๋ถˆ๋Ÿฌ์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ์‹์œผ๋กœ ๊ณ„์† ์ด์–ด์ น์„œ ์‚ฌ์šฉํ•˜๋ฉด Chaining ์ฝ”๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

 

์ž ์˜์กด์„ฑ ์ƒ์„ฑ์ด ๋๋‚ฌ์Šต๋‹ˆ๋‹ค. ์ด์ œ FastAPI์—์„œ ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?

 

 

 

 

Wiring

Dependency Injector์˜ Provider๋ฅผ ์ด์šฉํ•˜์—ฌ ์˜์กด์„ฑ ์ฃผ์ž…์„ ๋งˆ์นœ ๊ฒฝ์šฐ, ์šฐ๋ฆฌ๋Š” ์ด๋ฅผ ์‚ฌ์šฉํ•  ์ปดํฌ๋„ŒํŠธ ๋Œ€์ƒ์„ wireํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ wire ๋ž€, ์—ฐ๊ฒฐ์„ ๋œปํ•˜๋ฉฐ ์ปจํ…Œ์ด๋„ˆ์— ์žˆ๋Š” ์˜์กด์„ฑ์„ ํ•จ์ˆ˜ ํ˜น์€ ๋ฉ”์†Œ๋“œ์— ์ฃผ์ž…ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

 

์ฃผ์ž…ํ•˜๋ ค๋Š” ๋Œ€์ƒ์˜ ํ•จ์ˆ˜ ํ˜น์€ ๋ฉ”์†Œ๋“œ๊ฐ€ ๊ฐ™์€ ๋ชจ๋“ˆ์—์„œ Wiring ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” Dependency Injector์—์„œ ์ œ๊ณตํ•˜๋Š” inject ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์›ํ•˜๋Š” API๋ฅผ ๋งŒ๋“ค๊ณ , ํ•ด๋‹น ํ•จ์ˆ˜ ์œ„์— Dependency Injector์˜ inject ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฃผ์ž…ํ•œ ์˜์กด์„ฑ ์‚ฌ์šฉ์„ ์œ„ํ•ด Provide๋ฅผ ํ†ตํ•ด ์ฃผ์ž…ํ•œ ์˜์กด์„ฑ์„ ์–ด๋–ค ๋ณ€์ˆ˜์— ๋ฐฐ์น˜ํ• ์ง€๋ฅผ ์ •ํ•ด์ค๋‹ˆ๋‹ค. ์ด ๋•Œ FastAPI์˜ Depends๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์ „์— ๋ฐ˜๋“œ์‹œ Container๋ฅผ ์—ฐ๊ฒฐํ•˜๋ ค๋Š” ๋ชจ๋“ˆ์„ ์ •ํ•ด์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ•ด๋‹น ๋ชจ๋“ˆ์—๋Š” IoC๊ฐ€ ๋ฐฐ์ •๋˜์ง€ ์•Š์•„ import๋กœ ์ปจํ…Œ์ด๋„ˆ ๋‚ด ์˜์กด์„ฑ์„ ๊ฐ€์ ธ์˜ค๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋”๋ผ๋„ ๋ถˆ๋Ÿฌ์˜ค์ง€๋ฅผ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

 

๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๋””๋ฒ„๊น… ํ•ด๋ณด๋ฉด, MemoService ๊ฐ์ฒด๊ฐ€ ์ฃผ์ž…๋˜์—ˆ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

 

 

 

 

Test with FastAPI

์ด ํŒŒํŠธ์—์„œ๋Š” pytest, unittests์™€ ๊ฐ™์€ Python์˜ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์— ๋Œ€ํ•ด์„œ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜์ง€๋Š” ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ํŒŒํŠธ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Python์˜ ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์„ ์ง€์‹์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

FastAPI์—์„œ ์ž˜ ๋™์ž‘ํ•˜๋Š”์ง€๋ฅผ ํ…Œ์ŠคํŠธ ํ•ด๋ณผ ์ˆ˜ ์žˆ์„๊นŒ? Dependency Injector ๋ฌธ์„œ๋Š” FastAPI ํ”„๋ ˆ์ž„์›Œํฌ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์‚ฌ์šฉ๋ฒ•์„ ์ œ๊ณตํ•ด์ค๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ FastAPI ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ํ…Œ์ŠคํŠธํ•  ๋•Œ๋Š” ํ…Œ์ŠคํŠธ ๋กœ๋“œ๋งต์„ ์ž˜ ์งœ๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ๋ฐ, ๊ฐœ์ธ์ ์œผ๋กœ FastAPI์—์„œ Dependency๋ฅผ ํ…Œ์ŠคํŠธํ•  ๋•Œ unittest์˜ AsyncMock์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

Dependency Injector๊ฐ€ ๊ฐ€์ง€๋Š” ๊ฐ•์ ์€ ๋ฐ”๋กœ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ์„ฑ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์‹ค์ œ ์˜์กด์„ฑ์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ ๋„ ์ด๋Ÿฌํ•œ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ์•„ํ‚คํ…์ฒ˜๊ฐ€ ๋ฏธ๋ฆฌ ๊ตฌ์ƒ๋˜์–ด ์žˆ๋‹ค๋ฉด ์ด๋ฅผ Mockingํ•˜์—ฌ ํ…Œ์ŠคํŠธ ํ•ด ๋ณธ ๋‹ค์Œ ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ด์™€ ๊ฐ™์ด ๋™์ž‘ํ•˜๋Š”์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์œ„ ์˜ˆ์ œ๋Š” FastAPI๋ฅผ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋กœ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ์˜ˆ์‹œ์ด๋ฉฐ ์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ถ”๊ฐ€์ ์ธ ์ฝ”๋“œ๋ฅผ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. test_client๋Š” Python์˜ ๋น„๋™๊ธฐ ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ httpx๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒƒ์ด๋ฉฐ asgi์—๋Š” ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฐ์ฒด๊ฐ€ ๋‹ด๊ฒจ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

๋˜ํ•œ ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ปจํ…Œ์ด๋„ˆ์—์„œ Mocking์„ ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— FastAPI ๊ฐ์ฒด์˜ container attribute๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ IoC๋ฅผ ์ถ”๊ฐ€ํ•ด๋†“๊ณ , ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋™์ž‘ํ•  ๊ฒฝ์šฐ์˜ IoC๋ฅผ ๋งŒ๋“ค์–ด, ์˜์กด์„ฑ์„ Mocking ํ•ด์ค˜์•ผ๋งŒ ์›ํ™œํ•œ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์„ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋งˆ์ง€๋ง‰์œผ๋กœ Python์—์„œ ๊ฐ์ฒด๋ฅผ Mockingํ•  ๋•Œ๋Š” ๋น„๋™๊ธฐ ๊ฐ์ฒด๋ฅผ ๋ชจํ‚นํ•˜๋Š” AsyncMock๊ณผ ๋™๊ธฐ ๊ฐ์ฒด๋ฅผ ๋ชจํ‚นํ•˜๋Š” Mock์ด ์žˆ์Šต๋‹ˆ๋‹ค. Infrastructure ๋ ˆ์ด์–ด์—์„œ ๋น„๋™๊ธฐ ์—ฐ๊ฒฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ AsyncMock์„ ์‚ฌ์šฉํ•ด์•ผํ•˜์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ๋Š” Mock์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด ์งœ์‹œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ตฌํ˜„์— ๋”ฐ๋ผ ์ด๋ฅผ ์œ ๋™์ ์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

 

๋งˆ์น˜๋ฉฐ..

์—ฌ๊ธฐ๊นŒ์ง€ Dependency Injector๋ฅผ ์ด์šฉํ•˜์—ฌ FastAPI๋ฅผ ์˜ˆ์‹œ๋กœ ์˜์กด์„ฑ์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค. Django๋‚˜ DRF(Django Rest Framework)์˜ ๊ฒฝ์šฐ์—๋Š” ์ž์ฒด์ ์œผ๋กœ ์˜์กด์„ฑ ๊ด€๋ฆฌ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•˜์ง€๋งŒ Flask๋‚˜ Falcon, FastAPI์™€ ๊ฐ™์€ ๋งˆ์ดํฌ๋กœ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์„œ ์žฅ๋‹จ์ ์„ ๋‚˜๋ˆ  ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, Django์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ ์˜์กด์„ฑ ๊ด€๋ฆฌ ๋งค์ปค๋‹ˆ์ฆ˜์„ ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ๋Š” ์–ด๋ ต์ง€๋งŒ Dependency Injector์™€ ๊ฐ™์€ ๋ฒ”์šฉ์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์˜์กด์„ฑ ๋งค์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์ด์ „์ด ์‰ฝ๋‹ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋” ๋Š์Šจํ•˜๊ณ , ๋” ๋งŽ์€ ๊ฐ€๋Šฅ์„ฑ์„ ์—ผ๋‘ํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด ์ด ์„ ํƒ์€ ๋‚˜์˜์ง€ ์•Š๋‹ค๊ณ  ๋ด…๋‹ˆ๋‹ค.

 

๋งŒ์•ฝ FastAPI๋ฅผ ํ˜„์—…์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ณ , Dependency Injector์™€ ๊ฐ™์€ ์˜์กด์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ณ ๋ คํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ์•„๋ž˜์˜ ๋งํฌ๋ฅผ ํ†ตํ•ด ํ’๋ถ€ํ•œ ์˜ˆ์ œ๋ฅผ ๊ฒฝํ—˜ํ•ด๋ณด๊ณ  ์‚ฌ์šฉํ•ด๋ณด์‹œ๋Š” ๊ฑธ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.

 

https://python-dependency-injector.ets-labs.org/examples/fastapi.html

 

FastAPI example — Dependency Injector 4.36.0 documentation

FastAPI example This example shows how to use Dependency Injector with FastAPI. The example application is a REST API that searches for funny GIFs on the Giphy. The source code is available on the Github. Application structure Application has next structur

python-dependency-injector.ets-labs.org

 

 

๋ฐ˜์‘ํ˜•
TAGS.

Tistory Comments