StudyingπŸ’¨

[CodeStates] pre project - μ‹œμŠ€ν…œ κ΅¬ν˜„

hae02y 2023. 8. 23. 19:56
λ°˜μ‘ν˜•

πŸ”Š κ΅¬ν˜„ μ„€λͺ…

μ œκ°€ μ‚¬μš©ν•œ Java version은 11.0.2λ₯Ό μ‚¬μš©ν•˜μ˜€κ³ , Spring Boot λŠ” 2.7.14 λ₯Ό μ‚¬μš©ν•˜μ˜€μŠ΅λ‹ˆλ‹€. μžλ°” 11의 경우 LTS 버전이고, μžλ°” 8보닀 λ§Žμ€ κΈ°λŠ₯을 μ§€μ›ν•˜μ—¬ 11버전을 μ„ νƒν•˜μ˜€μŠ΅λ‹ˆλ‹€.

그리고 DB의 κ²½μš°μ—λŠ” 개발 κ³Όμ •μ—μ„œ H2 DBλ₯Ό μ‚¬μš©ν•˜μ˜€κ³ , CI/CD 이후에 AWS RDS의 MySQL DBλ₯Ό μ‚¬μš©ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

DB 섀계 및 API λ¬Έμ„œ μž‘μ„±

  • DB 섀계
    일단해보죠.png
  • νšŒμ›κ³Ό 질문의 경우 νšŒμ› 1λͺ…이 μ—¬λŸ¬ 개의 μ§ˆλ¬Έμ„ μž‘μ„±ν•˜κ±°λ‚˜ μ•„μ˜ˆ μž‘μ„±ν•˜μ§€ μ•Šμ„ μˆ˜λ„ 있고, λ‹΅λ³€μ˜ κ²½μš°λ„ νšŒμ›κ³Όμ˜ κ΄€κ³„λŠ” λ§ˆμ°¬κ°€μ§€μ΄λ©° 질문 1κ°œμ— 닡변이 μ—¬λŸ¬ 개 달릴 수 μžˆμœΌλ―€λ‘œ μœ„μ™€ 같이 μ„€κ³„ν•˜μ˜€μŠ΅λ‹ˆλ‹€. νƒœκ·ΈλŠ” μ§ˆλ¬Έμ— μ—¬λŸ¬ κ°œκ°€ 달릴 수 μžˆλŠ” ν˜•νƒœλ‘œ μ„€κ³„ν•˜μ˜€μŠ΅λ‹ˆλ‹€. N:M 관계인 νƒœκ·Έμ™€ 질문의 관계λ₯Ό 1:N 1:M으둜 λ‚˜λˆ„κΈ° μœ„ν•΄ μ§ˆλ¬Ένƒœκ·Έ(QuestionTag)λ₯Ό μƒμ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
  • νŒ€μ›λ“€κ³Όμ˜ μ†Œν†΅μ„ μœ„ν•΄μ„œ λ…Έμ…˜νŽ˜μ΄μ§€μ™€ λ””μŠ€μ½”λ“œλ‘œ μ†Œν†΅μ„ ν•˜λ©΄μ„œ μž‘μ—…μ„ ν•˜μ˜€μŠ΅λ‹ˆλ‹€. ν”„λ‘œμ νŠΈμ— λ“€μ–΄κ°€κΈ°μ „ μ‚¬μ΄νŠΈμ˜ μš”κ΅¬μ‚¬ν•­μ„ νŒŒμ•…ν•˜κΈ° μœ„ν•΄ μš”κ΅¬μ‚¬ν•­ λͺ…μ„Έμ„œλ₯Ό μž‘μ„±ν•˜μ˜€κ³ , 그에 따라 역할을 λΆ„λ°°ν•˜μ˜€μŠ΅λ‹ˆλ‹€. λ¨Όμ € νŒ€μ›λ“€κ³Ό ν•¨κ»˜ ERD λ‹€μ΄μ–΄κ·Έλž¨κ³Ό APIλͺ…μ„Έμ„œλ₯Ό μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
  • API λ¬Έμ„œ[API λͺ…μ„Έμ„œ]
  • μž‘μ„±μ—λŠ” νŒ€μ› λͺ¨λ‘κ°€ μ°Έμ—¬ν•˜μ—¬ μž‘μ„±ν•˜μ˜€κ³  각자 본인의 도메인을 μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€. μ €λŠ” 질문, λ‹΅λ³€, νƒœκ·Έμ˜ API λ¬Έμ„œλ₯Ό μž‘μ„±ν•˜μ˜€λŠ”λ° APIλ¬Έμ„œκ°€ ν”„λ‘ νŠΈμ—”λ“œμ™€ μ†Œν†΅ν•˜λŠ” μ—”λ“œν¬μΈνŠΈλΌλŠ” 점을 ν•œλ²ˆ 더 μ•Œ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μž‘μ„±μ„ μœ„ν•΄ RESTfulν•œ API μž‘μ„± 방법을 많이 μ°Ύμ•„λ³΄μ•˜κ³ , μ–΄λ–€ μ‹μœΌλ‘œ μž‘μ„±ν•˜λŠ” 것이 쒋은 API인지 μ•Œ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.
  • APIλ¬Έμ„œλŠ” Swagger와 PostMan을 κ³ λ―Όν•˜μ˜€μŠ΅λ‹ˆλ‹€. μ €ν¬λŠ” κ΅¬ν˜„μ— μ•žμ„œ λ¬Έμ„œλ₯Ό μž‘μ„±ν•˜λŠ” μ‹œκ°„μ΄ μžˆμ—ˆκΈ°μ—, 개발 μ½”λ“œλ₯Ό λ°”νƒ•μœΌλ‘œ APIλ¬Έμ„œλ₯Ό μƒμ„±ν•˜λŠ” Swagger 보닀 λ¬Έμ„œλ₯Ό μž‘μ„± 후에 ν™œμš© κ°€λŠ₯ν•œ Postman을 ν™œμš©ν•˜μ—¬ λ¬Έμ„œλ₯Ό μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€. λ¨Όμ € λ¬Έμ„œ μž‘μ„±μ„ ν•˜κ²Œ λ˜λ‹ˆ APIκ΅¬μ„±μ˜ λΌˆλŒ€λ₯Ό μž‘μ„ 수 μžˆμ—ˆκ³ , API ν†΅μ‹ μ˜ ν…ŒμŠ€νŠΈ μš©λ„λ‘œ Postman을 μ‚¬μš©ν–ˆκΈ° λ•Œλ¬Έμ— 접근이 νŽΈν–ˆμŠ΅λ‹ˆλ‹€.

질문, λ‹΅λ³€, νƒœκ·Έ CRUD κ΅¬ν˜„

  • 질문 쑰회수 κΈ°λŠ₯
    • 질문 κ²Œμ‹œκΈ€μ— 쑰회수 κΈ°λŠ₯을 μΆ”κ°€ν•˜μ˜€μŠ΅λ‹ˆλ‹€. Get μš”μ²­μœΌλ‘œ findQuestion에 μ ‘κ·Όμ‹œ viewCountUp λ©”μ„œλ“œμ—μ„œ 쑰회수의 증가λ₯Ό κ΅¬ν˜„ν•˜μ˜€μŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ findQuestionμ—μ„œ λ ˆν¬μ§€ν† λ¦¬μ— saveκ°€ μΌμ–΄λ‚˜λŠ” λ°©μ‹μœΌλ‘œ κ΅¬ν˜„μ„ ν•˜μ—¬μ„œ 좔후에 방식을 변경해보렀고 ν•©λ‹ˆλ‹€.
    • //QuestionService.java public Question findQuestion(Long questionsId) { Question question = questionRepository.findById(questionsId) .orElseThrow(() -> new BusinessLogicException(ExceptionCode.QUESTION_NOT_FOUND)); viewCountUp(question); // -> 쑰회수 questionRepository.save(question); return question; } //쑰회수 증가(get Question) private static void viewCountUp(Question question) { Long view = question.getViews(); question.setViews(++view); }
  • TimeStamp κ΅¬ν˜„
    • κ²Œμ‹œκΈ€κ³Ό, λ‹΅λ³€, μœ μ €μ˜ 생성에 μžˆμ–΄μ„œ μƒμ„±μ‹œκ°„κ³Ό μ‚­μ œμ‹œκ°„μ΄ κ³΅ν†΅μ μœΌλ‘œ κ΅¬ν˜„μ΄ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 쀑볡을 μ œκ±°ν•˜κΈ° μœ„ν•΄μ„œ TimeStamp 클래슀λ₯Ό κ΅¬ν˜„ν•˜μ—¬ Entity에 μƒμ†ν•˜μ—¬ μ‚¬μš©ν•˜λŠ” 방식을 νƒν–ˆμŠ΅λ‹ˆλ‹€.
      //Question.class
      
      @Entity
      @Getter
      @Setter
      public class Question extends TimeStamp {
      ...
      }
      μœ„μ™€ 같이 Question.classμ—μ„œ TimeStampλ₯Ό μƒμ†ν•˜μ—¬ μ‚¬μš©ν•˜μ˜€μŠ΅λ‹ˆλ‹€. μ•„μ‰¬μš΄ 뢀뢄은 modifiedAt의 경우 LocalDateTime을 직접 ν• λ‹Ήν•΄μ€¬λŠ”λ°, μœ„μ˜ 쑰회수 κ΅¬ν˜„ λΆ€λΆ„μ—μ„œ Getμš”μ²­μ΄ λ°œμƒν•  λ•Œ JPA Auditing κΈ°λŠ₯이 ν™œμ„±ν™” λ˜μ–΄, modifiedAt이 λ°”λ€ŒλŠ” μ΄μŠˆκ°€ μžˆμ–΄ μ μš©ν•˜μ˜€μŠ΅λ‹ˆλ‹€. μ΄λŠ” 좔후에 λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ λ¦¬νŒ©ν„°λ§ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.
    • //TimeStamp.class @Getter @Setter @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public class TimeStamp { @CreatedDate @Column(updatable = false) private LocalDateTime createdAt; private LocalDateTime modifiedAt = LocalDateTime.now(); }

CI/CD (AWS EC2 + Github Action)

CI/CDλŠ” 처음 μ§„ν–‰ν•˜λ‹€ λ³΄λ‹ˆ μ–΄λ €μš΄ 점이 λ§Žμ•˜μŠ΅λ‹ˆλ‹€. μ•„λž˜μ™€ 같은 λ°©μ‹μœΌλ‘œ κ΅¬ν˜„μ„ ν•˜μ˜€μŠ΅λ‹ˆλ‹€. Jenkins의 μ‚¬μš©μ„ κ³ λ €ν–ˆμ—ˆλŠ”λ° ν”„λ‘œμ νŠΈμ˜ 규λͺ¨λ‚˜ μ‹œκ°„ 등을 κ³ λ € ν–ˆμ„ λ•Œ Github Action이 ν”„λ‘œμ νŠΈμ— μ ν•©ν•˜λ‹€κ³  νŒλ‹¨ν•˜μ—¬ μ§„ν–‰ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

Untitled

Github λ ˆν¬μ§€ν† λ¦¬μ˜ main으둜 pushν•˜κ²Œ 되면 github Action이 μž‘λ™ν•˜κ²Œ 되고, AWS의 CodeDeployλ₯Ό 톡해 EC2에 배포와 싀행이 λ˜λŠ” λ°©μ‹μœΌλ‘œ κ΅¬ν˜„μ„ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

name: CI-CD

on:
  push:
    branches:
      - main
  workflow_dispatch:

  pull_request:
    branches:
      - main

env:
  S3_BUCKET_NAME: pre016
  RESOURCE_PATH: server/src/main/resources/application.yml
  CODE_DEPLOY_APPLICATION_NAME: pre016-codedeploy-app
  CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: pre016-codedeploy-deployment-group

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: 11
          distribution: 'temurin'

    # appspec.yml, scripts(start.sh, stop.sh)디렉토리 볡사
      - name: Copy appspec.yml to current directory
        run: |
            cp server/appspec.yml .
            cp -r server/scripts .
        shell: bash

      - name: Build with Gradle and print build result
        run: |
          cd server
          chmod +x gradlew
          ./gradlew build -x test
        shell: bash

      - name: Copy jar file to current directory
        run: cp server/build/libs/*.jar .
        shell: bash

      - name: Make zip file
        run: zip -r ./$GITHUB_SHA.zip .
        shell: bash

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Upload to S3
        run: |
          aws deploy push \
            --application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
            --ignore-hidden-files \
            --s3-location s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip \
            --source .

      - name: Code Deploy
        run: |
          aws deploy create-deployment \
          --application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
          --deployment-config-name CodeDeployDefault.AllAtOnce \
          --deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \
          --s3-location bucket=$S3_BUCKET_NAME,key=$GITHUB_SHA.zip,bundleType=zip

CI/CD λ₯Ό κ΅¬ν˜„ν•˜λ©΄μ„œ Github Action을 μ‚¬μš©ν•΄λ³Ό 수 μžˆλŠ” 쒋은 κΈ°νšŒμ˜€μŠ΅λ‹ˆλ‹€. CI/CDλ₯Ό κ΅¬ν˜„ν•˜λŠ” Flowκ°€ 정말 λ‹€μ–‘ν•˜λ‹€λŠ” 것을 μ•Œκ²Œ λ˜μ—ˆκ³  κΈ°νšŒκ°€ λœλ‹€λ©΄ λ‹€λ₯Έ λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν•΄ 보고 μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€. 그리고 yml을 μž‘μ„±ν•˜λŠ” 방법도 κ³΅λΆ€ν•˜μ˜€μŠ΅λ‹ˆλ‹€. yml의 κ²½μš°μ—λ„ λ°°μ—΄ 등을 ν‘œν˜„ν•  수 μžˆλ‹€λŠ” 것을 μ•Œμ•˜μŠ΅λ‹ˆλ‹€. 이와 κ΄€λ ¨ν•˜μ—¬ λΈ”λ‘œκ·Έμ— 기둝해 λ‘μ—ˆμŠ΅λ‹ˆλ‹€.

[XML / JSon / YAML]

MySQL DBμ„œλ²„ 연동(AWS RDS μ‚¬μš©)

Untitled

κ°œλ°œλ‹¨κ³„μ—μ„œ H2 DBλ₯Ό μ‚¬μš©ν•˜λ‹€λ³΄λ‹ˆ, μ„œλ²„κ°€ μž¬κΈ°λ™ 되면 데이터가 μ΄ˆκΈ°ν™” λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄ MySQL을 κ³ λ €ν•˜μ˜€μŠ΅λ‹ˆλ‹€. μ΄λ•Œ μ €ν¬μ—κ²Œ 선택할 수 μžˆλŠ” 방법은 RDSλ₯Ό μ‚¬μš©ν•˜λŠ” 방법과 EC2에 직접 MySQL을 μ„€μΉ˜ν•˜μ—¬ μš΄μ˜ν•˜λŠ” 방법이 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μ €λŠ” RDSλ₯Ό ν•œλ²ˆ κ²½ν—˜ν•΄λ³΄κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ RDSλ₯Ό μ„ νƒν•˜μ˜€κ³ , RDSλ₯Ό μ‚¬μš©μ‹œμ— μ–»κ²Œ λ˜λŠ” μž₯점에 λŒ€ν•΄ 곡뢀할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ RDSμ‚¬μš©ν•˜κ²Œ λ˜λ‹ˆ λΉ„μš©μ— λŒ€ν•œ 뢀담이 μƒκ²ΌμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ ν˜„μž¬λŠ” RDS DBλ₯Ό 내렀놓은 μƒνƒœμ΄κ³ , EC2에 직접 μ„€μΉ˜ν•˜μ—¬ λ¦¬νŒ©ν† λ§ μž‘μ—…μ— μ‚¬μš© ν•  κ³„νšμ„ μ„Έμš°κ³  μžˆμŠ΅λ‹ˆλ‹€.


πŸ’‘ μ–΄λ €μ› λ˜ 점 / 배운 점

MappedBy μ—λŸ¬

Spring Data JPA의 mappedByλ₯Ό μž‘μ„±ν•˜λŠ” 것에 어렀움이 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œ ν…Œμ΄λΈ”μ˜ 연관관계에 λŒ€ν•œ 곡뢀λ₯Ό ν•˜μ˜€κ³ , μ–‘λ°©ν–₯ λ§€ν•‘μ‹œμ— λ‘˜μ€‘ ν•˜λ‚˜κ°€ μ™Έλž˜ν‚€λ₯Ό κ΄€λ¦¬ν•΄μ•Όν•˜κ³  μ΄λŠ” μ—°κ΄€κ΄€κ³„μ˜ 주인(Owner)이 ν•΄μ•Όν•œλ‹€λŠ” 것을 μ•Œμ•˜μŠ΅λ‹ˆλ‹€. μ΄λ•Œ OwnerλŠ” mappedBy 속성을 μ‚¬μš©ν•˜μ§€ μ•Šκ³ , Ownerκ°€ μ•„λ‹ˆλ©΄ mappedBy속성을 μ‚¬μš©ν•©λ‹ˆλ‹€.

μˆœν™˜μ°Έμ‘° μ—λŸ¬

@Entity
@Getter
@Setter
public class Question extends TimeStamp {

        ... 

    @JsonIgnore //μˆœν™˜μ°Έμ‘° λ°œμƒν•˜μ—¬ stackoverflow μ—λŸ¬λ‚¨ > JsonIgnore μ‚¬μš©ν•΄μ„œ μ—†μ• μ€€λ‹€
    @OneToMany(mappedBy = "question", cascade = CascadeType.ALL)
    private List<Answer> answers = new ArrayList<>();

    @JsonIgnore //μˆœν™˜μ°Έμ‘° λ°œμƒν•˜μ—¬ stackoverflow μ—λŸ¬λ‚¨ > JsonIgnore μ‚¬μš©ν•΄μ„œ μ—†μ• μ€€λ‹€
    @OneToMany(mappedBy = "question", cascade = CascadeType.ALL)
    private List<QuestionTag> questionTags = new ArrayList<>();

}

OneToMany κ΄€κ³„μ—μ„œ Getμš”μ²­μœΌλ‘œ μ‘°νšŒμ‹œμ— μˆœν™˜μ°Έμ‘°μ—λŸ¬κ°€ λ°œμƒν•˜μ˜€μŠ΅λ‹ˆλ‹€. 이λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄μ„œ @JsonIgnoreλ₯Ό μ‚¬μš©ν•˜μ—¬ λ°©μ§€ν•΄μ€¬μŠ΅λ‹ˆλ‹€.

H2 DB μ˜ˆμ•½μ–΄ μ—λŸ¬

졜초의 ν…Œμ΄λΈ”μ„€κ³„μ‹œμ— νšŒμ›μ„ User둜 μ„€κ³„ν•˜μ˜€μŠ΅λ‹ˆλ‹€. μ΄λ•Œ, κ°œλ°œκ³Όμ •μ—μ„œ μ‚¬μš©ν–ˆλ˜ H2 DB의 μ˜ˆμ•½μ–΄μ™€ μΆ©λŒν•˜λŠ” λ¬Έμ œκ°€ λ°œμƒν•˜μ˜€μŠ΅λ‹ˆλ‹€.

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "insert into [*]user 
(id, created_at, deleted_at, last_modified_at, password, role, user_name) values 
(default, ?, ?, ?, ?, ?, ?)"; expected "identifier"; SQL statement:
insert into user (id, created_at, deleted_at, last_modified_at, password, role, user_name) values (default, ?, ?, ?, ?, ?, ?) [42001-214]

μœ„μ™€ 같은 μ—λŸ¬κ°€ λ°œμƒν•˜μ˜€κ³ , 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œ User → Users둜 ν…Œμ΄λΈ”λͺ…을 λ³€κ²½ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

@Tableμ–΄λ…Έν…Œμ΄μ…˜μ„ μ μš©ν•˜μ—¬ λ³€κ²½ν•˜μ˜€μŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 ν…Œμ΄λΈ”μ„ 섀계 ν•  λ•Œ μ˜¬λ°”λ₯Έ λͺ…칭을 μ •ν•˜λŠ” 것이 μ–Όλ§ˆλ‚˜ μ€‘μš”ν•œμ§€ μ•Œ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

Validation μ—λŸ¬ [λΈ”λ‘œκ·Έ 정리 보기]

@NotBlank
private long password;

μœ„μ™€ 같이 μž‘μ„±ν–ˆλ”λ‹ˆ μ—λŸ¬κ°€ λ°œμƒν•˜μ˜€μŠ΅λ‹ˆλ‹€. μ΄μœ λŠ” longνƒ€μž…, intνƒ€μž…λ“±μ˜ μ›μ‹œνƒ€μž…μ— λŒ€ν•΄μ„œλŠ” @NotBlank μ• λ„ˆν…Œμ΄μ…˜μ„ μ‚¬μš©ν• μˆ˜μ—†κ³  λ§Œμ•½ μœ νš¨μ„±κ²€μ‚¬κ°€ ν•„μš”ν•˜λ‹€λ©΄ @Min, @Maxλ“±μ˜ μ΅œμ†Œ, μ΅œλŒ€κ°’μ„ μ§€μ •ν•˜λŠ” λ°©μ‹μœΌλ‘œ μ‚¬μš©μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 μ‚¬μ†Œν•œ λΆ€λΆ„μ—μ„œλ„ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆλ‹€λŠ” 것을 μ•Œμ•˜μŠ΅λ‹ˆλ‹€. Dtoλ₯Ό μž‘μ„±ν• λ•Œ λΆ™μ—¬λ„£κΈ°λ₯Ό ν•˜μ˜€λŠ”λ° μ’€ 더 신경을 써야겠닀고 μƒκ°ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

CORS μ—λŸ¬

ν”„λ‘ νŠΈμ™€ μ—°λ™ν•˜μ—¬ ν…ŒμŠ€νŠΈλ₯Ό μ§„ν–‰ν•˜λŠ” κ³Όμ •μ—μ„œ 정말 λ§Žμ€ corsμ—λŸ¬κ°€ λ°œμƒν•˜μ˜€μŠ΅λ‹ˆλ‹€.

Untitled

setAllowedOrigins 와 setcredential ν•¨κ»˜ μ‚¬μš© λͺ» ν•˜λŠ” 것을 μ•Œμ•˜κ³ , 이λ₯Ό μ μš©ν•˜μ—¬ corsFilter λ„£μ–΄μ„œ testλŠ” μ„±κ³΅ν•˜μ˜€μŠ΅λ‹ˆλ‹€. 이외에도 거의 λͺ¨λ“  ν…ŒμŠ€νŠΈ 진행 μ‹œμ— Corsμ—λŸ¬κ°€ λ°œμƒν•˜μ˜€λŠ”λ°, λ°±μ—”λ“œλ„ 처음 ν˜‘μ—…μ„ μ§„ν–‰ν•˜λŠ” μƒν™©μ΄μ—ˆκ³ , ν”„λ‘ νŠΈλ„ 처음 ν˜‘μ—…μ„ 진행 ν•˜λ‹€ λ³΄λ‹ˆ μ–΄λ””κ°€ λ¬Έμ œμΈμ§€ μ •ν™•νžˆ νŒŒμ•…ν•  μˆ˜κ°€ μ—†μ–΄μ„œ μΌμ–΄λ‚˜λŠ” λ¬Έμ œκ°€ λŒ€λΆ€λΆ„ μ΄μ˜€μŠ΅λ‹ˆλ‹€. 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œ ν”„λ‘ νŠΈμ™€ 거의 날이 μƒˆλ„λ‘ ν•˜λ‚˜μ”© ν…ŒμŠ€νŠΈλ₯Ό 진행 ν•˜μ˜€κ³  κ²°κ΅­ 문제λ₯Ό ν•΄κ²°ν• μˆ˜μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό ν†΅ν•΄μ„œ 초보 κ°œλ°œμžλ“€μ΄ κ°€μž₯ μ• λ₯Ό λ¨ΉλŠ”λ‹€λŠ” Cors에 λŒ€ν•΄μ„œ ν•œλ²ˆ 더 μ•Œκ²Œ λ˜μ—ˆκ³ , μ–΄λ–€ μ‹μœΌλ‘œ ν•΄κ²°ν•΄μ•Ό ν•˜λŠ”μ§€, 그리고 μ–΄λŠ 뢀뢄을 μ§‘μ€‘ν•΄μ„œ 확인 ν•΄μ•Ό ν•˜λŠ”μ§€ μ•Œ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 특히 preflight μš”μ²­μ— λŒ€ν•΄μ„œ μžμ„Ένžˆ 곡뢀할 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

λ°˜μ‘ν˜•