ALPACO ํ”„๋กœ์ ํŠธ: ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜(MSA) Lambda ๊ฐœ๋ฐœ ๊ฐ€์ด๋“œ

1. ์„œ๋ก 

๋ณธ ๋ฌธ์„œ๋Š” ALPACO ํ”„๋กœ์ ํŠธ์˜ ๋ฐฑ์—”๋“œ ์‹œ์Šคํ…œ์„ ๊ตฌ์„ฑํ•˜๋Š” AWS Lambda ํ•จ์ˆ˜๋“ค์„ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜(MSA) ๊ด€์ ์—์„œ ๊ฐœ๋ฐœ, ๋ฐฐํฌ ๋ฐ ํ†ตํ•ฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ํฌ๊ด„์ ์ธ ๊ธฐ์ˆ  ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค. ALPACO๋Š” ์—ฌ๋Ÿฌ ๋…๋ฆฝ์ ์ธ Lambda ํ•จ์ˆ˜๋“ค์„ ์กฐํ•ฉํ•˜์—ฌ ํŠน์ • ๋น„์ฆˆ๋‹ˆ์Šค ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” MSA ์›์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

์ด ๊ฐ€์ด๋“œ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฐ Lambda ์„œ๋น„์Šค์˜ ์—ญํ• , ๋‹ค๋ฅธ ์„œ๋น„์Šค์™€์˜ ์ƒํ˜ธ์ž‘์šฉ, ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ, ๋ฐฐํฌ ์ „๋žต, ๊ทธ๋ฆฌ๊ณ  MSA ํ™˜๊ฒฝ์—์„œ์˜ ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ณต๋œ chatbot-query, code-executor, code-grader, community-lambda-functions, problem-generator-v3, problems-api, submissions-api ๋“ฑ์˜ Lambda ํ•จ์ˆ˜๋“ค๊ณผ ๊ด€๋ จ ์ธํ”„๋ผ ๋ฌธ์„œ๋ฅผ ์ฃผ์š” ์ฐธ๊ณ  ์ž๋ฃŒ๋กœ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

2. MSA ๋ฐ Lambda ๊ธฐ๋ณธ ์›์น™

ALPACO ํ”„๋กœ์ ํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ MSA ์›์น™์„ Lambda ํ•จ์ˆ˜ ์„ค๊ณ„์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค:

  • ๋‹จ์ผ ์ฑ…์ž„ ์›์น™ (Single Responsibility Principle): ๊ฐ Lambda ํ•จ์ˆ˜๋Š” ํŠน์ • ๋น„์ฆˆ๋‹ˆ์Šค ๊ธฐ๋Šฅ ๋˜๋Š” ๋„๋ฉ”์ธ์— ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: code-executor๋Š” ์ฝ”๋“œ ์‹คํ–‰๋งŒ ๋‹ด๋‹น, chatbot-query๋Š” ์ฑ—๋ด‡ ๋กœ์ง๋งŒ ๋‹ด๋‹น).
  • ๋…๋ฆฝ์ ์ธ ๋ฐฐํฌ: ๊ฐ Lambda ์„œ๋น„์Šค๋Š” ๋‹ค๋ฅธ ์„œ๋น„์Šค์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ์„ ์ตœ์†Œํ™”ํ•˜๋ฉด์„œ ๋…๋ฆฝ์ ์œผ๋กœ ๋ฐฐํฌ ๋ฐ ์—…๋ฐ์ดํŠธ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (Terraform ๋ชจ๋“ˆ๋กœ ๊ด€๋ฆฌ).
  • ๋ถ„์‚ฐ๋œ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ: ๊ฐ ์„œ๋น„์Šค๋Š” ์ž์ฒด ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ(์ฃผ๋กœ DynamoDB ํ…Œ์ด๋ธ”)๋ฅผ ์†Œ์œ ํ•˜๊ฑฐ๋‚˜, ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ ์„œ๋น„์Šค์˜ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: Community ํ…Œ์ด๋ธ”, Problems ํ…Œ์ด๋ธ”, Submissions ํ…Œ์ด๋ธ”).
  • ๊ธฐ์ˆ  ๋‹ค์–‘์„ฑ (Polyglot Persistence & Programming): MSA๋Š” ์„œ๋น„์Šค๋ณ„๋กœ ์ตœ์ ์˜ ๊ธฐ์ˆ  ์Šคํƒ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ALPACO๋Š” ์ฃผ๋กœ Node.js๋ฅผ Lambda ๋Ÿฐํƒ€์ž„์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€๋งŒ, code-executor๋Š” Python์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ํƒ„๋ ฅ์„ฑ ๋ฐ ํ™•์žฅ์„ฑ: AWS Lambda์˜ ์„œ๋ฒ„๋ฆฌ์Šค ํŠน์„ฑ์€ ํŠธ๋ž˜ํ”ฝ์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ ํ™•์žฅ/์ถ•์†Œ๋˜์–ด ๋†’์€ ๊ฐ€์šฉ์„ฑ๊ณผ ๋น„์šฉ ํšจ์œจ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • API ๊ธฐ๋ฐ˜ ํ†ต์‹ : ์„œ๋น„์Šค ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ์€ ์ž˜ ์ •์˜๋œ API(์ฃผ๋กœ API Gateway ๋˜๋Š” Lambda ์ง์ ‘ ํ˜ธ์ถœ)๋ฅผ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.

3. ALPACO Lambda ํ•จ์ˆ˜ ๊ฐœ๋ฐœ ํŒจํ„ด

3.1. ๊ณตํ†ต ๊ตฌ์กฐ

๋Œ€๋ถ€๋ถ„์˜ ALPACO Node.js Lambda ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค:

// ์˜ˆ์‹œ: backend/lambdas/chatbot-query/index.mjs
import { /* ํ•„์š”ํ•œ AWS SDK ํด๋ผ์ด์–ธํŠธ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ */ } from "...";

// ์ „์—ญ ๋ฒ”์œ„์—์„œ ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™” (์—ฐ๊ฒฐ ์žฌ์‚ฌ์šฉ)
// const dynamoDB = DynamoDBDocumentClient.from(new DynamoDBClient({}));

export const handler = async (event, context) => {
  // 1. CORS ๋ฐ ์‚ฌ์ „ ์š”์ฒญ(Preflight) ์ฒ˜๋ฆฌ (API Gateway Lambda Proxy ํ†ตํ•ฉ ์‹œ)
  if (event.httpMethod === "OPTIONS") {
    return {
      statusCode: 200,
      headers: { /* CORS ํ—ค๋” */ },
      body: JSON.stringify({ message: "CORS preflight check successful" }),
    };
  }

  try {
    // 2. ์ž…๋ ฅ ํŒŒ์‹ฑ ๋ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
    //  - event.body (API Gateway), event (์ง์ ‘ ํ˜ธ์ถœ)
    //  - event.pathParameters, event.queryStringParameters
    //  - event.requestContext.authorizer.claims (Cognito ์ธ์ฆ ์ •๋ณด)
    const requestBody = typeof event.body === "string" ? JSON.parse(event.body) : event.body;
    // ... ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๋กœ์ง ...

    // 3. ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ (ํ•„์š”์‹œ)
    //  - JWT ํ† ํฐ ๊ฒ€์ฆ (์˜ˆ: chatbot-query, code-grader)
    //  - IAM ์—ญํ•  ๊ธฐ๋ฐ˜ ๊ถŒํ•œ (Lambda ์‹คํ–‰ ์—ญํ• )

    // 4. ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰
    //  - ์™ธ๋ถ€ ์„œ๋น„์Šค ํ˜ธ์ถœ (์˜ˆ: Google Gemini API, ๋‹ค๋ฅธ Lambda ํ•จ์ˆ˜)
    //  - ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—… (DynamoDB CRUD)
    //  - ๊ณ„์‚ฐ ๋ฐ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜

    // 5. ์‘๋‹ต ์ƒ์„ฑ
    const responseBody = { /* ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ */ };
    return {
      statusCode: 200, // ๋˜๋Š” 201, 204 ๋“ฑ
      headers: {
        "Content-Type": "application/json",
        /* CORS ํ—ค๋” */
      },
      body: JSON.stringify(responseBody),
    };

  } catch (error) {
    console.error("Error processing request:", error);
    // 6. ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๋ฐ ์‘๋‹ต
    return {
      statusCode: error.statusCode || 500,
      headers: {
        "Content-Type": "application/json",
        /* CORS ํ—ค๋” */
      },
      body: JSON.stringify({
        message: error.message || "Internal server error",
        details: error.details, // ์ถ”๊ฐ€ ์˜ค๋ฅ˜ ์ •๋ณด (์„ ํƒ ์‚ฌํ•ญ)
      }),
    };
  }
};

// ์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต์˜ ๊ฒฝ์šฐ (์˜ˆ: chatbot-query, problem-generator-v3)
// export const handler = awslambda.streamifyResponse(async (event, responseStream, context) => {
//   // ... ์œ ์‚ฌํ•œ ๊ตฌ์กฐ, responseStream.write() ๋ฐ responseStream.end() ์‚ฌ์šฉ
// });

3.2. ์ž…๋ ฅ ์ฒ˜๋ฆฌ ๋ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

  • API Gateway ํ”„๋ก์‹œ ํ†ตํ•ฉ: event.httpMethod, event.pathParameters, event.queryStringParameters, event.body(JSON ๋ฌธ์ž์—ด)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. event.body๋Š” JSON.parse()๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ์ง์ ‘ Lambda ํ˜ธ์ถœ: event ๊ฐ์ฒด๊ฐ€ ์ง์ ‘ ์ž…๋ ฅ ํŽ˜์ด๋กœ๋“œ์ž…๋‹ˆ๋‹ค. (์˜ˆ: code-grader๊ฐ€ code-executor ํ˜ธ์ถœ ์‹œ).
  • ์ธ์ฆ ์ •๋ณด: Cognito์™€ ํ†ตํ•ฉ๋œ API Gateway๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, event.requestContext.authorizer.claims์—์„œ ์‚ฌ์šฉ์ž ํด๋ ˆ์ž„(์˜ˆ: sub (์‚ฌ์šฉ์ž ID), cognito:username)์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  • ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ: ํ•„์ˆ˜ ํ•„๋“œ ๋ˆ„๋ฝ, ๋ฐ์ดํ„ฐ ํƒ€์ž… ๋ถˆ์ผ์น˜ ๋“ฑ์„ ์ดˆ๊ธฐ์— ํ™•์ธํ•˜์—ฌ ์˜ค๋ฅ˜๋ฅผ ์กฐ๊ธฐ์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. (Zod์™€ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅ, ํ˜„์žฌ๋Š” ์ˆ˜๋™ ๊ฒ€์‚ฌ ์œ„์ฃผ).

3.3. ์„ค์ • ๋ฐ ํ™˜๊ฒฝ ๋ณ€์ˆ˜

  • Lambda ํ•จ์ˆ˜ ์„ค์ •(์˜ˆ: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ” ์ด๋ฆ„, ์™ธ๋ถ€ API ํ‚ค, ๋‹ค๋ฅธ ์„œ๋น„์Šค ARN)์€ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค.
  • Terraform (*.tf ํŒŒ์ผ์˜ environment ๋ธ”๋ก)์„ ์‚ฌ์šฉํ•˜์—ฌ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: PROBLEMS_TABLE_NAME, GOOGLE_AI_API_KEY, CODE_EXECUTOR_LAMBDA_ARN).
  • backend/lambdas/*/src/utils/constants.mjs์™€ ๊ฐ™์€ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํŒŒ์ผ์—์„œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ฝ์–ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด์—์„œ ์ผ๊ด€๋˜๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

3.4. ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ

  • Cognito JWT ์ธ์ฆ (API Gateway):
    • API Gateway ์—”๋“œํฌ์ธํŠธ๋Š” Cognito ์‚ฌ์šฉ์ž ํ’€ ๊ถŒํ•œ ๋ถ€์—ฌ์ž๋กœ ๋ณดํ˜ธ๋ฉ๋‹ˆ๋‹ค.
    • ํด๋ผ์ด์–ธํŠธ๋Š” Authorization: Bearer <ID_TOKEN> ํ—ค๋”๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
    • chatbot-query, code-grader, ์ปค๋ฎค๋‹ˆํ‹ฐ API ๋“ฑ์€ ๋‚ด๋ถ€์ ์œผ๋กœ JWT๋ฅผ ๊ฒ€์ฆํ•˜๊ฑฐ๋‚˜(์˜ˆ: chatbot-query์˜ validateJwt ํ•จ์ˆ˜) API Gateway ๊ถŒํ•œ ๋ถ€์—ฌ์ž์— ์˜์กดํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ event.requestContext.authorizer.claims๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.
  • IAM ์—ญํ•  ๋ฐ ์ •์ฑ…:
    • ๊ฐ Lambda ํ•จ์ˆ˜๋Š” ์ตœ์†Œ ๊ถŒํ•œ ์›์น™์„ ๋”ฐ๋ฅด๋Š” IAM ์‹คํ–‰ ์—ญํ• ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
    • ์ด ์—ญํ• ์€ ํ•„์š”ํ•œ AWS ์„œ๋น„์Šค(DynamoDB, ๋‹ค๋ฅธ Lambda ํ˜ธ์ถœ, CloudWatch Logs ๋“ฑ)์— ๋Œ€ํ•œ ์ ‘๊ทผ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: infrastructure/api/iam.tf).
  • Lambda ํ•จ์ˆ˜ URL ์ธ์ฆ:
    • chatbot-query ๋ฐ problem-generator-v3๋Š” AWS_IAM ์ธ์ฆ์„ ์‚ฌ์šฉํ•˜๋Š” Lambda ํ•จ์ˆ˜ URL์„ ํ†ตํ•ด ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
    • CloudFront๋Š” OAC(Origin Access Control)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ํ•จ์ˆ˜ URL์„ ์•ˆ์ „ํ•˜๊ฒŒ ํ˜ธ์ถœํ•˜๋ฉฐ, SigV4 ์„œ๋ช…์„ ํ†ตํ•ด ์ธ์ฆํ•ฉ๋‹ˆ๋‹ค.

3.5. ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ

  • try...catch ๋ธ”๋ก์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜ˆ์ƒ๋˜๋Š” ์˜ค๋ฅ˜์™€ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ์˜ค๋ฅ˜๋ฅผ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ์ผ๊ด€๋œ ์˜ค๋ฅ˜ ์‘๋‹ต ํ˜•์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค (์˜ˆ: statusCode, { message, details } ๋ณธ๋ฌธ).
  • console.error๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ CloudWatch Logs์— ์ƒ์„ธํ•œ ์˜ค๋ฅ˜ ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
  • ์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต์˜ ๊ฒฝ์šฐ, ์˜ค๋ฅ˜๋„ SSE ์ŠคํŠธ๋ฆผ์„ ํ†ตํ•ด ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์˜ˆ: chatbot-query์˜ responseStream.write(JSON.stringify({ error: ..., details: ... }))).

3.6. ๋กœ๊น… ๋ฐ ๋ชจ๋‹ˆํ„ฐ๋ง

  • console.log, console.info, console.warn, console.error๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ CloudWatch Logs์— ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
  • GENERATOR_VERBOSE (problem-generator-v3)์™€ ๊ฐ™์€ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ๊ทธ ์ƒ์„ธ ์ˆ˜์ค€์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • CloudWatch Logs๋Š” ๋””๋ฒ„๊น…, ์„ฑ๋Šฅ ๋ถ„์„, ์˜ค๋ฅ˜ ์ถ”์ ์— ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค.

3.7. ์˜์กด์„ฑ ๊ด€๋ฆฌ ๋ฐ Lambda Layers

  • Node.js ํ”„๋กœ์ ํŠธ: ๊ฐ Lambda ํ•จ์ˆ˜ ๋˜๋Š” ๊ด€๋ จ ์„œ๋น„์Šค ๊ทธ๋ฃน์€ ์ž์ฒด package.json์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์˜ˆ: backend/lambdas/chatbot-query/package.json).
  • Lambda Layers: ์—ฌ๋Ÿฌ Lambda ํ•จ์ˆ˜์—์„œ ๊ณต์œ ๋˜๋Š” ๊ณตํ†ต ์˜์กด์„ฑ(์˜ˆ: AWS SDK, LangChain ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, uuid, jose)์„ Lambda Layer๋กœ ํŒจํ‚ค์ง•ํ•ฉ๋‹ˆ๋‹ค.
    • infrastructure/api/layers/common-deps/: ์ปค๋ฎค๋‹ˆํ‹ฐ API์šฉ ๊ฐ„๋‹จํ•œ uuid ๋ ˆ์ด์–ด.
    • infrastructure/chatbot/layers/chatbot_deps/: ์ฑ—๋ด‡์šฉ @langchain/google-genai, jose ๋“ฑ.
    • infrastructure/problem-generator-v3/layers/: Docker ๊ธฐ๋ฐ˜ ๋นŒ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋” ๋ณต์žกํ•œ ๋ ˆ์ด์–ด.
    • Terraform (layer.tf ๋˜๋Š” lambda.tf ๋‚ด)์—์„œ aws_lambda_layer_version ๋ฆฌ์†Œ์Šค๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค.
    • ๋ ˆ์ด์–ด ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋Š” ๋กœ์ปฌ npm install ๋˜๋Š” Docker ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ(build-layer.sh)๋ฅผ ํ†ตํ•ด ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

4. ์„œ๋น„์Šค ๊ฐ„ ํ†ต์‹ 

ALPACO ํ”„๋กœ์ ํŠธ์˜ Lambda ๊ธฐ๋ฐ˜ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ƒํ˜ธ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค:

4.1. API Gateway๋ฅผ ํ†ตํ•œ ๋™๊ธฐ์‹ ํ˜ธ์ถœ

  • ํŒจํ„ด: ํด๋ผ์ด์–ธํŠธ (๋˜๋Š” ๋‹ค๋ฅธ ์„œ๋น„์Šค) -> API Gateway -> Lambda ํ•จ์ˆ˜
  • ์˜ˆ์‹œ:
    • ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ submissions-api๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ œ์ถœ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
    • ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ code-grader API๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ฝ”๋“œ ์ฑ„์ ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
    • problem-generator-v3 ์„œ๋น„์Šค (๋ฐฑ์—”๋“œ)๊ฐ€ code-execution-service API Gateway๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ƒ์„ฑ๋œ ์ฝ”๋“œ ์กฐ๊ฐ์„ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (ํ˜„์žฌ ๊ตฌํ˜„์€ Lambda ์ง์ ‘ ํ˜ธ์ถœ).
  • ํŠน์ง•: ์š”์ฒญ-์‘๋‹ต ๋ชจ๋ธ, HTTP ๊ธฐ๋ฐ˜, API Gateway๊ฐ€ ์ธ์ฆ, ์†๋„ ์ œํ•œ, ๋กœ๊น…, CORS ๋“ฑ์„ ์ฒ˜๋ฆฌ.

4.2. Lambda ์ง์ ‘ ๋™๊ธฐ์‹ ํ˜ธ์ถœ

  • ํŒจํ„ด: Lambda A -> AWS SDK -> Lambda B (๋™๊ธฐ์‹ ํ˜ธ์ถœ, Lambda A๋Š” Lambda B์˜ ์‘๋‹ต์„ ๊ธฐ๋‹ค๋ฆผ)
  • ์˜ˆ์‹œ:
    • code-grader Lambda๊ฐ€ ๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์— ๋Œ€ํ•ด code-executor Lambda๋ฅผ ๋™๊ธฐ์ ์œผ๋กœ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. code-grader๋Š” code-executor์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    • problem-generator-v3 Lambda๊ฐ€ ์ƒ์„ฑ๋œ ์†”๋ฃจ์…˜ ์ฝ”๋“œ ๊ฒ€์ฆ์„ ์œ„ํ•ด code-executor Lambda๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง•: ์„œ๋น„์Šค ๊ฐ„ ๋‚ฎ์€ ์ง€์—ฐ ์‹œ๊ฐ„. ํ˜ธ์ถœํ•˜๋Š” Lambda๋Š” ํ˜ธ์ถœ๋˜๋Š” Lambda์˜ ์‘๋‹ต ํ˜•์‹๊ณผ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•ด ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. IAM ๊ถŒํ•œ์œผ๋กœ ํ˜ธ์ถœ์„ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.

4.3. CloudFront + Lambda ํ•จ์ˆ˜ URL (SSE ์ŠคํŠธ๋ฆฌ๋ฐ)

  • ํŒจํ„ด: ํด๋ผ์ด์–ธํŠธ -> CloudFront -> Lambda ํ•จ์ˆ˜ URL -> Lambda (์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต)
  • ์˜ˆ์‹œ:
    • chatbot-query: ์ฑ—๋ด‡ ์‘๋‹ต์„ SSE๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•ฉ๋‹ˆ๋‹ค.
    • problem-generator-v3: ๋ฌธ์ œ ์ƒ์„ฑ ์ง„ํ–‰ ์ƒํ™ฉ๊ณผ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ SSE๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง•: ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ, ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์— ์ ํ•ฉ. CloudFront OAC๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Lambda ํ•จ์ˆ˜ URL์„ ๋ณดํ˜ธํ•ฉ๋‹ˆ๋‹ค.

5. ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ

  • DynamoDB: ์ฃผ์š” ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
    • alpaco-Community-production: ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œ๋ฌผ, ๋Œ“๊ธ€, ์ข‹์•„์š”. (infrastructure/api/dynamodb.tf)
    • alpaco-Problems-production ๋˜๋Š” alpaco-Problems-v3-production: ์ƒ์„ฑ๋œ ๋ฌธ์ œ, ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค, ์†”๋ฃจ์…˜ ๋“ฑ. (infrastructure/problem-generator-v3/dynamodb.tf)
    • problem-submissions: ์ฝ”๋“œ ์ œ์ถœ ๊ฒฐ๊ณผ. (infrastructure/code-execution-service/dynamodb.tf)
  • ๋ฐ์ดํ„ฐ ๊ฒฉ๋ฆฌ: ๊ฐ ์ฃผ์š” ์„œ๋น„์Šค ๋„๋ฉ”์ธ(์ปค๋ฎค๋‹ˆํ‹ฐ, ๋ฌธ์ œ, ์ œ์ถœ)์€ ์ž์ฒด DynamoDB ํ…Œ์ด๋ธ”์„ ๊ฐ–๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” MSA์˜ โ€œ์„œ๋น„์Šค๋‹น ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šคโ€ ํŒจํ„ด๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • ๊ธ€๋กœ๋ฒŒ ๋ณด์กฐ ์ธ๋ฑ์Šค (GSI): ๋‹ค์–‘ํ•œ ์ฟผ๋ฆฌ ํŒจํ„ด์„ ํšจ์œจ์ ์œผ๋กœ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. (์˜ˆ: getAllPosts์˜ CompletedProblemsByCreatedAtGSI, getSubmission์˜ ๋‹ค์–‘ํ•œ GSI).
  • ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ:
    • ์›์ž์  ์นด์šดํ„ฐ (Atomic Counters): DynamoDB์˜ ์›์ž์  ์นด์šดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ likesCount, commentCount์™€ ๊ฐ™์€ ์†์„ฑ์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
    • ํŠธ๋žœ์žญ์…˜: community-lambda-functions/comment/createComment_modified.mjs ๋ฐ deleteComment_modified.mjs๋Š” TransactWriteCommand๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋Œ“๊ธ€์„ ์ถ”๊ฐ€/์‚ญ์ œํ•˜๊ณ  ๊ฒŒ์‹œ๋ฌผ์˜ commentCount๋ฅผ ์›์ž์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ํ”„๋กœ์ ์…˜ ํ‘œํ˜„์‹: Lambda ํ•จ์ˆ˜๋Š” ํ•„์š”ํ•œ ์†์„ฑ๋งŒ ์ฝ๋„๋ก DynamoDB ์ฟผ๋ฆฌ์— ํ”„๋กœ์ ์…˜ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ๊ธฐ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๊ณ  ๋น„์šฉ์„ ์ ˆ๊ฐํ•ฉ๋‹ˆ๋‹ค.

6. ๋ฐฐํฌ (Terraform์„ ์‚ฌ์šฉํ•œ IaC)

ALPACO์˜ ๋ชจ๋“  AWS ๋ฆฌ์†Œ์Šค(Lambda, API Gateway, DynamoDB, IAM ์—ญํ• , CloudFront ๋“ฑ)๋Š” Terraform์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ๋กœ ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

  • ๋ชจ๋“ˆ์‹ ๊ตฌ์กฐ: Terraform ์ฝ”๋“œ๋Š” ์„œ๋น„์Šค๋ณ„ ๋””๋ ‰ํ„ฐ๋ฆฌ(infrastructure/api, infrastructure/chatbot ๋“ฑ)๋กœ ๊ตฌ์„ฑ๋˜์–ด ๊ฐ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๋˜๋Š” ํ•จ๊ป˜ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์›๊ฒฉ ์ƒํƒœ: Terraform ์ƒํƒœ๋Š” S3 ๋ฒ„ํ‚ท(alpaco-tfstate-bucket-kmu)์— ์ค‘์•™์—์„œ ๊ด€๋ฆฌ๋˜๋ฉฐ, DynamoDB ํ…Œ์ด๋ธ”(alpaco-tfstate-lock-table)์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒํƒœ ์ž ๊ธˆ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. (infrastructure/backend-setup/ ๋ชจ๋“ˆ์—์„œ ์„ค์ •).
  • terraform_remote_state: ํ•œ ๋ชจ๋“ˆ์ด ๋‹ค๋ฅธ ๋ชจ๋“ˆ์˜ ์ถœ๋ ฅ(์˜ˆ: Cognito ์‚ฌ์šฉ์ž ํ’€ ARN, DynamoDB ํ…Œ์ด๋ธ” ์ด๋ฆ„)์— ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ data "terraform_remote_state"๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: code-execution-service๊ฐ€ problem-generator-v3์˜ problems_table_arn์„ ์ฐธ์กฐ).
  • ๋ณ€์ˆ˜ ๋ฐ ์ถœ๋ ฅ: ๊ฐ Terraform ๋ชจ๋“ˆ์€ variables.tf๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ์„ ๋ฐ›๊ณ  outputs.tf๋ฅผ ํ†ตํ•ด ์ค‘์š”ํ•œ ๋ฆฌ์†Œ์Šค ์‹๋ณ„์ž๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  • CI/CD: GitHub Actions๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ Terraform ๊ตฌ์„ฑ์„ ์ž๋™์œผ๋กœ ๊ณ„ํšํ•˜๊ณ  ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. OIDC๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ AWS์— ์•ˆ์ „ํ•˜๊ฒŒ ์ธ์ฆํ•ฉ๋‹ˆ๋‹ค.
    • Lambda ๋ ˆ์ด์–ด ๋นŒ๋“œ ๋‹จ๊ณ„๋Š” CI/CD ํŒŒ์ดํ”„๋ผ์ธ์— ํ†ตํ•ฉ๋˜์–ด terraform apply ์ „์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
  • ๋ฐฐํฌ ์ˆœ์„œ: ๋ชจ๋“ˆ ๊ฐ„ ์˜์กด์„ฑ์œผ๋กœ ์ธํ•ด ํŠน์ • ๋ฐฐํฌ ์ˆœ์„œ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (InfrastructureAsCode.md์˜ โ€œ์ „์ฒด ๋ฐฐํฌ ์ „๋žต ๋ฐ ์ˆœ์„œโ€ ์ฐธ์กฐ). ํŠนํžˆ problem-generator-v3์™€ code-execution-service ๊ฐ„์˜ ์ˆœํ™˜ ์˜์กด์„ฑ์€ ๋‹ค๋‹จ๊ณ„ ๋ฐฐํฌ๋กœ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

7. ๋กœ์ปฌ ๊ฐœ๋ฐœ ๋ฐ ํ…Œ์ŠคํŠธ

  • Lambda ๊ฐœ๋ณ„ ํ…Œ์ŠคํŠธ:
    • chatbot-query/howto.md: AWS CLI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ chatbot-query Lambda๋ฅผ ์ˆ˜๋™์œผ๋กœ ํ˜ธ์ถœํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.
    • problem-generator-v3/local-test.mjs: problem-generator-v3 ํŒŒ์ดํ”„๋ผ์ธ์„ ๋กœ์ปฌ์—์„œ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค. DynamoDB ๋ชจํ‚น์„ ์ง€์›ํ•˜๋ฉฐ, .env ํŒŒ์ผ์„ ํ†ตํ•ด ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจํ‚น:
    • problem-generator-v3์˜ local-test.mjs๋Š” mock-dynamodb.mjs๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DynamoDB ์ž‘์—…์„ ๋ชจํ‚นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์™ธ๋ถ€ API ํ˜ธ์ถœ(์˜ˆ: Google Gemini)์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ์ค‘ ์‹ค์ œ ํ˜ธ์ถœ๋˜๊ฑฐ๋‚˜, ํ•„์š”์‹œ ๋ชจํ‚น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(์˜ˆ: sinon, jest.mock)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจํ‚น๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ํ˜„์žฌ codeExecutor.mjs์˜ Python ์ฝ”๋“œ ์‹คํ–‰์€ ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ์ค‘์—๋„ ๋ฐฐํฌ๋œ ์‹ค์ œ Code Executor Lambda๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์™„์ „ํ•œ ์˜คํ”„๋ผ์ธ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด์„œ๋Š” ์ด ๋ถ€๋ถ„์— ๋Œ€ํ•œ ๋ชจํ‚น ๋˜๋Š” ๋กœ์ปฌ Python ์‹คํ–‰๊ธฐ ๊ตฌํ˜„์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹จ์œ„ ํ…Œ์ŠคํŠธ: ๊ฐ Lambda ํ•จ์ˆ˜์˜ ํ•ต์‹ฌ ๋กœ์ง์— ๋Œ€ํ•ด Jest, Mocha ๋“ฑ์˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค (ํ˜„์žฌ ์ฝ”๋“œ๋ฒ ์ด์Šค์—๋Š” ๋ช…์‹œ์ ์ธ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ ์‚ฌ์šฉ์ด ๋‘๋“œ๋Ÿฌ์ง€์ง€ ์•Š์Œ).
  • ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ: ๋ฐฐํฌ๋œ ํ™˜๊ฒฝ์—์„œ ์„œ๋น„์Šค ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ์„ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค (์˜ˆ: API Gateway ์—”๋“œํฌ์ธํŠธ ํ˜ธ์ถœ).

8. ALPACO Lambda ์„œ๋น„์Šค ์˜ˆ์‹œ ๋ฐ MSA ํŒจํ„ด ์ ์šฉ

8.1. code-grader ๋ฐ code-executor (์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ๋ฐ ์ž‘์—…์ž ํŒจํ„ด)

  • code-grader๋Š” ์ฑ„์  ์š”์ฒญ์„ ๋ฐ›๋Š” ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • code-executor๋Š” ํŠน์ • ์ž‘์—…(์ฝ”๋“œ ์‹คํ–‰)์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์ž ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ๋‘˜์€ Lambda ์ง์ ‘ ๋™๊ธฐ์‹ ํ˜ธ์ถœ์„ ํ†ตํ•ด ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋Š” MSA์—์„œ ๋ณต์žกํ•œ ์ž‘์—…์„ ๋” ์ž‘๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์šด ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„๋Š” ์ผ๋ฐ˜์ ์ธ ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

8.2. chatbot-query ๋ฐ problem-generator-v3 (์™ธ๋ถ€ API ํ†ตํ•ฉ ๋ฐ ์ŠคํŠธ๋ฆฌ๋ฐ)

  • ๋‘ ์„œ๋น„์Šค ๋ชจ๋‘ ์™ธ๋ถ€ LLM(Google Gemini)๊ณผ ์ƒํ˜ธ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค.
  • API ํ‚ค์™€ ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์•ˆ์ „ํ•˜๊ฒŒ ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
  • ์‘๋‹ต์„ SSE ์ŠคํŠธ๋ฆผ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์— ์ „์†กํ•˜์—ฌ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.
  • chatbot-query๋Š” JWT ์ธ์ฆ์„ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ณด์•ˆ ๊ณ„์ธต์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

8.3. ์ปค๋ฎค๋‹ˆํ‹ฐ API (CRUD ๋ฐ ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ ์„œ๋น„์Šค)

  • createPost, getPost, updatePost, deletePost, likePost, createComment ๋“ฑ์€ ํŠน์ • ๋ฐ์ดํ„ฐ ์—”ํ‹ฐํ‹ฐ(๊ฒŒ์‹œ๋ฌผ, ๋Œ“๊ธ€)์— ๋Œ€ํ•œ CRUDL(Create, Read, Update, Delete, Like) ์ž‘์—…์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹จ์ผ DynamoDB ํ…Œ์ด๋ธ”๊ณผ ์—ฌ๋Ÿฌ GSI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์ ‘๊ทผ ํŒจํ„ด์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ํŠธ๋žœ์žญ์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ commentCount์™€ ๊ฐ™์€ ํŒŒ์ƒ ๋ฐ์ดํ„ฐ๋ฅผ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

8.4. problems-api ๋ฐ submissions-api (์ฝ๊ธฐ ์ „์šฉ ๋ฐ์ดํ„ฐ API)

  • ์ฃผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ  ํ•„ํ„ฐ๋งํ•˜๋Š” ๊ฐ„๋‹จํ•œ API์ž…๋‹ˆ๋‹ค.
  • ๋‹ค๋ฅธ ์„œ๋น„์Šค(problem-generator-v3, code-execution-service)์— ์˜ํ•ด ์ฑ„์›Œ์ง„ DynamoDB ํ…Œ์ด๋ธ”์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค.
  • ํŽ˜์ด์ง€๋„ค์ด์…˜ ๋ฐ ์ •๋ ฌ์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด GSI๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

9. ๊ฒฐ๋ก  ๋ฐ ๋ชจ๋ฒ” ์‚ฌ๋ก€ ์š”์•ฝ

ALPACO ํ”„๋กœ์ ํŠธ๋Š” AWS Lambda๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. MSA ํ™˜๊ฒฝ์—์„œ Lambda๋ฅผ ๊ฐœ๋ฐœํ•  ๋•Œ ๋‹ค์Œ ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค:

  • ๋‹จ์ผ ์ฑ…์ž„: Lambda ํ•จ์ˆ˜๋ฅผ ์ž‘๊ณ  ํŠน์ • ๊ธฐ๋Šฅ์— ์ง‘์ค‘ํ•˜๋„๋ก ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒํƒœ ๋น„์ €์žฅ(Stateless): Lambda ํ•จ์ˆ˜๋Š” ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๋„๋ก ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ์ƒํƒœ๋Š” DynamoDB์™€ ๊ฐ™์€ ์™ธ๋ถ€ ์ €์žฅ์†Œ์— ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค.
  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํ™œ์šฉ: ์„ค์ •์„ ์ฝ”๋“œ์—์„œ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • IAM ์ตœ์†Œ ๊ถŒํ•œ: ๊ฐ Lambda์— ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ๊ถŒํ•œ๋งŒ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ (Layers): ๊ณตํ†ต ๋กœ์ง ๋ฐ ์˜์กด์„ฑ์€ Lambda Layer๋ฅผ ํ†ตํ•ด ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๋ฐ ์žฌ์‹œ๋„: ๊ฒฌ๊ณ ํ•œ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜๊ณผ ์ ์ ˆํ•œ ์žฌ์‹œ๋„ ๋กœ์ง(์˜ˆ: problem-generator-v3 ํŒŒ์ดํ”„๋ผ์ธ)์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • ๋กœ๊น… ๋ฐ ๋ชจ๋‹ˆํ„ฐ๋ง: ํฌ๊ด„์ ์ธ ๋กœ๊น…์„ ํ™œ์„ฑํ™”ํ•˜๊ณ  CloudWatch๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ฑ๋Šฅ๊ณผ ์˜ค๋ฅ˜๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.
  • IaC (Terraform): ์ธํ”„๋ผ๋ฅผ ์ฝ”๋“œ๋กœ ๊ด€๋ฆฌํ•˜์—ฌ ์ผ๊ด€์„ฑ, ๋ฐ˜๋ณต์„ฑ ๋ฐ ๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • API ๋ฒ„์ „ ๊ด€๋ฆฌ: API ๋ณ€๊ฒฝ ์‹œ ํ•˜์œ„ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๊ฑฐ๋‚˜ API Gateway๋ฅผ ํ†ตํ•ด ๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ: ๋‹จ์œ„ ํ…Œ์ŠคํŠธ, ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ, ์ข…๋‹จ ๊ฐ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ฒ ์ €ํžˆ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ฐ€์ด๋“œ๊ฐ€ ALPACO ํ”„๋กœ์ ํŠธ์˜ Lambda ๊ธฐ๋ฐ˜ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋ฅผ ์ดํ•ดํ•˜๊ณ  ๊ฐœ๋ฐœํ•˜๋Š” ๋ฐ ์œ ์šฉํ•œ ์ž๋ฃŒ๊ฐ€ ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.