Submissions API & ํ”„๋ก ํŠธ์—”๋“œ ์—ฐ๋™ (capstone-2025-04)

1. ๊ฐœ์š”

์ด ๋ชจ๋“ˆ์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฒฝ์ง„๋Œ€ํšŒ ์ œ์ถœ(Submission) ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค์ธ โ€œSubmissions APIโ€๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ด API๋ฅผ ํ†ตํ•ด ์ œ์ถœ ๋ชฉ๋ก์„ ํ‘œ์‹œํ•˜๊ณ , ํ•„ํ„ฐ๋งํ•˜๋ฉฐ, ๊ฐœ๋ณ„ ์ œ์ถœ์˜ ์ƒ์„ธ ์ •๋ณด๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

API๋Š” AWS API Gateway์™€ AWS Lambda๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์ถ•๋˜์—ˆ์œผ๋ฉฐ, ์ œ์ถœ ๊ธฐ๋ก์„ ์ €์žฅํ•˜๋Š” DynamoDB ํ…Œ์ด๋ธ”(์ด๋Š” code-execution-service ๋ชจ๋“ˆ์—์„œ ๊ด€๋ฆฌ)๊ณผ ์ƒํ˜ธ ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ ์—ฐ๋™์€ ์ด API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Next.js/React ํŽ˜์ด์ง€๋ฅผ ํ†ตํ•ด ์‹œ์—ฐ๋ฉ๋‹ˆ๋‹ค.

2. ์ฃผ์š” ๊ธฐ๋Šฅ

  • ์ œ์ถœ ๋ชฉ๋ก ์กฐํšŒ: ๋ชจ๋“  ์ œ์ถœ ๋˜๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ์ค€์œผ๋กœ ํ•„ํ„ฐ๋ง๋œ ์ œ์ถœ ๋ชฉ๋ก์„ ํŽ˜์ด์ง€๋„ค์ด์…˜(pagination)ํ•˜์—ฌ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  • ์ œ์ถœ ํ•„ํ„ฐ๋ง:
    • userId (์ œ์ถœํ•œ ์‚ฌ์šฉ์ž์˜ ID) ๊ธฐ์ค€
    • problemId (์‹œ๋„ํ•œ ๋ฌธ์ œ์˜ ID) ๊ธฐ์ค€
    • author (์ œ์ถœ์ž์˜ ๋‹‰๋„ค์ž„/์‚ฌ์šฉ์ž๋ช…) ๊ธฐ์ค€
    • problemTitleTranslated (๋ฒˆ์—ญ๋œ ๋ฌธ์ œ ์ œ๋ชฉ์— ๋Œ€ํ•œ ๋ถ€๋ถ„ ๋˜๋Š” ์ „์ฒด ์ผ์น˜) ๊ธฐ์ค€
    • userId์™€ problemId ์กฐํ•ฉ
    • author์™€ problemId ์กฐํ•ฉ
  • ์ œ์ถœ ์ •๋ ฌ: submissionTime ๊ธฐ์ค€์œผ๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ(ASC) ๋˜๋Š” ๋‚ด๋ฆผ์ฐจ์ˆœ(DESC) ์ •๋ ฌํ•ฉ๋‹ˆ๋‹ค.
  • ํŽ˜์ด์ง€๋„ค์ด์…˜: ํšจ์œจ์ ์ธ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ์„ ์œ„ํ•ด pageSize์™€ lastEvaluatedKey๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ • ์ œ์ถœ ์กฐํšŒ: submissionId๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹จ์ผ ์ œ์ถœ์˜ ์ „์ฒด ์ƒ์„ธ ์ •๋ณด(์‚ฌ์šฉ์ž ์ฝ”๋“œ userCode ํฌํ•จ)๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  • CORS ์ง€์›: API Gateway ์ˆ˜์ค€์—์„œ ์„ค์ •ํ•˜๊ณ , ์‚ฌ์ „ ์š”์ฒญ(preflight request)์„ ์œ„ํ•ด Lambda์—์„œ๋„ ๊ฐ•ํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • ๋กœ๊น…: API Gateway ์ ‘๊ทผ ๋กœ๊ทธ ๋ฐ Lambda ์‹คํ–‰ ๋กœ๊ทธ๋Š” CloudWatch Logs๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.
  • ์ฝ”๋“œํ˜• ์ธํ”„๋ผ (Infrastructure as Code): ๋ชจ๋“  AWS ๋ฆฌ์†Œ์Šค๋Š” Terraform์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๋น„์ €๋‹๋ฉ๋‹ˆ๋‹ค.

3. ์•„ํ‚คํ…์ฒ˜

์‹œ์Šคํ…œ์€ ์„œ๋ฒ„๋ฆฌ์Šค ์•„ํ‚คํ…์ฒ˜๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค:

  1. ํ”„๋ก ํŠธ์—”๋“œ (Next.js/React): ์‚ฌ์šฉ์ž๋Š” /submissions ํŽ˜์ด์ง€์™€ ์ƒํ˜ธ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค.
  2. API ํด๋ผ์ด์–ธํŠธ (submissionApi.ts): Submissions API๋กœ HTTP GET ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
  3. AWS API Gateway (submissions_api):
    • /submissions ๋ฆฌ์†Œ์Šค์— GET ๋ฐ OPTIONS ๋ฉ”์„œ๋“œ๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
    • GET ์š”์ฒญ์„ get_submission Lambda ํ•จ์ˆ˜๋กœ ๋ผ์šฐํŒ…ํ•ฉ๋‹ˆ๋‹ค (AWS_PROXY ํ†ตํ•ฉ).
    • CORS ์‚ฌ์ „ ์š”์ฒญ์„ ์œ„ํ•ด MOCK ํ†ตํ•ฉ์œผ๋กœ OPTIONS ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  4. AWS Lambda (get_submission):
    • Node.js 20.x ๋ฒ„์ „์˜ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
    • API Gateway ์ด๋ฒคํŠธ์—์„œ ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํŒŒ์‹ฑํ•ฉ๋‹ˆ๋‹ค.
    • submissionId๊ฐ€ ์žˆ์œผ๋ฉด DynamoDB ํ…Œ์ด๋ธ”์— ๋Œ€ํ•ด GetItem ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    • ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด, ํ•„ํ„ฐ์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ๊ธ€๋กœ๋ฒŒ ๋ณด์กฐ ์ธ๋ฑ์Šค(GSI)๋ฅผ ํ™œ์šฉํ•˜์—ฌ DynamoDB ํ…Œ์ด๋ธ”์— Query ์ž‘์—…์„ ๊ตฌ์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    • ์ œ์ถœ ๋ฐ์ดํ„ฐ(๋˜๋Š” ์˜ค๋ฅ˜)๋ฅผ API Gateway๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  5. AWS DynamoDB (code-execution-service์—์„œ ๊ด€๋ฆฌ):
    • Submissions ํ…Œ์ด๋ธ”์€ ๋ชจ๋“  ์ œ์ถœ ๊ธฐ๋ก์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
    • Lambda์—์„œ ์‚ฌ์šฉ๋˜๋Š” GSI:
      • ProblemIdSubmissionTimeIndex (problemId-submissionTime)
      • UserIdSubmissionTimeIndex (userId-submissionTime)
      • AllSubmissionsByTimeIndex (is_submission-submissionTime, โ€œ๋ชจ๋“  ์ œ์ถœโ€์šฉ)
      • AuthorSubmissionTimeIndex (author-submissionTime)
  6. AWS IAM: Lambda๊ฐ€ DynamoDB์— ์ ‘๊ทผํ•˜๊ณ  API Gateway๊ฐ€ ๋กœ๊ทธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ถŒํ•œ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  7. AWS CloudWatch Logs: ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ๋””๋ฒ„๊น…์„ ์œ„ํ•ด API Gateway ๋ฐ Lambda์˜ ๋กœ๊ทธ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

4. ๊ธฐ์ˆ  ์Šคํƒ

  • ๋ฐฑ์—”๋“œ:
    • AWS API Gateway (Regional Endpoint)
    • AWS Lambda (Node.js 20.x, arm64 ์•„ํ‚คํ…์ฒ˜)
    • AWS DynamoDB (AWS SDK v3 for JavaScript๋ฅผ ํ†ตํ•ด ์ ‘๊ทผ)
    • AWS IAM
    • AWS CloudWatch Logs
  • ์ฝ”๋“œํ˜• ์ธํ”„๋ผ:
    • Terraform (~> 5.0)
  • ํ”„๋ก ํŠธ์—”๋“œ ํด๋ผ์ด์–ธํŠธ (submissionApi.ts):
    • TypeScript
    • Fetch API
  • ํ”„๋ก ํŠธ์—”๋“œ UI (submissions/page.tsx):
    • Next.js 13+ (App Router)
    • React
    • TypeScript
    • Tailwind CSS (ํด๋ž˜์Šค๋ช…์œผ๋กœ ์œ ์ถ”)
    • date-fns (๋‚ ์งœ ํฌ๋งทํŒ…)
    • sonner (ํ† ์ŠคํŠธ ์•Œ๋ฆผ)

5. API ์—”๋“œํฌ์ธํŠธ ์ƒ์„ธ ์ •๋ณด

๋ชจ๋“  ์—”๋“œํฌ์ธํŠธ๋Š” API Gateway ์Šคํ…Œ์ด์ง€ ํ˜ธ์ถœ URL์„ ๊ธฐ์ค€์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค (์˜ˆ: https://{api_id}.execute-api.{region}.amazonaws.com/{stage_name}).

5.1. ์ œ์ถœ ์กฐํšŒ (๋ชฉ๋ก ๋˜๋Š” ํŠน์ • ๊ฑด)

  • ๊ฒฝ๋กœ: /submissions
  • ๋ฉ”์„œ๋“œ: GET
  • ์„ค๋ช…: ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋”ฐ๋ผ ์ œ์ถœ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜, submissionId๊ฐ€ ์ œ๊ณต๋œ ๊ฒฝ์šฐ ๋‹จ์ผ ์ œ์ถœ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  • ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ:
    • submissionId (๋ฌธ์ž์—ด, ์„ ํƒ ์‚ฌํ•ญ): ์ œ๊ณต๋œ ๊ฒฝ์šฐ, ID๋กœ ํŠน์ • ์ œ์ถœ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํ•„ํ„ฐ๋Š” ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.
    • userId (๋ฌธ์ž์—ด, ์„ ํƒ ์‚ฌํ•ญ): ์‚ฌ์šฉ์ž์˜ ๊ณ ์œ  ์‹๋ณ„์ž๋กœ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.
    • problemId (๋ฌธ์ž์—ด, ์„ ํƒ ์‚ฌํ•ญ): ๋ฌธ์ œ์˜ ๊ณ ์œ  ์‹๋ณ„์ž๋กœ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.
    • author (๋ฌธ์ž์—ด, ์„ ํƒ ์‚ฌํ•ญ): ์ž‘์„ฑ์ž์˜ ๋‹‰๋„ค์ž„์œผ๋กœ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.
    • problemTitleTranslated (๋ฌธ์ž์—ด, ์„ ํƒ ์‚ฌํ•ญ): ๋ฒˆ์—ญ๋œ ๋ฌธ์ œ ์ œ๋ชฉ์— ๋Œ€ํ•œ ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ ๋ถ€๋ถ„ ๋ฌธ์ž์—ด ์ผ์น˜๋กœ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.
    • pageSize (์ˆซ์ž, ์„ ํƒ ์‚ฌํ•ญ, ๊ธฐ๋ณธ๊ฐ’: 20): ํŽ˜์ด์ง€๋‹น ๋ฐ˜ํ™˜ํ•  ํ•ญ๋ชฉ ์ˆ˜์ž…๋‹ˆ๋‹ค.
    • lastEvaluatedKey (๋ฌธ์ž์—ด, ์„ ํƒ ์‚ฌํ•ญ): ๋‹ค์Œ ํŽ˜์ด์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•œ ์ด์ „ ์‘๋‹ต์˜ lastEvaluatedKey์ž…๋‹ˆ๋‹ค. URL ์ธ์ฝ”๋”ฉ๋œ JSON ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.
    • sortOrder (๋ฌธ์ž์—ด, ์„ ํƒ ์‚ฌํ•ญ, ๊ธฐ๋ณธ๊ฐ’: โ€œDESCโ€): submissionTime์— ๋Œ€ํ•œ ์ •๋ ฌ ์ˆœ์„œ์ž…๋‹ˆ๋‹ค. โ€œASCโ€ ๋˜๋Š” โ€œDESCโ€๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์ธ์ฆ: NONE (๊ณต๊ฐœ์ ์œผ๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅ, apigateway.tf์—์„œ AWS_IAM ๋˜๋Š” Cognito๋กœ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ)
  • ์„ฑ๊ณต ์‘๋‹ต (200 OK):
    // ๋ชฉ๋ก ์ฟผ๋ฆฌ์˜ ๊ฒฝ์šฐ
    {
      "items": [
        {
          "submissionId": "unique-submission-id-1",
          "problemId": "problem-abc-123",
          "problemTitle": "Original Problem Title", // ํ•ญ์ƒ ์กด์žฌํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ
          "problemTitleTranslated": "๋ฒˆ์—ญ๋œ ๋ฌธ์ œ ์ œ๋ชฉ",
          "userId": "user-xyz-789",
          "author": "AlpacoCoder",
          "status": "ACCEPTED", // ๋˜๋Š” WRONG_ANSWER, TIME_LIMIT_EXCEEDED ๋“ฑ
          "submissionTime": "2023-10-27T10:30:00.123Z", // ISO 8601 ๋ฌธ์ž์—ด (DynamoDB ์ •๋ ฌ ํ‚ค)
          "executionTime": 0.123, // ์ดˆ
          "language": "python",
          "errorMessage": null // ๋˜๋Š” ์ƒํƒœ๊ฐ€ ์˜ค๋ฅ˜์ธ ๊ฒฝ์šฐ ์˜ค๋ฅ˜ ์„ธ๋ถ€ ์ •๋ณด
          // submissionId๋กœ ์กฐํšŒ ์‹œ userCode๋„ ์—ฌ๊ธฐ์— ํฌํ•จ๋  ์ˆ˜ ์žˆ์Œ (ํ”„๋กœ์ ์…˜/๊ฐ€์ ธ์˜ค๊ธฐ ๋œ ๊ฒฝ์šฐ)
        }
        // ... ๋” ๋งŽ์€ ํ•ญ๋ชฉ๋“ค
      ],
      "lastEvaluatedKey": "URL_ENCODED_JSON_STRING_OR_NULL",
      "count": 1, // ์ด ์‘๋‹ต์˜ ํ•ญ๋ชฉ ์ˆ˜
      "scannedCount": 1 // DynamoDB์—์„œ ์Šค์บ”ํ•œ ํ•ญ๋ชฉ ์ˆ˜ (ํ•„ํ„ฐ ํšจ์œจ์„ฑ๊ณผ ๊ด€๋ จ๋จ)
    }
    
    // ํŠน์ • submissionId ์ฟผ๋ฆฌ์˜ ๊ฒฝ์šฐ (Lambda์—์„œ ๋™์ผํ•œ ๊ตฌ์กฐ๋กœ ๋ž˜ํ•‘๋จ)
    {
      "items": [
        {
          "submissionId": "specific-submission-id",
          "problemId": "problem-def-456",
          "problemTitleTranslated": "ํŠน์ • ๋ฌธ์ œ ์ œ๋ชฉ",
          "userId": "user-abc-123",
          "author": "TestUser",
          "status": "RUNTIME_ERROR",
          "submissionTime": "2023-10-28T12:00:00.000Z",
          "executionTime": 0.050,
          "language": "javascript",
          "userCode": "console.log('hello world'); // ์‹ค์ œ ์‚ฌ์šฉ์ž ์ฝ”๋“œ",
          "errorMessage": "TypeError: undefined is not a function"
        }
      ],
      "lastEvaluatedKey": null,
      "count": 1,
      "scannedCount": 1
    }
    
  • ์˜ค๋ฅ˜ ์‘๋‹ต:
    • 400 Bad Request: ์ž˜๋ชป๋œ lastEvaluatedKey ํ˜•์‹์ž…๋‹ˆ๋‹ค.
    • 404 Not Found: submissionId๊ฐ€ ์ œ๊ณต๋˜์—ˆ์ง€๋งŒ ์ œ์ถœ์„ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.
    • 500 Internal Server Error: ์„œ๋ฒ„ ์ธก ์˜ค๋ฅ˜ (์˜ˆ: Lambda ๊ตฌ์„ฑ ์˜ค๋ฅ˜, DynamoDB ์ ‘๊ทผ ๋ฌธ์ œ).

5.2. CORS ์‚ฌ์ „ ์š”์ฒญ (Preflight)

  • ๊ฒฝ๋กœ: /submissions
  • ๋ฉ”์„œ๋“œ: OPTIONS
  • ์„ค๋ช…: ๋ธŒ๋ผ์šฐ์ €๋กœ๋ถ€ํ„ฐ์˜ CORS ์‚ฌ์ „ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ์‘๋‹ต (200 OK):
    • ๋‹ค์Œ ํ—ค๋”๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค:
      • Access-Control-Allow-Origin: '*' (์„ค์ • ๊ฐ€๋Šฅ)
      • Access-Control-Allow-Methods: 'GET,OPTIONS'
      • Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'

6. Lambda ํ•จ์ˆ˜ (getSubmission.mjs)

์œ„์น˜: capstone-2025-04/backend/lambdas/submissions-api/getSubmission.mjs

  • ๋ชฉ์ :
    • API Gateway ํ”„๋ก์‹œ ํ†ตํ•ฉ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • CORS๋ฅผ ์œ„ํ•ด OPTIONS ์š”์ฒญ์— ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.
    • ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํŒŒ์‹ฑํ•ฉ๋‹ˆ๋‹ค.
    • DynamoDB์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค:
      • submissionId๊ฐ€ ์žˆ์œผ๋ฉด GetItemCommand๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
      • ๋ชฉ๋ก/ํ•„ํ„ฐ๋ง๋œ ์š”์ฒญ์˜ ๊ฒฝ์šฐ ์ ์ ˆํ•œ GSI์™€ KeyConditionExpression/FilterExpression์„ ์‚ฌ์šฉํ•˜์—ฌ QueryCommand๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • API Gateway๋ฅผ ์œ„ํ•œ ์‘๋‹ต ํ˜•์‹์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜:
    • SUBMISSIONS_TABLE_NAME: ์ œ์ถœ์„ ์ €์žฅํ•˜๋Š” DynamoDB ํ…Œ์ด๋ธ”์˜ ์ด๋ฆ„ (code-execution-service ์›๊ฒฉ ์ƒํƒœ์—์„œ ๊ฐ€์ ธ์˜ด).
    • AWS_NODEJS_CONNECTION_REUSE_ENABLED: AWS SDK์˜ TCP ์—ฐ๊ฒฐ ์žฌ์‚ฌ์šฉ์„ ํ™œ์„ฑํ™”ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๋ ค๋ฉด โ€œ1โ€๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฃผ์š” ๋กœ์ง:
    • GSI ์„ ํƒ: userId, problemId ๋˜๋Š” author ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋”ฐ๋ผ GSI๋ฅผ ๋™์ ์œผ๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ํŠน์ • ์—”ํ‹ฐํ‹ฐ ํ•„ํ„ฐ๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š์œผ๋ฉด AllSubmissionsByTimeIndex๋ฅผ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ํ”„๋กœ์ ์…˜ ํ‘œํ˜„์‹ (Projection Expression): ์ฝ๊ธฐ ์šฉ๋Ÿ‰์„ ์ตœ์ ํ™”ํ•˜๊ณ  ํŽ˜์ด๋กœ๋“œ ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด DynamoDB์—์„œ ๊ฒ€์ƒ‰ํ•  ํŠน์ • ์†์„ฑ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ : submissionId๋กœ ๊ฐ€์ ธ์˜ฌ ๋•Œ Lambda๋Š” ํ•ด๋‹น ํ•ญ๋ชฉ์˜ ๋ชจ๋“  ์†์„ฑ(userCode ํฌํ•จ)์„ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ: DynamoDB ์ž‘์—… ๋ฐ ํŒŒ๋ผ๋ฏธํ„ฐ ํŒŒ์‹ฑ์„ ์œ„ํ•œ ๊ธฐ๋ณธ try-catch ๋ธ”๋ก์ž…๋‹ˆ๋‹ค.
    • unmarshallItem ํ—ฌํผ ํ•จ์ˆ˜: GetItemCommand ๊ฒฐ๊ณผ์— ๋Œ€ํ•ด DynamoDB์˜ ์†์„ฑ ๊ฐ’ ํ˜•์‹(์˜ˆ: { "S": "stringValue" })์„ ํ‘œ์ค€ JavaScript ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. DynamoDBDocumentClient๋Š” QueryCommand์— ๋Œ€ํ•ด ์ด๋ฅผ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

7. ํ”„๋ก ํŠธ์—”๋“œ ์—ฐ๋™

7.1. API ํด๋ผ์ด์–ธํŠธ (capstone-2025-04/frontend/src/api/submissionApi.ts)

  • SUBMISSIONS_API_BASE_URL: NEXT_PUBLIC_SUBMISSIONS_API_BASE_URL ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
  • getSubmissions(params):
    • GetSubmissionsParams๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    • /submissions ์—”๋“œํฌ์ธํŠธ๋กœ GET ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
    • Promise<GetSubmissionsResponse>๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • getSubmissionById(submissionId):
    • submissionId ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ /submissions ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ฟผ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • ๋™์ผํ•œ ์ œ์ถœ ID์— ๋Œ€ํ•œ ์ค‘๋ณต API ํ˜ธ์ถœ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด 5๋ถ„ ๋งŒ๋ฃŒ ์‹œ๊ฐ„์˜ ๊ฐ„๋‹จํ•œ ์ธ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ(submissionCache)๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
    • Markdown ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด language๊ฐ€ ์†Œ๋ฌธ์ž์ธ์ง€ ํ™•์ธํ•˜๊ณ , ์—†๋Š” ๊ฒฝ์šฐ โ€œplaintextโ€๋ฅผ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    • SubmissionSummary๊ฐ€ userCode๋ฅผ ํฌํ•จํ•˜๋Š” Promise<SubmissionSummary>๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • handleApiResponse: ์ผ๋ฐ˜์ ์ธ ์‘๋‹ต ์ฒ˜๋ฆฌ ๋ฐ ์˜ค๋ฅ˜ ํŒŒ์‹ฑ์„ ์œ„ํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

7.2. ์ œ์ถœ ํŽ˜์ด์ง€ (capstone-2025-04/frontend/src/app/submissions/page.tsx)

  • ์ƒํƒœ ๊ด€๋ฆฌ: ์ œ์ถœ ๋ชฉ๋ก, ๋กœ๋”ฉ ์ƒํƒœ, ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€, ํ•„ํ„ฐ(filterProblemTitle, filterAuthor), ์ •๋ ฌ ์ˆœ์„œ ๋ฐ ํŽ˜์ด์ง€๋„ค์ด์…˜(lastEvaluatedKey, hasMore)์„ ์œ„ํ•ด useState๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ:
    • useEffect์™€ useCallback์œผ๋กœ ๋ฉ”๋ชจ์ด์ง•๋œ fetchSubmissions ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค:
      • ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ ๋กœ๋“œ.
      • ํ•„ํ„ฐ ๋˜๋Š” ์ •๋ ฌ ์ˆœ์„œ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ๋ฐ์ดํ„ฐ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ค๊ธฐ.
    • handleLoadMore ํ•จ์ˆ˜๋Š” ์ €์žฅ๋œ lastEvaluatedKey๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ›„์† ํŽ˜์ด์ง€๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  • ํ•„ํ„ฐ๋ง UI: โ€œ๋ฌธ์ œ ์ œ๋ชฉ (ํ•œ๊ธ€)โ€ ๋ฐ โ€œ์ž‘์„ฑ์žโ€์— ๋Œ€ํ•œ ์ž…๋ ฅ ํ•„๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ์ •๋ ฌ UI: ์ •๋ ฌ ์ˆœ์„œ(ASC/DESC)๋ฅผ ์„ ํƒํ•˜๋Š” ๋“œ๋กญ๋‹ค์šด์ž…๋‹ˆ๋‹ค.
  • ํ‘œ์‹œ:
    • ์ œ์ถœ๋ฌผ์„ ํ…Œ์ด๋ธ”์— ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
    • ์ œ์ถœ ID๋ฅผ ๊ฒฐ๊ณผ ํŽ˜์ด์ง€(/coding-test/result?id={problemId}&submissionId={submissionId})๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฌธ์ œ ์ œ๋ชฉ์„ ๋ฌธ์ œ ํ’€์ด ํŽ˜์ด์ง€(/coding-test/solve?id={problemId})๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
    • date-fns๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ submissionTime์„ ํฌ๋งทํ•ฉ๋‹ˆ๋‹ค.
    • ์ ์ ˆํ•œ ์Šคํƒ€์ผ๊ณผ ํ•œ๊ธ€ ํ…์ŠคํŠธ๋กœ ์ƒํƒœ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ: ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ์‹คํŒจํ•˜๋ฉด toast ์•Œ๋ฆผ ๋ฐ ์ธ๋ผ์ธ ๋ฉ”์‹œ์ง€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ๋กœ๋”ฉ ํ‘œ์‹œ๊ธฐ: ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์ค‘์— ๋กœ๋”ฉ ์Šคํ”ผ๋„ˆ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • Suspense: ์ดˆ๊ธฐ ํŽ˜์ด์ง€ ๋กœ๋“œ ๋˜๋Š” ๊ฒฝ๋กœ ์ „ํ™˜ ์ค‘ ๋” ๋‚˜์€ ๋กœ๋”ฉ UX๋ฅผ ์œ„ํ•ด SubmissionsContent๋ฅผ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค.

8. ์ธํ”„๋ผ (Terraform)

์œ„์น˜: capstone-2025-04/infrastructure/submissions-api/

8.1. ์ฃผ์š” ๋ฆฌ์†Œ์Šค ์ •์˜:

  • aws_api_gateway_rest_api.submissions_api: ์ฃผ API Gateway ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค.
  • aws_api_gateway_resource.submissions_resource: /submissions ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.
  • aws_api_gateway_method.submissions_get: /submissions์— ๋Œ€ํ•œ GET ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
    • request_parameters: API Gateway์—์„œ ์ธ์‹ํ•˜๋Š” ์˜ˆ์ƒ ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
      • ์ฐธ๊ณ : ํ˜„์žฌ apigateway.tf ํŒŒ์ผ์˜ request_parameters์—๋Š” submissionId, author, problemTitleTranslated๊ฐ€ ๋ˆ„๋ฝ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Lambda๋Š” ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ, API Gateway ๋ฉ”์„œ๋“œ ์ •์˜์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฌธ์„œํ™” ๋ฐ Gateway ์ˆ˜์ค€์—์„œ์˜ ์š”์ฒญ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • aws_api_gateway_integration.submissions_get_lambda_integration: GET ๋ฉ”์„œ๋“œ๋ฅผ get_submission Lambda์™€ ํ†ตํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  • aws_api_gateway_method.submissions_options & aws_api_gateway_integration.submissions_options_mock_integration: CORS OPTIONS ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • aws_api_gateway_deployment.submissions_api_deployment & aws_api_gateway_stage.submissions_api_stage: API๋ฅผ ๋ฐฐํฌํ•˜๊ณ  ์Šคํ…Œ์ด์ง•ํ•ฉ๋‹ˆ๋‹ค. ์Šคํ…Œ์ด์ง€์—๋Š” ์ ‘๊ทผ ๋กœ๊น… ๊ตฌ์„ฑ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
  • aws_cloudwatch_log_group.submissions_api_gateway_logs: API Gateway ์ ‘๊ทผ ๋กœ๊ทธ๋ฅผ ์œ„ํ•œ ๋กœ๊ทธ ๊ทธ๋ฃน์ž…๋‹ˆ๋‹ค.
  • aws_iam_role.get_submission_lambda_role: get_submission Lambda๋ฅผ ์œ„ํ•œ IAM ์—ญํ• ์ž…๋‹ˆ๋‹ค.
  • aws_iam_policy.get_submission_dynamodb_policy: Lambda๊ฐ€ Submissions DynamoDB ํ…Œ์ด๋ธ”(GSI ํฌํ•จ)์—์„œ Query ๋ฐ GetItem์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•˜๋Š” IAM ์ •์ฑ…์ž…๋‹ˆ๋‹ค.
  • aws_iam_role.api_gateway_cloudwatch_role_submissions: API Gateway๊ฐ€ CloudWatch๋กœ ๋กœ๊ทธ๋ฅผ ํ‘ธ์‹œํ•˜๊ธฐ ์œ„ํ•œ IAM ์—ญํ• ์ž…๋‹ˆ๋‹ค.
  • aws_lambda_function.get_submission: Lambda ํ•จ์ˆ˜ ์ •์˜์ž…๋‹ˆ๋‹ค.
    • ../../backend/lambdas/submissions-api/getSubmission.mjs์—์„œ ์ฝ”๋“œ๋ฅผ ํŒจํ‚ค์ง•ํ•ฉ๋‹ˆ๋‹ค.
    • ํ™˜๊ฒฝ ๋ณ€์ˆ˜ SUBMISSIONS_TABLE_NAME(์›๊ฒฉ ์ƒํƒœ์—์„œ ๊ฐ€์ ธ์˜ด) ๋ฐ AWS_NODEJS_CONNECTION_REUSE_ENABLED๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • aws_lambda_permission.apigw_invoke_get_submission: API Gateway๊ฐ€ Lambda๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • data.terraform_remote_state.code_execution_service: S3์— ์ €์žฅ๋œ code-execution-service Terraform ์ƒํƒœ์—์„œ ์ถœ๋ ฅ(DynamoDB ํ…Œ์ด๋ธ” ์ด๋ฆ„ ๋ฐ ARN)์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

8.2. ๋ฐฑ์—”๋“œ ๊ตฌ์„ฑ (backend.tf):

  • Terraform ์ƒํƒœ๋Š” S3 ๋ฒ„ํ‚ท(alpaco-tfstate-bucket-kmu)์— ์ €์žฅ๋˜๋ฉฐ ์ƒํƒœ ์ž ๊ธˆ์„ ์œ„ํ•ด DynamoDB(alpaco-tfstate-lock-table)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

8.3. ๋ณ€์ˆ˜ (variables.tf):

  • aws_region, project_name, environment, common_tags์™€ ๊ฐ™์€ ๊ณตํ†ต ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • Lambda ๊ด€๋ จ ๊ตฌ์„ฑ: lambda_runtime, lambda_code_base_path, get_submission_handler, lambda_memory_size, lambda_timeout.
  • code-execution-service์— ๋Œ€ํ•œ ์›๊ฒฉ ์ƒํƒœ ๊ตฌ์„ฑ์ž…๋‹ˆ๋‹ค.

8.4. ์ถœ๋ ฅ (outputs.tf):

  • get_submission_lambda_name: ๋ฐฐํฌ๋œ Lambda ํ•จ์ˆ˜์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • submissions_api_invoke_url: API Gateway ์Šคํ…Œ์ด์ง€๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋ณธ URL์ž…๋‹ˆ๋‹ค.

9. ๋ฐฐํฌ ์ „์ œ ์กฐ๊ฑด

  • ํ•„์š”ํ•œ ๊ถŒํ•œ์„ ๊ฐ€์ง„ AWS ๊ณ„์ • ๋ฐ ๊ตฌ์„ฑ๋œ AWS CLI ์ž๊ฒฉ ์ฆ๋ช….
  • Terraform CLI (๋ฒ„์ „ ~> 5.0) ์„ค์น˜.
  • Node.js ๋ฐ npm/yarn (๋ฏธ๋ฆฌ ๋นŒ๋“œ๋œ zip์œผ๋กœ archive_file์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ Lambda ํŒจํ‚ค์ง• ๋ฐ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์šฉ).
  • code-execution-service ๋ชจ๋“ˆ์ด ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐฐํฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ชจ๋“ˆ์€ DynamoDB ํ…Œ์ด๋ธ” ์„ธ๋ถ€ ์ •๋ณด์— ๋Œ€ํ•ด ํ•ด๋‹น ๋ชจ๋“ˆ์˜ S3 ์›๊ฒฉ ์ƒํƒœ์— ์˜์กดํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Terraform ์ƒํƒœ๋ฅผ ์œ„ํ•œ S3 ๋ฒ„ํ‚ท(alpaco-tfstate-bucket-kmu)๊ณผ DynamoDB ํ…Œ์ด๋ธ”(alpaco-tfstate-lock-table)์ด ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

10. ์„ค์ • ๋ฐ ๋ฐฐํฌ

  1. ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๋ณต์ œ:
    git clone <your-repository-url>
    cd capstone-2025-04/infrastructure/submissions-api
    
  2. Lambda ์ฝ”๋“œ ์กด์žฌ ํ™•์ธ: Lambda ํ•จ์ˆ˜ ์ฝ”๋“œ getSubmission.mjs๊ฐ€ var.lambda_code_base_path (๊ธฐ๋ณธ๊ฐ’: ../../backend/lambdas/submissions-api/getSubmission.mjs)๋กœ ์ง€์ •๋œ ๊ฒฝ๋กœ์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  3. ๋ณ€์ˆ˜ ๊ตฌ์„ฑ (ํ•„์š”ํ•œ ๊ฒฝ์šฐ): variables.tf๋ฅผ ๊ฒ€ํ† ํ•˜๊ณ , ๊ธฐ๋ณธ๊ฐ’์ด ์ ํ•ฉํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ terraform.tfvars ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๋ช…๋ น์ค„์„ ํ†ตํ•ด ๋ณ€์ˆ˜๋ฅผ ์žฌ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ํ™•์ธํ•  ์ฃผ์š” ๋ณ€์ˆ˜:
    • aws_region
    • project_name
    • environment
    • code_execution_service_tfstate_bucket
    • code_execution_service_tfstate_key (์ด๊ฒƒ์ด code-execution-service์˜ ์˜ฌ๋ฐ”๋ฅธ ์ƒํƒœ ํŒŒ์ผ์„ ๊ฐ€๋ฆฌํ‚ค๋Š”์ง€ ํ™•์ธ)
  4. Terraform ์ดˆ๊ธฐํ™”:
    terraform init
    
  5. ๋ฐฐํฌ ๊ณ„ํš:
    terraform plan
    

    ๊ณ„ํš์„ ๊ฒ€ํ† ํ•˜์—ฌ ์˜ˆ์ƒ๋˜๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ์ƒ์„ฑ/์ˆ˜์ •๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  6. ๊ตฌ์„ฑ ์ ์šฉ:
    terraform apply
    

    ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋˜๋ฉด yes๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  7. API ํ˜ธ์ถœ URL ๊ธฐ๋ก: ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐฐํฌ๋˜๋ฉด Terraform์€ submissions_api_invoke_url์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด API์˜ ๊ธฐ๋ณธ URL์ž…๋‹ˆ๋‹ค. ์˜ˆ์‹œ: https://abcdef123.execute-api.ap-northeast-2.amazonaws.com/production

  8. ํ”„๋ก ํŠธ์—”๋“œ ๊ตฌ์„ฑ ์—…๋ฐ์ดํŠธ: ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(์˜ˆ: Next.js์˜ ๊ฒฝ์šฐ .env.local ํŒŒ์ผ)์—์„œ NEXT_PUBLIC_SUBMISSIONS_API_BASE_URL ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ด์ „ ๋‹จ๊ณ„์—์„œ ์–ป์€ submissions_api_invoke_url๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    NEXT_PUBLIC_SUBMISSIONS_API_BASE_URL=https://abcdef123.execute-api.ap-northeast-2.amazonaws.com/production
    

    ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์ ์šฉ๋˜๋„๋ก ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‹ค์‹œ ๋นŒ๋“œ/์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

11. ํ–ฅํ›„ ๊ฐœ์„  ์‚ฌํ•ญ / ๊ณ ๋ ค ์‚ฌํ•ญ

  • ์ธ์ฆ: API๊ฐ€ ๊ณต๊ฐœ๋˜์–ด์„œ๋Š” ์•ˆ ๋˜๋Š” ๊ฒฝ์šฐ ๊ฐ•๋ ฅํ•œ ์ธ์ฆ(์˜ˆ: AWS IAM, Amazon Cognito)์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • ์ž…๋ ฅ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ: API Gateway ์ˆ˜์ค€ ๋˜๋Š” Lambda ๋‚ด์— ๋ณด๋‹ค ํฌ๊ด„์ ์ธ ์ž…๋ ฅ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋ฅ˜ ์„ธ๋ถ„ํ™”: API์—์„œ ๋ณด๋‹ค ๊ตฌ์ฒด์ ์ธ ์˜ค๋ฅ˜ ์ฝ”๋“œ์™€ ๋ฉ”์‹œ์ง€๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ๊ณ ๊ธ‰ ๊ฒ€์ƒ‰: ๋ณด๋‹ค ๋ณต์žกํ•œ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ(์˜ˆ: ๋ฌธ์ œ ์ œ๋ชฉ ๋˜๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ „์ฒด ํ…์ŠคํŠธ ๊ฒ€์ƒ‰, ๋‚ ์งœ ๋ฒ”์œ„ ํ•„ํ„ฐ๋ง)์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • ์บ์‹ฑ: ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ์ž์ฃผ ์ ‘๊ทผ๋˜๊ณ  ๊ฐœ์ธํ™”๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด API Gateway ์ˆ˜์ค€ ์บ์‹ฑ์„ ๊ณ ๋ คํ•ฉ๋‹ˆ๋‹ค.
  • Dead Letter Queue (DLQ): ์ฒ˜๋ฆฌ ์‹คํŒจ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด Lambda ํ•จ์ˆ˜์— DLQ๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฉฑ๋“ฑ์„ฑ(Idempotency): POST/PUT/DELETE ์ž‘์—…์ด ์ถ”๊ฐ€๋˜๋Š” ๊ฒฝ์šฐ ๋ฉฑ๋“ฑ์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ: Lambda ํ•จ์ˆ˜์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ๋ฐ API์— ๋Œ€ํ•œ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • API Gateway ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ: apigateway.tf์˜ aws_api_gateway_method.submissions_get์— ์ •์˜๋œ request_parameters๋ฅผ Lambda์—์„œ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ(submissionId, author, problemTitleTranslated ๋“ฑ)์™€ ์ผ์น˜์‹œํ‚ต๋‹ˆ๋‹ค.

12. ๋ฌธ์ œ ํ•ด๊ฒฐ

  • API Gateway 5xx ์˜ค๋ฅ˜ (Internal Server Error ๋“ฑ):
    • API Gateway์— ๋Œ€ํ•œ CloudWatch Logs (/aws/api-gateway/{api_name}/{stage_name})๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    • get_submission Lambda ํ•จ์ˆ˜์— ๋Œ€ํ•œ CloudWatch Logs (/aws/lambda/{project_name}-getSubmission-{environment})๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ํ˜ธ์ถœ ์˜ค๋ฅ˜, ๊ถŒํ•œ ๋ฌธ์ œ(์˜ˆ: DynamoDB ์ ‘๊ทผ ๊ฑฐ๋ถ€) ๋˜๋Š” ์ฝ”๋“œ ์˜ค๋ฅ˜๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
  • ๋ธŒ๋ผ์šฐ์ €์˜ CORS ์˜ค๋ฅ˜:
    • API Gateway์—์„œ OPTIONS ๋ฉ”์„œ๋“œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌ์„ฑ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    • Access-Control-Allow-Origin ํ—ค๋”๊ฐ€ ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์˜ค๋ฆฌ์ง„๊ณผ ์ผ์น˜ํ•˜๋Š”์ง€ (๋˜๋Š” ๊ฐœ๋ฐœ์šฉ์œผ๋กœ *์ธ์ง€) ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    • ํŠน์ • CORS ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์— ๋Œ€ํ•ด ๋ธŒ๋ผ์šฐ์ € ์ฝ˜์†”์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • Lambda ์‹œ๊ฐ„ ์ดˆ๊ณผ:
    • ์š”์ฒญ ์‹œ๊ฐ„์ด ์ดˆ๊ณผ๋˜๋Š” ๊ฒฝ์šฐ CloudWatch์—์„œ Lambda ์‹คํ–‰ ์‹œ๊ฐ„์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๊ฒฝ์šฐ var.lambda_timeout์„ ๋Š˜๋ฆฝ๋‹ˆ๋‹ค.
    • DynamoDB ์ฟผ๋ฆฌ๋ฅผ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค (GSI๊ฐ€ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์Šค์บ”๋œ ํ•ญ๋ชฉ์„ ์ค„์ž„).
  • Terraform ์ ์šฉ ์‹คํŒจ:
    • Terraform์˜ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ์˜ ๊นŠ๊ฒŒ ์ฝ์Šต๋‹ˆ๋‹ค. ์ข…์ข… ๊ถŒํ•œ ๋ฌธ์ œ, ์ž˜๋ชป ๊ตฌ์„ฑ๋œ ๋ฆฌ์†Œ์Šค ๋˜๋Š” ์ข…์†์„ฑ ๋ฌธ์ œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.
    • code-execution-service์— ๋Œ€ํ•œ ์›๊ฒฉ ์ƒํƒœ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ  ์˜ˆ์ƒ ์ถœ๋ ฅ์„ ํฌํ•จํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.