API 개발

API๋Š” Lino ์„œ๋น„์Šค์˜ HTTP ๊ฒฝ๊ณ„์ž…๋‹ˆ๋‹ค. ์ „์†ก ๋ฌธ์ œ๋ฅผ ๋„๋ฉ”์ธ ๊ทœ์น™๊ณผ ํ˜ผํ•ฉํ•˜์ง€ ์•Š๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด ์žฅ์—์„œ๋Š” Lino๊ฐ€ Minimal APIs, request/response contracts, typed clients, OpenAPI ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ฐ Source Generators์— ์˜ํ•œ endpoint ์ž๋™ ๋“ฑ๋ก์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.


์ƒ์„ฑ๋œ endpoint๋Š” ์–‘ํ˜ธํ•œ ์ƒํƒœ๋กœ ์œ ์ง€๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. HTTP ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ , ๋ช…๋ น ๋˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์กฐํ•ฉํ•˜๊ณ , ์ด๋ฅผ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต์œผ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ISender ๊ฒฐ๊ณผ๋ฅผ typed responses์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ, ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™, ์ง€์†์„ฑ, ํŠธ๋žœ์žญ์…˜ ๋ฐ ๋„๋ฉ”์ธ ๊ถŒํ•œ ๋ถ€์—ฌ๋Š” ๋ช…๋ น, ์ฟผ๋ฆฌ, ์ฒ˜๋ฆฌ๊ธฐ, ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ธฐ, ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๋ฐ ์ž‘์—… ๋‹จ์œ„์—์„œ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค.

Lino์˜ Minimal APIs

Lino๋Š” ASP.NET ์ฝ”์–ด๋ฅผ ์ฑ„ํƒํ•ฉ๋‹ˆ๋‹ค. Minimal APIs Clean Architecture์˜ ๊ฒฝ๊ณ„๋ฅผ ๊นจ์ง€ ์•Š์œผ๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ์ง์ ‘์ ์ด๊ณ  ๋ช…์‹œ์ ์ด๋ฉฐ ์„ฑ๋Šฅ์„ ์œ ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— endpoint ์ƒ์„ฑ์„ ์œ„ํ•œ ํ‘œ์ค€์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ Lino ํ”„๋กœ์ ํŠธ์—์„œ ์ƒ์„ฑ๋œ endpoint๋Š” ๊ตฌํ˜„ํ•˜๋Š” Minimal APIs ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. IEndpoint. ๊ฐ endpoint๋Š” ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. MapEndpoint(IEndpointRouteBuilder app) ๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ ๋ฉ”์†Œ๋“œ ISender ์ƒ์„ฑ๋œ ๋ช…๋ น์ด๋‚˜ ์ฟผ๋ฆฌ๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต์œผ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

์ƒ์„ฑ๋œ ์ฃผ์š” ๋ถ€ํ’ˆ

  • *Endpoint.cs: ๋งคํ•‘ ๋ฐฉ๋ฒ• HTTP, ๊ฒฝ๋กœ, ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ, ๊ถŒํ•œ ๋ถ€์—ฌ, ํ…Œ๋„ŒํŠธ ์š”๊ตฌ ์‚ฌํ•ญ, ์†๋„ ์ œํ•œ ๋ฐ ๋ฒ„์ „.
  • *Request.cs: ๋ณธ๋ฌธ, ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด, ๊ฒฝ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋˜๋Š” ์–‘์‹ ๋ฐ์ดํ„ฐ์—์„œ ๋‚˜์˜ค๋Š” ์ž…๋ ฅ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  • *Extensions.cs: ์š”์ฒญ์„ ๋ช…๋ น/์ฟผ๋ฆฌ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฒฐ๊ณผ๋ฅผ ์‘๋‹ต HTTP๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • *Response.cs: ๋์ ๊ณผ ํ˜•์‹ํ™”๋œ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ˜ํ™˜๋œ ๊ฐ•๋ ฅํ•œ ํ˜•์‹์˜ contracts์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด์žฅ๋œ ๊ธฐ๋Šฅ

Lino๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. TypedResults ๊ทธ๋ฆฌ๊ณ  Results<...> ์„ฑ๊ณต ๋ฐ ์˜ค๋ฅ˜ ์‘๋‹ต์ด ์ฝ”๋“œ์— ๋ช…์‹œ์ ์œผ๋กœ ํ‘œ์‹œ๋˜๊ณ  OpenAPI์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ๊ณ„์ธต์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜๋Š” ๋‹ค์Œ์œผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. ProblemDetails ๋†“๋‹ค result.MapToProblemDetails().

  • WithTags: OpenAPI ๋ฐ Scalar์˜ ๋ชจ๋“ˆ, ์—”ํ„ฐํ‹ฐ ๋˜๋Š” ๊ธฐ๋Šฅ๋ณ„๋กœ endpoint๋ฅผ ๊ทธ๋ฃนํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • WithName: ํ•ด๋‹นํ•˜๋Š” ๊ฒฝ์šฐ ์ผ๊ด€๋œ OperationId๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • WithSummary: endpoint์˜ ๋ชฉ์ ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.
  • Produces(statusCode, schema): ์ƒํƒœ ์ฝ”๋“œ์™€ ์‘๋‹ต contracts์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • MapToApiVersion(1, 0): endpoint๋ฅผ API ๋ฒ„์ „๊ณผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
  • RequirePermission, RequireAuthorization, AllowAnonymous ๊ทธ๋ฆฌ๊ณ  RequireTenant: ํ”„๋กœ์ ํŠธ ์˜ต์…˜์— ๋”ฐ๋ผ ๋ณด์•ˆ์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๊ตฌ์„ฑ์— ๋”ฐ๋ผ ์ธ์ฆ๋œ ์ •์ฑ…์ด๋‚˜ ์ต๋ช… ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ฃน ๋˜๋Š” endpoint ์ˆ˜์ค€์—์„œ ์†๋„๋ฅผ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

์š”์ฒญ๊ณผ ์‘๋‹ต

๊ธฐ๋ณธ์ ์œผ๋กœ Lino๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ก ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์œ„ํ•ด. ์ด๋Š” ๊ฐ„๊ฒฐํ•˜๊ณ  ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์œผ๋ฉฐ API, ํ˜•์‹ํ™”๋œ ํด๋ผ์ด์–ธํŠธ ๋ฐ ์™ธ๋ถ€ ์†Œ๋น„์ž ๊ฐ„์˜ ๋ช…์‹œ์  contracts์œผ๋กœ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

  • endpoint๋ฅผ ํ†ตํ•ด ์ˆ˜์‹ ๋œ ์š”์ฒญ์€ ๋ช…๋ น ๋˜๋Š” ์ฟผ๋ฆฌ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
  • ๋ช…๋ น์ด๋‚˜ ์ฟผ๋ฆฌ์˜ ๊ฒฐ๊ณผ๋Š” ์‘๋‹ต์œผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
  • ๋„๋ฉ”์ธ ์—”ํ„ฐํ‹ฐ๋Š” contracts HTTP๋กœ ์ง์ ‘ ๋…ธ์ถœ๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.
public record CreatePersonRequest(string Name, int Age);
public record CreatePersonResponse(Guid Id, string Name, int Age);

์ƒˆ API ์ƒ์„ฑ

๋„๋ฉ”์ธ ๋ชจ๋ธ๊ณผ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์ด๋ฏธ HTTP์— ์˜ํ•ด ๋…ธ์ถœ๋  ๋งŒํผ ๋ช…ํ™•ํ•  ๋•Œ CLI๋กœ API๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. API๋Š” Minimal APIs, contracts, typed responses ๋ฐ ๋ฌธ์„œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํ†ตํ•ด ๋ช…๋ น๊ณผ ์ฟผ๋ฆฌ๋ฅผ ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๊ณ„์ธต์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

lino api new
lino api new --name <ApiName> --service <ServiceName> --module <ModuleName> --entity <EntityName>
lino api list --service <ServiceName> --module <ModuleName> --entity <EntityName>

๋Œ€ํ™”ํ˜• ๋งˆ๋ฒ•์‚ฌ๋Š” ๋‹ค์Œ ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

  • ์„œ๋น„์Šค: API๊ฐ€ ์ƒ์„ฑ๋  ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.
  • ๊ธฐ์ค€ ์น˜์ˆ˜: ํ•ด๋‹น๋˜๋Š” ๊ฒฝ์šฐ ์„œ๋น„์Šค ๋ชจ๋“ˆ์ž…๋‹ˆ๋‹ค.
  • ์—”ํ„ฐํ‹ฐ ๋˜๋Š” ์—ด๊ฑฐํ˜•: ๋์ ๊ณผ ์—ฐ๊ฒฐ๋œ ๋„๋ฉ”์ธ ์š”์†Œ์ž…๋‹ˆ๋‹ค.
  • API์˜ ์ด๋ฆ„: ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…์˜ ๋™์‚ฌ์™€ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. CreatePerson.
  • ์ž‘์—… ์œ ํ˜•: GET, POST, PUT, PATCH, DELETE, ์—…๋กœ๋“œ, ๋‹ค์šด๋กœ๋“œ ๋˜๋Š” endpoint ์˜ต์…˜.
  • ๋…ธ์„ :๊ฒฝ๋กœ ํŒจํ„ด, ์˜ˆ: /people/{id:guid}.
  • ์†์„ฑ: ์‹ค์ œ๋กœ HTTP ๊ฒฝ๊ณ„๋ฅผ ๋„˜์–ด์•ผ ํ•˜๋Š” ์š”์ฒญ ๋ฐ ์‘๋‹ต ํ•„๋“œ์ž…๋‹ˆ๋‹ค.

๋งˆ๋ฒ•์‚ฌ๊ฐ€ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌํ•ญ

  • ์–ป๋‹ค: ๋‹จ์ผ ๊ฒฐ๊ณผ, ๋ชฉ๋ก, ํŽ˜์ด์ง€ ๋ชฉ๋ก ๋ฐ ์˜ต์…˜/์„ ํƒ ์‹œ๋‚˜๋ฆฌ์˜ค.
  • ์šฐํŽธ: ๋ช…๋ น ์œ ํ˜• ๋ฐ ์„ ํƒํ•œ ์†์„ฑ์„ ํฌํ•จํ•œ ์ƒ์„ฑ ๋ฐ ๋น„์ฆˆ๋‹ˆ์Šค ์ž‘์—…์ž…๋‹ˆ๋‹ค.
  • ๋†“๋‹ค ๊ทธ๋ฆฌ๊ณ  ๋ฐ˜์ : ์ „์ฒด ๋˜๋Š” ๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ.
  • ์‚ญ์ œ: ์ œ๊ฑฐ๋Š” ์‚ญ์ œ ๋ช…๋ น์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค.
  • ์—…๋กœ๋“œ: ๋์  IFormFile ๊ทธ๋ฆฌ๊ณ  DisableAntiforgery() ํ•„์š”ํ•  ๋•Œ.
  • ๋‹ค์šด๋กœ๋“œ:endpoint ๋ฐ˜ํ™˜ FileStreamHttpResult; ์ธ์ฆ๋œ ํ”„๋กœ์ ํŠธ๋Š” ์•ˆ์ „ํ•œ ํŒŒ์ผ ์•ก์„ธ์Šค๋ฅผ ์œ„ํ•ด ํ† ํฐ endpoint๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์—ด๊ฑฐ: ์ƒ์„ฑ๋œ ์ฟผ๋ฆฌ ๋ฐ ์‘๋‹ต๋ณ„๋กœ ์œ ํšจํ•œ ์˜ต์…˜์„ ๋…ธ์ถœํ•˜๋Š” endpoint์ž…๋‹ˆ๋‹ค.

๊ถŒ์žฅ ํ๋ฆ„

  1. ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์—”ํ„ฐํ‹ฐ, ๋ช…๋ น ๋ฐ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๊ฒ€ํ† ํ•ฉ๋‹ˆ๋‹ค.
  2. ๋‹ฌ๋ฆฌ๋‹ค lino api new ์˜ฌ๋ฐ”๋ฅธ ์„œ๋น„์Šค, ๋ชจ๋“ˆ ๋ฐ ์—”ํ„ฐํ‹ฐ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  3. ์›ํ•˜๋Š” HTTP ๋™์‚ฌ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ณ„๋กœ ์ž‘์—… ์œ ํ˜•์„ ์„ ํƒํ•˜์„ธ์š”.
  4. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ œ์•ฝ ์กฐ๊ฑด์„ ์‚ฌ์šฉํ•˜์—ฌ ์•ˆ์ •์ ์ธ ๊ฒฝ๋กœ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. {id:int} ๋˜๋Š” {id:guid} ์ ์ ˆํ•œ ๊ฒฝ์šฐ.
  5. HTTP ๊ฒฝ๊ณ„๋ฅผ ๋„˜์–ด์•ผ ํ•˜๋Š” ์†์„ฑ๋งŒ ์„ ํƒํ•˜์„ธ์š”.
  6. ์Šน์ธ, ๊ถŒํ•œ, ํ…Œ๋„ŒํŠธ ์š”๊ตฌ ์‚ฌํ•ญ, ์†๋„ ์ œํ•œ ๋ฐ ์˜ˆ์ƒ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  7. ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  Scalar/OpenAPI๋ฅผ ๊ฒ€์‚ฌํ•˜์—ฌ ์ƒ์„ฑ๋œ ๊ฒฝ๋กœ, ์š”์•ฝ, ๋ฒ„์ „, ๋ณด์•ˆ ๋ฐ ์‘๋‹ต์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ: CreatePerson

API๋ฅผ ์ƒ์„ฑํ•  ๋•Œ POST ๋ถ€๋ฅด๋‹ค CreatePerson, ์—”ํ„ฐํ‹ฐ์™€ ์—ฐ๊ฒฐ๋จ Person, CLI๋Š” endpoint, request/response contracts, ๋งคํ•‘ ํ™•์žฅ, OpenAPI ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ฐ ํ•ด๋‹น ๋ช…๋ น๊ณผ์˜ ํ†ตํ•ฉ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

<ProjectName>/
โ””โ”€โ”€ src/
    โ””โ”€โ”€ Services/
        โ””โ”€โ”€ <ServiceName>/
            โ””โ”€โ”€ Api/
                โ””โ”€โ”€ Endpoints/
                    โ””โ”€โ”€ People/
                        โ””โ”€โ”€ CreatePerson/
                            โ”œโ”€โ”€ CreatePersonEndpoint.cs
                            โ”œโ”€โ”€ CreatePersonExtensions.cs
                            โ”œโ”€โ”€ CreatePersonRequest.cs
                            โ””โ”€โ”€ CreatePersonResponse.cs

contracts์„œ ๋ฐ typed clients

ํ”„๋กœ์ ํŠธ์— ์›น ์•ฑ Blazor๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ Lino๋Š” API์˜ ํ˜•์‹ํ™”๋œ ์†Œ๋น„๋ฅผ ์œ„ํ•œ ์•„ํ‹ฐํŒฉํŠธ(๊ณต์œ  contracts, ํด๋ผ์ด์–ธํŠธ ์ธํ„ฐํŽ˜์ด์Šค ๋ฐ HTTP ๊ตฌํ˜„)๋„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Blazor๋Š” ๊ฐ„๋‹จํ•˜๊ณ  ์ผ๊ด€๋˜๋ฉฐ ๊ฐ•๋ ฅํ•œ ํ˜•์‹์˜ ๋ฐฉ์‹์œผ๋กœ endpoint๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<ProjectName>/
โ””โ”€โ”€ src/
    โ””โ”€โ”€ Services/
        โ””โ”€โ”€ <ServiceName>/
            โ”œโ”€โ”€ Api.Contracts/
            โ”‚   โ””โ”€โ”€ Features/
            โ”‚       โ””โ”€โ”€ People/
            โ”‚           โ”œโ”€โ”€ CreatePerson/
            โ”‚           โ”‚   โ”œโ”€โ”€ CreatePersonRequest.cs
            โ”‚           โ”‚   โ””โ”€โ”€ CreatePersonResponse.cs
            โ”‚           โ””โ”€โ”€ IPersonApiClient.cs
            โ””โ”€โ”€ Api.Client/
                โ””โ”€โ”€ Features/
                    โ””โ”€โ”€ PersonApiClient.cs

ํด๋ผ์ด์–ธํŠธ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ข…์†์„ฑ ์ฃผ์ž…์„ ์œ„ํ•ด ๋“ฑ๋ก๋˜์—ˆ์œผ๋ฉฐ ๊ตฌํ˜„์—์„œ๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. HttpClientProvider Tolitech์˜ HTTP ๋„์šฐ๋ฏธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ•๋ ฅํ•œ ํ˜•์‹์˜ ๋ฐฉ์‹์œผ๋กœ ์ƒ์„ฑ๋œ API๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

์ถœํŒ ์ „ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

  • ์‚ฌ์šฉ GET ๋…์„œ๋ฅผ ์œ„ํ•ด, POST ์ƒ์„ฑ/์ž‘์—…์„ ์œ„ํ•ด, PUT/PATCH ๋ณ€ํ™”๋ฅผ ์œ„ํ•ด ๊ทธ๋ฆฌ๊ณ  DELETE ์˜๋ฏธ๊ฐ€ ์žˆ์„ ๋•Œ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
  • ๋„๋ฉ”์ธ ์—”ํ„ฐํ‹ฐ๋ฅผ ์™ธ๋ถ€ contracts์œผ๋กœ ์ง์ ‘ ๋…ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”.
  • ๋ฌธ์„œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ, ์ถฉ๋Œ, ์ฐพ์„ ์ˆ˜ ์—†์Œ ๋ฐ ์•ก์„ธ์Šค ๊ฑฐ๋ถ€ ์˜ค๋ฅ˜.
  • ์‚ฌ์šฉ api list ๋™์ผํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•ด ์ค‘๋ณต ๊ฒฝ๋กœ๋‚˜ ๊ฒฝ์Ÿ endpoint๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

Source Generators๋กœ endpoint ๋“ฑ๋ก

Lino๋Š” Source Generators๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ์„ ์ˆ˜๋™์œผ๋กœ ๋งคํ•‘ํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋์ ์„ ํ•˜๋‚˜์”ฉ ๋‚˜์—ดํ•˜๋Š” ๋Œ€์‹  Program.cs, ์ปดํŒŒ์ผ ์ค‘์— ๋กœ๊ทธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์ƒ์„ฑ๋œ endpoint ํด๋ž˜์Šค ๊ตฌํ˜„ IEndpoint ~์˜ Tolitech.MinimalApis.Generators.Abstractions. endpoint ๊ทธ๋ฃน ํ˜ธ์ถœ MapEndpointsGenerated(), ์ œ์ž‘์‚ฌ: Tolitech.MinimalApis.Generators, ์ƒ์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์ƒˆ endpoint๊ฐ€ ๋“ฑ๋ก๋ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ์™œ ์ค‘์š”ํ•œ๊ฐ€์š”?

  • ์ˆ˜๋™ ๋ฐฐ์„  ๊ฐ์†Œ: ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ endpoint๋ฅผ ์ˆ˜๋™์œผ๋กœ ๋งคํ•‘ํ•˜๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • ์ปดํŒŒ์ผ ์‹œ๊ฐ„ ์ผ๊ด€์„ฑ: endpoint๋Š” ๋™์ผํ•œ ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฅด๋ฉฐ ์ƒ์„ฑ๋œ ์ฝ”๋“œ์— ์˜ํ•ด ๊ฒ€์ƒ‰๋ฉ๋‹ˆ๋‹ค.
  • ํด๋ฆฌ๋„ˆ ์‹œ์ž‘: Program.cs ์„œ๋น„์Šค, โ€‹โ€‹๋ฏธ๋“ค์›จ์–ด ๋ฐ ํ™•์žฅ ๋ฐฉ๋ฒ• ๊ตฌ์„ฑ์„ ์œ„ํ•œ ์„ค์ •์„ ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค.
  • AOT ํ˜ธํ™˜์„ฑ: ๋Ÿฐํƒ€์ž„ ์‹œ ๋ฆฌํ”Œ๋ ‰์…˜์— ๋Œ€ํ•œ ์ข…์†์„ฑ์„ ์ค„์ž…๋‹ˆ๋‹ค.
  • OpenAPI ์ผ๊ด€์„ฑ: ํƒœ๊ทธ, ์š”์•ฝ, ์ƒํƒœ ์ฝ”๋“œ ๋ฐ ๋ฒ„์ „์ด endpoint์—์„œ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  • ์•„ํ‚คํ…์ฒ˜ ์ •๋ ฌ: HTTP๋Š” API์— ์žˆ๊ณ , ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์€ MediatR์„ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง€๋ฉฐ, contracts์€ ํด๋ผ์ด์–ธํŠธ์™€ ๊ณต์œ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Ÿฐํƒ€์ž„ ์‹œ ํ๋ฆ„

  1. Program.cs ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•˜๊ณ  ์„œ๋น„์Šค ๋˜๋Š” ๋ชจ๋“ˆ endpoint์—์„œ ํ™•์žฅ์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  2. ํ™•์žฅ์€ API ๋ฒ„์ „ ์„ธํŠธ์™€ endpoint ๊ทธ๋ฃน์„ ์ƒ์„ฑํ•˜๊ณ  ๊ถŒํ•œ ๋ถ€์—ฌ/์†๋„ ์ œํ•œ์„ ์ ์šฉํ•˜๊ณ  ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. MapEndpointsGenerated().
  3. ์ƒ์„ฑ๋œ ๋งคํผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. MapEndpoint ๊ฐ endpoint์˜
  4. ๊ฐ ๋์ ์€ ๊ฒฝ๋กœ, OpenAPI ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ, ๊ถŒํ•œ, ํ…Œ๋„ŒํŠธ ์š”๊ตฌ ์‚ฌํ•ญ ๋ฐ ์ฒ˜๋ฆฌ๊ธฐ๋ฅผ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค.
  5. ํ•ธ๋“ค๋Ÿฌ๋Š” ์ž…๋ ฅ HTTP๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ์ด๋ฅผ ๋ช…๋ น/์ฟผ๋ฆฌ๋กœ ๋ณ€ํ™˜ํ•œ ํ›„ MediatR๋กœ ๋ณด๋‚ด๊ณ  ํ˜•์‹ํ™”๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ค๋ฅ˜ ์ •์˜

์˜ค๋ฅ˜ ์ •์˜๋Š” ์•Œ๋ ค์ง„ ๋„๋ฉ”์ธ ๋ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์˜ค๋ฅ˜๋ฅผ ํ‘œ์ค€ํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” API, ์ฒ˜๋ฆฌ๊ธฐ, ๋กœ๊ทธ ๋ฐ ํ”„๋ŸฐํŠธ์—”๋“œ๊ฐ€ ๊ฐ ๋์ ์—์„œ ๊ธธ ์žƒ์€ ๋ฉ”์‹œ์ง€, ์ค‘๋ณต ๋ฌธ์ž์—ด ๋˜๋Š” ์ž„์‹œ ๊ฒฐ์ •์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

lino error-definition new --name <ErrorDefinitionName> --service <ServiceName> --module <ModuleName> --entity <EntityName>
lino error-definition list --service <ServiceName> --module <ModuleName> --entity <EntityName>

์ƒ์„ฑ๋œ API์—์„œ ๋ช…๋ น ๋ฐ ์ฟผ๋ฆฌ์— ์˜ํ•ด ๋ฐ˜ํ™˜๋œ ์˜ˆ์ƒ ์˜ค๋ฅ˜๋Š” ๋‹ค์Œ์œผ๋กœ ๋ณ€ํ™˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ProblemDetails ์ƒํƒœ ์ฝ”๋“œ, ์˜ค๋ฅ˜ ์ฝ”๋“œ ๋ฐ ๋ณด์•ˆ ๋ฉ”์‹œ์ง€๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ์ž์„ธํ•œ ๊ธฐ์ˆ  ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ์ง€๋งŒ HTTP ์‘๋‹ต์€ ์ผ๊ด€๋˜๊ณ  ์•ˆ์ „ํ•˜๋ฉฐ ํ˜„์ง€ํ™” ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ƒํƒœ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ๋ฒ•์˜ˆ
400 ์ž˜๋ชป๋œ ์š”์ฒญ์ž˜๋ชป๋œ ์ž…๋ ฅ ๋˜๋Š” ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค.ํ•„์ˆ˜ ํ•„๋“œ ๋ˆ„๋ฝ, ์ž˜๋ชป๋œ ํ˜•์‹, ์†์ƒ๋œ ์š”์ฒญ ๊ทœ์น™.
401 ๋ฌด๋‹จ์ธ์ฆ๋˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž์ž…๋‹ˆ๋‹ค.ํ† ํฐ์ด ๋ˆ„๋ฝ๋˜์—ˆ๊ฑฐ๋‚˜ ๋งŒ๋ฃŒ๋˜์—ˆ๊ฑฐ๋‚˜ ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
403 ๊ธˆ์ง€๋จํ—ˆ๊ฐ€ ์—†์ด ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์ž…๋‹ˆ๋‹ค.๋‹ค์Œ์˜ ํ—ˆ๊ฐ€๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค: RequirePermission ๋ถ€์—ฌ๋˜์ง€ ์•Š์Œ.
404 ์ฐพ์„ ์ˆ˜ ์—†์Œ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ฆฌ์†Œ์Šค์ด๊ฑฐ๋‚˜ ํ—ˆ์šฉ๋œ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค.ProductNotFound, ๋‹ค๋ฅธ ํ…Œ๋„ŒํŠธ์˜ ์—”ํ„ฐํ‹ฐ ๋˜๋Š” ์•Œ ์ˆ˜ ์—†๋Š” ์‹๋ณ„์ž์ž…๋‹ˆ๋‹ค.
409 ๊ฐˆ๋“ฑ์ƒํƒœ ์ถฉ๋Œ ๋˜๋Š” ๊ณ ์œ ์„ฑ ๊ทœ์น™.์ค‘๋ณต๋œ ๊ธฐ๋ก, ์ž˜๋ชป๋œ ์ „ํ™˜, ๋ฒ„์ „ ์ถฉ๋Œ.

๋ชจ๋ฒ” ์‚ฌ๋ก€

  • ์˜ˆ์ƒ๋˜๊ณ  ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ์˜ค๋ฅ˜ ์ •์˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ๊ธฐ์ˆ ์  ์˜ˆ์™ธ๋‚˜ ์ธํ”„๋ผ ์„ธ๋ถ€์ •๋ณด๋ฅผ ํด๋ผ์ด์–ธํŠธ์— ๋ฐ˜ํ™˜ํ•˜์ง€ ๋งˆ์„ธ์š”.
  • ํ”„๋ŸฐํŠธ์—”๋“œ, ์ž…๋ ฅ๋œ ํด๋ผ์ด์–ธํŠธ ๋ฐ ํ…Œ์ŠคํŠธ๊ฐ€ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐ˜์‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ์•ˆ์ •์ ์ธ ์˜ค๋ฅ˜ ์ฝ”๋“œ๋ฅผ ์œ ์ง€ํ•˜์„ธ์š”.
  • endpoint๊ฐ€ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ ์ฝ”๋“œ๋ฅผ OpenAPI์— ๋ฌธ์„œํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ณต๊ฐœ ์‘๋‹ต์—์„œ ์ง„๋‹จ ์„ธ๋ถ€์ •๋ณด ๋ฐ ๋ณด์•ˆ ๋ฉ”์‹œ์ง€๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด ์„œ๋ฒ„ ์ธก ๋กœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
처리되지 않은 오류가 발생했습니다. 새로 고침 ๐Ÿ—™