728x90
반응형
  • 디자인 패턴은 코드를 잘 작성할 수 있도록 하는 지침서. 레시피라고 말할 수 있다.

생성 패턴

싱글톤 패턴 Singleton

  • 하나의 클래스 인스턴스를 전역에서 접근 가능하게 함
  • 따라서 해당 인스턴스가 한 번만 생성되도록 보장

팩토리 메서드 패턴 Factory Method

  • 객체를 생성하기 위한 인터페이스를 정의하고 서브 클래스에서 어떤 클래스를 인스턴스를 생성할지 결정하는 패턴

추상 팩토리 패턴 Abstract Factory

  • 관련된 객체들의 집합을 생성하는 인터페이스 제공
  • 구체적인 팩토리 클래스를 통해 객체 생성을 추상화하는 패턴

빌더 패턴 Builder

  • 복잡한 객체의 생성 과정을 단순화하고, 객체를 단계적으로 생성하며 구성하는 패턴

프로토타입 패턴 Prototype

  • 객체를 복제하여 새로운 객체를 생성하는 패턴
  • 기존 객체를 템플릿으로 사용
728x90
반응형
728x90
반응형

솔리드 (SOLID) 원칙

  • 솔리드 원칙은 코드를 올바르게 사용할 수 있게 하는 지침서이다
  • 여담으로 디자인패턴은 코드를 잘 만들 수 있게 하는 레시피이다.

단일 책임 원칙 (Single Responsiblity Principle; SRP)

  • 소프트웨어의 컴포넌트는 단 하나의 책임만을 가져야 한다.

개방 폐쇄 원칙 (Open Close Principles; OCP)

  • 확장에 대해선 열려 있어야 하고 수정에 대해선 닫겨 있어야 한다.

리츠코프 치환 원칙 (Liskov Substitution Principle; LSP)

  • 자식 클래스는 부모클래스에서 가능한 행위를 수행할 수 있어야 한다.

인터페이스 분리의 원칙 (Interface Segregation Principle; ISP)

  • 하나의 일반적인 인터페이스 보단 여러 개의 구체적인 인터페이스가 낫다.

*의존관계 역전 원칙 (Dependency Inversion Principle; DIP) *

  • 의존 관계를 맺을 때, 변화하기 쉬운것 보단 변화하기 어려운 것에 의존해야 한다.
728x90
반응형

'백엔드 Backend' 카테고리의 다른 글

[결합도/응집도] 결합도와 응집도란  (0) 2024.10.24
악성코드 종류  (0) 2024.10.16
비동기 Asynchronous 란?  (0) 2024.10.04
[백엔드] REST API 란?  (0) 2024.09.27
[백엔드] gRPC란  (3) 2024.09.26
728x90
반응형

CI / CD

  • CI (Continuous Integration): 지속적 통합
    • 코드에 대한 통합
    • 다수의 개발자들의 코드 베이스를 계속해서 통합한다는 의미
    • 즉 여러 개발자들의 코드를 빠르게 배포함을 의미
  • CD (Continuous Deployment): 지속적 배포
    • 코드 베이스를 사용자가 사용하는 환경에 코드 베이스 배포를 자동화하는 것
  • 즉 CI/CD는 여러명의 개발자들이 개발 환경을 통합하여 사용자가 사용하는 환경에 전달하는 모든 일련의 과정들을 자동화하는 것
    • 여기에는 코드 빌드, 테스트, 배포가 포함됨

젠킨스?

  • Java Runtime Environment에서 동작
    • 플러그인 사용하여 자동화 작업 파이프라인을 설계
    • 파이프라인 마저도 플러그인의 일부
  • Credentials 플러그인을 사용해서 민감정보를 보관

젠킨스 파이프라인

  • Section - 가장 큰 개념
    • Agent Section
      • 오케스트레이션 처럼 slave node에 일 처리 지정
    • Post Section
      • 스테이지가 끝난 이후의 결과에 따른 후속 조치
      • 즉 작업 결과에 따른 행동 조치
    • Stage Section - 카테고리
      • 어떠한 일을 처리할 것인지 stage를 정의
      • Dockerfile의 스테이지를 정의하는 것과 같음
    • Step Section - 카테고리 내부의 동작들
      • 한 스테이지 안에서의 단계
      • 여러 작업들 실행 가능

Declaratives

  • Environment, Stage, Options, Parameters, Triggers, When
  • 각 Stage 안에서 어떠한 일을 할 것인지 정의
  • Environment
    • 환경변수들 정의
  • Parameter
    • 파이프라인 실행시 파라미터를 받음
  • Triggers
    • 파이프라인이 실행되는 트리거 정의
    • 예시: 특정 브랜치에 머지가 감지되었을 때
  • When
    • 수행되는 조건문
    • 예시: 환경변수 BUILD_BRANCH가 dev일 때

예시

  • 깃허브 특정 레포 dev(개발)/main(운영) 브랜치에 머지 인식
    • 미리 Credentials에 등록해 둔 각각 환경에 따라 다른 환경 변수 로드
    • 각각 환경에 따른 이미지 명으로 도커 이미지 빌드
    • 개인 도커 레지스트리에 이미지 푸시
    • 각각 개발/운영 서버에 배포할 서비스 경로 생성
      • docker-compose.yml 파일 복사
      • 빌드하여 푸시한 이미지 가져와서 컨테이너 구동
// 브랜치별 배포 위치

def getDeployTargets(envName) {

targets = [:]



// dev 브랜치

targets['prod'] = [[

    COMPOSE_ENV: 'dev',

    SSH_MODE: 'KEYONLY',

    SSH_IP: '<Server IP>',

    SSH_KEY_ID: 'Key Id From Jenkins Credentials',

    COPY_DIR: '도커 컴포즈 파일 배포할 서버 상의 경로'

]]

    return targets[envName]
}



// 브랜치별 환경 정보

def getBuildBranch(branchName) {
    branches = [
        'origin/main': 'prod',
    ]

    return branches[branchName]
}



pipeline {
    agent any

    //환경변수
    environment {

        //브랜치 선택

        BUILD_BRANCH = getBuildBranch(env.GIT_BRANCH)

        // 도커 설정
        DOCKER_IMAGE = ''
        DOCKER_IMAGE_NAME = '빌드 할 도커 이미지 명'

        // Git, Docker private 레지스트리 로그인 정보 설정    
        GIT_KEY_ID = '깃허브 인증 SSH 키 ID - Credentials에서 관리;'
        REGISTRY_LOGIN_INFO_ID = 'donghquinn_registry'
    }



                        stages {

                            stage('체크아웃') {
                                steps {
                                    echo "작업 브랜치: ${env.GIT_BRANCH}"

                                    git branch: BUILD_BRANCH, credentialsId: GIT_KEY_ID, url: 'git@github.com:donghquinn/<레포 명>.git'

                            }

                        }



                        stage('도커 이미지 빌드') {
                            steps {
                                script {

                                    // 브랜치에 따라 이미지 이름 변경
                                    DOCKER_IMAGE = docker.build(DOCKER_IMAGE_NAME + '-' + BUILD_BRANCH)

                                }

                                echo "Built: ${DOCKER_IMAGE_NAME}-${BUILD_BRANCH}"

                            }
                        }



                        stage('도커 이미지 Push') {
                            steps {
                                script {
                                    // 개발서버 내부 Docker private 레지스트리에 업로드
                                    docker.withRegistry('https://registry.donghyuns.com', REGISTRY_LOGIN_INFO_ID) {

                                    DOCKER_IMAGE.push(env.BUILD_NUMBER)
                                    DOCKER_IMAGE.push('latest')
                                }

                            }
                            echo "Pushed: ${DOCKER_IMAGE_NAME}-${BUILD_BRANCH}:${env.BUILD_NUMBER}"

                            }

                        }



                        stage('도커 컨테이너 배포') {

                        steps {

                            script {

                                def deployTargets = getDeployTargets(BUILD_BRANCH)

                                def deployments = [:]



                                // 배포 타깃별로 병렬 배포

                                for (item in deployTargets) {

                                def target = item



                                deployments["TARGET-${BUILD_BRANCH}"] = {

                                def remote = [:]
                                remote.name = target.SSH_IP
                                remote.host = target.SSH_IP
                                remote.allowAnyHosts = true

                                if (target.SSH_MODE == 'KEYONLY') {

                                    withCredentials([

                                    // DOTENV 파일과 SSH KEY를 가져옴
                                    sshUserPrivateKey(credentialsId: target.SSH_KEY_ID, keyFileVariable: 'SSH_PRIVATE_KEY', usernameVariable: 'USERNAME')
                                    ]) {

                                    // 가져온 키로 ssh 정보 설정
                                    remote.user = USERNAME

                                    remote.identityFile = SSH_PRIVATE_KEY

                                    sshCommand remote: remote, command: """
                                        mkdir -p ${target.COPY_DIR}-${BUILD_BRANCH}/
                                    """

                                    // docker compose 파일 전송
                                    sshPut remote: remote, from: "docker-compose.${BUILD_BRANCH}.yml", into: "${target.COPY_DIR}-${BUILD_BRANCH}/docker-compose.yml", failOnError: 'true'

                                    // 각 상황에 맞는 .env.* 파일 전송

                                   // 각 상황에 맞는 .env.* 파일 전송
                                  sshPut remote: remote, from: DOTENV, into: "${target.COPY_DIR}/.env", failOnError: 'true'

                                    // 도커 이미지 Pull 및 재시작
                                    sshCommand remote: remote, command: """
                                        cd ${target.COPY_DIR}-${BUILD_BRANCH}/
                                        BUILD_BRANCH=${BUILD_BRANCH} docker compose pull
                                        BUILD_BRANCH=${BUILD_BRANCH} docker compose up -d
                                    """
                                }
                            }
                        }

                        parallel deployments

                    }

                }

            }

        }

    }

}
728x90
반응형
728x90
반응형

무중단 배포 전략이란 무엇일까? 각 전략에 대해 개인적 명칭을 붙여봤다.

무중단 배포란?

무중단 배포란 서비스의 중단 없이 새로운 버전을 배포하는 것을 의미한다. 이용자의 서비스 이용에 지장을 주지 않는 것과 동시에 새로운 버전을 배포하는 것이 핵심인 것이다.

이를 위해선 로드 밸런서와 두 대 이상의 서버가 필요하다.

Blue/Green 배포 - 단순 배포 전략?

이전 버전 서버와 새로운 버전 서버를 두고,
공통 로드 밸런서를 통해 새로운 버전을 배포하는 전략이다.

  • Blue 서버: 이전 환경 서버
  • Green 서버: 새로운 배포 환경

Blue/Green 전략

장점

트래픽을 새로운 버전쪽으로 옮기기 때문에 호환성 문제가 발생하지 않는다.

단점

실제 운영에 필요한 리소스보다 2배의 리소스를 확보해야 한다.(서버가 두 대이고, 일질적인 트래픽이 통하는 서버는 이전 환경이기 때문)

Rolling 전략 - 순차 배포 전략?

운영중인 복수개의 인스턴스들을 하나씩 돌아가며(Rolling) 로드 밸런서로부터 트래픽을 끊고 새로운 버전 배포를 하는 전략이다.
즉, 새로운 버전 배포가 완료가 되면 다시 로드 밸런서에 연결을 하고, 그 다음 인스턴스를 로드 밸런서로부터 끊고 새로운 버전을 배포하는 것을 반복하는 것이다.

장점

  • 많은 서버 자원을 배포하지 않아도 무중단 배포 가능
  • 인스턴스마다 차례로 돌아가며 배포를 진행하므로, 배포로 인한 위험이 줄어든다.

단점

  • 새 버전을 배포할 때마다 서비스 중인 인스턴스의 개수가 줄어, 서버 부담이 증가한다.
  • 배포가 진행되는 동안 새로운 버전과 이전 버전의 호환성 문제가 발생할 수 있다.

Canary 배포 - 위험 감지 전략?


Canary 전략

이전 버전과 새로운 버전이 동시에 가동되는 방식으로, 새 버전 인스턴스는 일부 사용자에게만 서비스 하는 방식이다.
새 버전이 정상적으로 작동함을 확인하면, 전체 트래픽을 새 버전으로 전환한다.
오류가 발생한다면, 일부 사용자에게만 발생하므로 오류 방지에 효과적이다.

참고 (개인적 의견)

Canary 전략이라는 이름이 붙은 이유는 탄광에서 위험 감지용으로 데려가던 것에서 유래한 것 같다.

장점

  • 사용자 테스트와 무중단 배포가 동시에 가능함
  • 새로운 버전으로 인한 위험을 감소시킬 수 있다.

단점

  • Rolling 전략과 마찬가지로 이전과 새로운 버전이 동시에 존재하므로 호환성 문제가 발생 가능하다.

참고 링크

728x90
반응형

'데브옵스 devOps > Server' 카테고리의 다른 글

[STANDALONE] Standalone 프로그램이란?  (1) 2024.12.26
[파일전송] Rsync  (0) 2024.12.11
728x90
반응형

_Async/Await_

 

비동기란 무엇일까?

비동기

비동기는 하나의 동작이 완료되는 것을 기다리지 않고, 동시에 다른 작업을 처리하는 방식이다.

 

자바스크립트는 싱글 스레드 언어이기 때문에 필수 불가결적으로 비동기 함수를 선택하게 되었다.

하나의 스레드를 가지고 다른 작업이 마칠때까지 대기해야 한다면, 작업이 너무나도 느려지기 때문이다.

비동기 처리를 지원하는 방식으로는 Promise와 async/await이 있다.

 

예시

비동기 함수는 에어프라이어에 음식 넣고 돌린 후, 다른 재료를 손질하면서 틈틈이 에어프라이어를 체크하는 것과 유사하다.

에어프라이어가 음식을 조리하는 것이 완료될 때 까지 기다리는 것이 아닌, 동시에 다른 작업을 진행하는 것이다.

 

동기

동기는 하나의 동작이 완료된 후에 다음 동작으로 실행하는 순차적 방식이다.

 

개인적인 헷갈림 정리

처음에 비동기와 동기의 개념을 반대로 생각하고 있었다.

오히려 동기를 "병렬 처리"와 개념적으로 혼동하고 있었던 것 같다.

 

동기는 "순차적", 비동기는 "동시에"라고 외워야 겠다.

 

참고 링크

- 주니어 웹 개발자가 알아야 할 "비동기 통신" (https://yozm.wishket.com/magazine/detail/1982/)

728x90
반응형

'백엔드 Backend' 카테고리의 다른 글

[결합도/응집도] 결합도와 응집도란  (0) 2024.10.24
악성코드 종류  (0) 2024.10.16
SOLID 원칙  (0) 2024.10.08
[백엔드] REST API 란?  (0) 2024.09.27
[백엔드] gRPC란  (3) 2024.09.26
728x90
반응형

계기

컨테이너를 구동하였을 때,
해당 컨테이너가 정상적으로 올라간 것으로 보였지만 로그를 확인하거나 exec 명령어로 컨테이너 내부에 접근하고자 했을 때 문제가 발생하고 있는 것을 확인한 적이 여러번 있었다.

때문에 컨테이너의 정상 여부(Health) 를 주기적으로 체크하며 모니터링 할 필요가 있다.

healthcheck 옵션

  • docker compose 설정
    • healthcheck 라는 설정을 함으로써 가능하다.
      • test: 헬스체크 시도 시에 실행할 동작을 정의한다. 단순 curl/wget 으로 요청을 날려볼 수 있고, CLI를 넣을 수도 있으며, 함수를 실행시킬 수도 있다.
      • interval: 말 그대로 체크 실행 주기를 의미한다.
      • timeout: 실행된 헬스체크 동작에 대한 리턴을 기다리는 시간(timeout)을 의미한다.
      • retries: 타임아웃이 걸려 체크 실패 시 재시도 횟수를 의미한다. 재시도까지 전부 실패하면 unhealthy 상태가 된다.
      • start_period: 컨테이너 구동을 기준으로, 헬스체크를 시작할 때까지의 시간을 의미한다. 처음 구동 시, 초기 세팅에 시간이 많이 걸리는 경우가 있기 때문
    • 상태값
      • 0 : healthy. 즉 건강한 상태이다.
      • 1 혹은 다른 숫자: unhealthy. 비정상적인 문제가 발생하고 있다.
services:
    app:
        expose:
            - ${APP_PORT}
        healthcheck:  
            // 헬스체크를 위해 실행할 함수
            test: curl --fail http://localhost:5000/ || exit 1  

            // REDIS 체크의 경우
            test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]

            // 체크 실행 주기
            interval: 40s 
            // 타임아웃 
            timeout: 30s  
            retries: 3  
            // 컨테이너 구동 후 체크 시작할 시점
            start_period: 60s
  • DockerFile 설정

    • 도커 파일 설정은 Dockerfile의 이미지 빌드 과정에 입력된다.
    • 이외 헬스 체크 주기 등의 옵션은 컨테이너 구동 시 입력한다.
    FROM asdcasdcas
    # ... 빌드 내용
    
    # 컨테이너에서 구동하는 어플리케이션의 /health 엔드포인트에 요청을 날리는 것이 헬스체크 방식이다.
    HEALTHCHECK CMD curl --fail http://localhost/health
    docker container run -d -p 8080:80 --health-interval 5s app_image/stable/latest

    결과

    • 헬스체크가 완료되면 아래처럼 보이게 된다.

주기 설정에 관하여

  • healthcheck 는 어찌 되었건 cpu 등 서버 리소스를 사용하기 때문에 적당한 주기(interval)로 실행시켜야 한다.
  • 또한 실제로 헬스체크 동작을 실행시켰을 때 받아올 수 있는 정도의 주기로 실행해야 한다.
    • 만약 헬스체크 대상 어플리케이션의 특정 함수 동작 주기가 1분인데, 10초마다 헬스체크를 한다면, 이는 자원 낭비일 것이다.
728x90
반응형
728x90
반응형

Golang은 뛰어난 동시성 지원이 장점이라고들 한다.

일반적으로 쓰레드를 활용하여 동시성 프로그래밍을 하지만, Golang은 고루틴 goroutine으로 가능하다.

 

고루틴 Goroutine

공시적인 설명으로는 경량 쓰레드이다. 실제 OS의 쓰레드를 사용하는 것이 아닌, golang의 런타임에서 관리되는 논리적 / 가상적 쓰레드이다.

 

사용법

go func() {

    // 대충 코드

  }()

이게 끝이다.

 

thread VS goroutine

1. 메모리 사용량

  • goroutine: 생성시 약 2KB의 스택 메모리 혹은 힙 메모리 공간만을 사용한다.
  • thread: 약 1MB 의 메모리 공간을 사용한다.
  • P.S. Guard Page: 쓰레드가 사용할 메모리 공간과 각 메모리 간의 경계 역할
  • 따라서 스레드 기반의 동시성 처리는 결국 메모리 부족 현상(OutOfMemory) 문제 발생할 수 있으므로, 스레드를 미리 생성해 재활용하는 형태가 될 수 있음.

 

2. 비용

  • goroutine: 런타임에서 논리적으로(하드웨어와 상관 없이) 생성되고 소거되기 때문에 가볍다.
  • thread: OS 에 스레드 생성을 요청해 사용하고 작업 완료 시 다시 OS에 반환해야 한다.
  • 따라서 쓰레드 생성시마다 OS에 요청해 생성하고 다시 반환하는 방식이 더 리소스 사용량이 많다.

 

3. Context Switching 비용

  • 하나의 스레드가 특정 작업 처리를 위해 사용(Blocking)된다면, 다른 쓰레드가 대신하여 처리하도록 스케쥴링 됨
  • goroutine: 3개의 레지스터(PC(Program Counter)), SP(Stack Pointer), DX)만 save/restore 작업을 함
  • thread: 스레드가 스케쥴링고 교체되는 동안 스케쥴러에서는 모든 레지스터들을 save/restore 해야함
  • 일반적으로 16개의 범용 레지스터, PC, SP, Segment 레지스터, 16개의 XMM레지스터, FP coprocessor state, 16개의 AVX 레지스터, 모든 MSR들 등 save/restore 작업을 진해해야함
  • 따라서 Context Switching 할 때 save/restore 해야하는 레지스터의 개수부터가 큰 차이가 남

 

결론

golang이 메모리 사용량과 쓰레드 생성과 작업처리에 있어서의 비용 측면에서 효율적이다.

 

마지막

goroutine의 동작 방식과 쓰레드 종류에 대해선 다음에 서술하고자 한다.

 

REFERENCE

- https://velog.io/@khsb2012/go-goroutine

 

 

728x90
반응형
728x90
반응형

_Event Loop_

이벤트 루프란 무엇일까?

 

Event Loop

이벤트 루프는 node.js의 기본적인 동작 방식이다.

Call Stack과 Callback Queue의 상태를 체크하여, Call Stack이 빈 상태가 되면 Callback Queue의 첫번째 콜백을 Call Stack으로 밀어넣는다. 이를 틱(Tick)이라 한다.

  • Call Stack: 코드가 실행될 때 쌓이는 곳. Stack 형태로 쌓임. 함수를 실행하고 값을 **return 하면 call Stack에서 제거**된다.
  • Callback Queue: 비동기적으로 실행된 콜백함수가 보관된 영역. eg. setTimeout에서 타이머 완료 후 실행되는 함수 등...

 

이벤트 루프는 총 6개의 단계를 가진다.

 

이벤트 단계

  • Timer 단계
    • 이벤트 루프의 시작 단계이다.
  • Pending(I/O) 콜백 단계
  • Idel, Prepare 단계
  • Poll 단계
  • Check 단계
  • Close 단계

 

microTaskQueue

이벤트 루프는 우선적으로 Microtask Queue를 먼저 확인한다.

MicroStack Queue에 콜백이 있다면 이를 먼저 Call Stack에 담는다.

 

 

이벤트 루프는 계속 공부를 더 해야겠다..

 

참고 링크

 

728x90
반응형

'백엔드 Backend > Nodejs' 카테고리의 다른 글

[NODEJS] Async/Await 란?  (0) 2024.10.23
[NODEJS] Promise란?  (0) 2024.10.22
Nodejs 란?  (1) 2024.09.30
728x90
반응형

_Node.js Logo_

Node.js가 무엇일까?

 

JS의 역사

자바스크립트는 브라우저에서 동적 페이지를 다루기 위해 시작된 언어였다.

그러나 브라우저에서 소스코드를 그대로 확인할 수 있었기 때문에 보안에 취약하다는 인식과 함께 프로그래밍 언어로써 인정을 받지 못하였다.

 

Node.JS

Node.JS는 자바스크립트 런타임이다. 즉 브라우저에서만 사용 가능했던 자바스크립트를 로컬에서 사용할 수 있게끔 해 주는 역할을 한다. 이 덕분에 자바스크립트는 프론트엔드 뿐만 아니라 백엔드에서 까지 활용할 수 있게 된 것이다. 거기에 V8엔진을 이용했기 때문에 성능 역시 인정을 받는다.

 

특징

싱글 스레드 방식

싱글 스레드는 작업에 사용하는 스레드를 하나 사용하는 방식이다. 그러나 엄밀히 말하면 개발자가 직접 스레드 풀을 관리하지 않고 node.js에 포함된 **libuv**스레드 풀을 관리하기 때문에 단일 스레드에서 동작하는 것처럼 이해하기 쉬운 코드를 작성할 수 있다.

추가로 웹 서버를 운용할 때는 프로세서(CPU)를 분산해서 관리하므로, 실질적으로는 여러 개의 코어에서 별개로 처리된다.

 

- P.S.

작업 요청이 동시에 발생했을 때 각 작업을 처리하기 위한 스레드를 만들고 할당하는 방식은 멀티 스레드인데, 여러 작업을 동시에 처리하기 때문에 빠르지만 자원을 관리하는 노력이 많이 들어가고 쓰레드의 개수만큼 메모리를 차지하므로 메모리 관리에 문제가 생길 수 있다.

 

non-blocking I/O

앞의 작업이 끝날때까지 기다리지 않고(non-blocking) 비동기로 처리한다. 즉, 입력은 하나의 스레드에서 받지만 순서대로 처리하지 않고 먼저 처리된 결과를 이벤트로 반환해줌을 의미한다.

728x90
반응형

'백엔드 Backend > Nodejs' 카테고리의 다른 글

[NODEJS] Async/Await 란?  (0) 2024.10.23
[NODEJS] Promise란?  (0) 2024.10.22
[NODEJS] 이벤트 루프란?  (0) 2024.10.01
728x90
반응형

_RESTful API_

백엔드 코드를 구현할 때 RESTful API 라는 개념이 자주 등장한다. 과연 이게 무엇일까

 

API란?

우선 API가 무엇인지 이해를 해야 할 것 같다.

API란 Application Programming Interface의 약자로, 다른 소프트웨어 시스템과 통신하기 위해 따라야 하는 규칙이다.

즉 데이터와 기능의 집합을 제공하여 프로그램 간 상호 작용을 통해, 정보를 교환 가능하도록 하는 것

 

HTTP URI

리소스를 고유하게 식별하는 것, URL과 보통 혼용되고 있다.

- ex. www.example.com/font/2 에서 2가 리소스

 

REST 란?

목표

  1. 컴포넌트 간 확장성을 가진 상호 연동성 확보
  2. 범용 인터페이스
  3. 각 컴포넌트들의 독립적인 배포
  4. 지연 감소, 보안 강화, 레거시 시스템을 인캡슐레이션 하는 중간 컴포넌트로의 역할

인캡슐레이션: 데이터에 헤더가 추가되는 과정. 즉, 한 프로그램에서 다른 프로그램으로 데이터를 전송할 때 데이터를 패키지화 하는 과정

 

개념

REST는 Representational State Transfer(REST)의 약자로, API 작동 방식에 대한 조건을 부과하는 소프트웨어 아키텍처 스타일이다.

네트워크 상에서 Client와 Server 사이의 통신 방신 중 하나로, 자원을 이름으로 구분하여 해당 자원의 상태를 주고 받는 모든 것을 의미하는 것이다.

HTTP Method (POST, GET, PUT, DELETE)를 통해 자원에 대한 CRUD Operation을 적용하는 것을 의미한다.

  • 자원: 해당 소프트웨어가 관리하는 모든 것
    • 문서, 그림, 데이터, 소프트웨어 자체 등...
  • 자원의 이름(자원의 표현)
    • 학생 정보가 자원일 때, 'student'를 자원의 표현으로 정한다.
  • 상태 전달
    • 데이터가 요청되는 시점의 자원의 상태를 전달
    • 일반적으로 JSON 혹은 XML 포맷을 통해 주고받는다.

 

CRUD Operation

  • Create: 생성 (POST)
  • Read: 조회 (GET)
  • Update: 수정 (PUT)
  • Delete: 삭제 (DELETE)
  • HEAD: header 정보 조회 (HEAD)

 

REST 특징

  • 클라이언트 / 서버 구조
    • 클라이언트는 유저 관련 처리, 서버는 REST API 제공으로 역할 분리
    • 때문에 서버와 클라이언트 간 의존성이 줄어든다.
  • REST Server: API 제공, 비즈니스 로직 처리 및 저장
    • Client: 사용자 인증 / Context(세션, 로그인 정보) 등을 직접 관리 및 책임
  • 무상태성 (Stateless)
    • 서버에서 어떤 작업을 하기 위해 상태 정보를 기억할 필요가 없고, 들어온 요청에 대해 처리만 해주면 된다.
  • 캐시 처리 가능 (Cacheable)
  • HTTP 웹 표준을 사용하기에, 기존 웹 인프라를 그대로 사용
  • 대량의 요청을 효율적으로 처리. 응답시간이 빨라지고 REST Server 트랜잭션이 발생하지 않기 때문에 전체 응답시간, 성능, 서버의 자원 이용률을 향상
  • 자체 표현 구조 (Self- Descriptiveness)
    • JSON을 이용한 메세지 포맷을 이용해 요청에 대한 이해가 쉽다
  • 계층화
    • 클라이언트와 서버가 분리되어 있기 때문에, 프록시 서버 / 암호화 계층 등 중간매체를 사용할 수 있음
  • 유니폼 인터페이스
    • HTTP 표준에만 따른다면 모든 플랫폼에서 사용 가능하며, 리소스 조작이 통일되기 때문에 특정 언어나 기술에 종속되지 않는다

 

RESTful API란?

REST 기반으로 API를 구현한 것을 RESTful 웹 서비스라고 지칭한다.

즉 REST 하게 자원으로 구분을 잘 한 API라는 의미

확장성과 재사용성을 높여 유지보수 및 운용의 편리성을 확보할 수 있다.

개인적으로 정의하자면, 통신의 표준화라고 생각한다.

 

규칙

  1. 슬레시(/)는 계층 관계를 나타내는데 사용한다.
  2. URI 마지막 문자로 슬레시(/)는 사용하지 않는다.
  3. 하이픈(-)은 URI 가독성을 높이는데 사용한다.
  4. 밑줄 (_)은 URI에 사용하지 않는다.
  5. URI는 최대한 소문자를 사용한다.
  6. 파일 확장자는 URI에 포함하지 않는다.

 

참고 링크

- REST, REST API, RESTful 특징 (https://hahahoho5915.tistory.com/54)

728x90
반응형

'백엔드 Backend' 카테고리의 다른 글

[결합도/응집도] 결합도와 응집도란  (0) 2024.10.24
악성코드 종류  (0) 2024.10.16
SOLID 원칙  (0) 2024.10.08
비동기 Asynchronous 란?  (0) 2024.10.04
[백엔드] gRPC란  (3) 2024.09.26

+ Recent posts