요구사항 API URI 설계
  회원 목록 조회
• 회원 조회
• 회원 등록
• 회원 수정
• 회원 삭제
  회원 목록 조회 /read-member-list
• 회원 조회 /read-member-by-id
• 회원 등록 /create-member
• 회원 수정 /update-member
• 회원 삭제 /delete-member

 

단적으로 위의 설계는 틀린 방식이다.

가장 중요한 것은 리소스 식별

 

API URI 고민

URI(Uniform Resource Identier)

 

• 리소스의 의미는 뭘까?

  • 회원을 등록하고 수정하고 조회하는게 리소스가 아니다!
  • 예) 미네랄을 캐라 -> 미네랄이 리소스
  • 회원이라는 개념 자체가 바로 리소스다.

• 리소스를 어떻게 식별하는게 좋을까?

  • 회원을 등록하고 수정하고 조회하는 것을 모두 배제
  • 회원이라는 리소스만 식별하면 된다. -> 회원 리소스를 URI에 매핑
요구사항 API URI 설계
  회원 목록 조회
• 회원 조회
• 회원 등록
• 회원 수정
• 회원 삭제
  회원 목록 조회 /members
• 회원 조회 /members/{id}
• 회원 등록 /members/{id}
• 회원 수정 /members/{id}
• 회원 삭제 /members/{id} 

참고: 계층 구조상 상위를 컬렉션으로 보고 복수단어 사용 권장(member -> members)

 

 

리소스와 행위 분리

가장 중요한 것은 리소스를 식별하는 것

 

• URI는 리소스만 식별!

• 리소스와 해당 리소스를 대상으로 하는 행위을 분리

  • 리소스: 회원
  • 행위: 조회, 등록, 삭제, 변경

• 리소스는 명사, 행위는 동사 (미네랄을 캐라)

• 행위(메서드)는 어떻게 구분?

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] Cookie  (1) 2024.12.28
[Net] MVC 패턴  (0) 2024.12.13
[Net] Rendering  (1) 2024.12.05
[Net] Servlet  (1) 2024.12.04
[Net] Web Application  (1) 2024.12.03

Annotation

📌 코드에 메타데이터를 추가할 수 있는 기능을 제공하며 주로 코드에 특별한 의미를 부여하거나, 컴파일러와 런타임에 특정 동작을 트리거하기 위해 사용된다.

  • 어노테이션은 코드에서 직접적인 로직 실행에 영향을 미치지 않지만, 코드의 의미를 설명하거나 추가적인 처리를 위해 사용됩니다.
  • "명함"를 생각하면 편하다. 이 명함은 "사람"에서 "프로그래머인 사람"이 된다. 사람이라는 정체성은 그대로이지만, 이 사람의 용도를 알 수 있다. 코드의 용도를 표시하며 실제로 컴파일러도 그 의미를 알지만 프로그램(사람) 자체에는 변화가 없다.

[1]  어노테이션 정의

  • 어노테이션은 @ 기호로 시작하며, 클래스, 메서드, 변수, 매개변수, 패키지 등에 추가할 수 있다.

[2]  내장 어노테이션

  • @Override
    • 메서드가 상위 클래스나 인터페이스의 메서드를 오버라이드하고 있음을 나타낸다.
      • 이때 컴파일러는 메서드가 실제로 오버라이드하고 있는지 확인한다.
  • @Deprecated
    • 해당 요소가 더 이상 사용되지 않음을 나타낸다.
    • 해당 어노테이션이 붙은 코드를 사용하면 컴파일 경고가 발생한다.
  • @SuppressWarnings
    • 컴파일러 경고를 억제한다.
      • 사용되지 않는 변수에 대한 경고를 무시할 수 있다.

[3]  사용자 정의 어노테이션

  • 개발자가 필요에 따라 직접 어노테이션을 정의할 수 있다.
  • 사용자 정의 어노테이션은 특정 메타데이터를 추가하거나,
  • AOP(Aspect-Oriented Programming) 같은 기술과 결합하여 다양한 기능을 구현할 수 있다.
    • AOP는 심화 주차에 배울 내용

 

Lombok

📌 Java에서 반복적인 코드를 줄여주는 라이브러리로, 코드의 가독성과 유지보수성을 높이는 데 도움이 됩니다. 주로 getter, setter, toString, equals, hashCode 메서드와 같은 보일러플레이트 코드를 자동으로 생성해줍니다.

 

[1]  Lombok 사용 시 장점:

  • 보일러플레이트 코드 감소: Lombok은 반복적인 코드(예: getter, setter, 생성자 등)를 자동으로 생성해 주어 코드가 간결해집니다.
  • 코드의 가독성 향상: 중요한 로직에 집중할 수 있어 코드가 더 깔끔하고 이해하기 쉬워집니다.
  • 생산성 향상: 반복적인 코드 작성에 소모되는 시간을 절약할 수 있습니다.

 

[2]   Lombok 사용 시 단점:

  • 자동 생성된 코드의 가시성 부족: Lombok은 컴파일 시 코드 생성이 이루어지기 때문에, IDE에서 코드가 어떻게 처리되는지 확인하기 어려운 경우가 있습니다.
  • 디버깅 어려움: Lombok이 생성한 코드는 실제로 파일에 존재하지 않기 때문에, 디버깅 시 자동으로 생성된 메서드를 추적하는 데 어려움이 있을 수 있습니다.

 

@Getter, @Setter

  • 클래스의 모든 필드에 대한 getter와 setter 메서드를 자동으로 생성한다.
  • 예시 코드
@Getter
@Setter
public class User {
    private String name;
    private int age;
  
  /** 아래 코드를 @Getter, @Setter 어노테이션이 생성해준다.
    public String getName() {
	    return name;
    }

    public void setName(String name) {
	    this.name = name;
    }
    
    public int getAge() {
	    return age;
    }

    public void setAge(int age) {
	    this.age = age;
    }
    **/
}

위 코드에서 getName(), setName(String name), getAge(), setAge(int age) 메서드가 자동으로 생성된다.



@ToString

  • 객체의 toString() 메서드를 자동으로 생성한다.
  • 기본적으로 클래스의 모든 필드를 포함하며, 특정 필드를 제외하거나 포맷을 지정할 수도 있다.
  • 예시코드
@ToString
public class User {
    private String name;
    private int age;
}
  • toString() 메서드는 객체를 String으로 변환해주는 역할을 수행한다.

@EqualsAndHashCode

  • equals()와 hashCode() 메서드를 자동으로 생성한다.
  • 객체의 동일성과 해시 코드를 정의하는데 사용된다.
  • 예시 코드
@EqualsAndHashCode
public class User {
    private String name;
    private int age;
}

 


 

@NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor

  • 기본 생성자를 생성한다.
  • 모든 필드를 매개변수로 하는 생성자를 생성한다.
  • 필수(final) 필드만을 매개변수로 하는 생성자를 자동으로 생성한다.
  • 예시 코드
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private int age;
}

 

@Data

  • @Getter, @Setter, @ToString, @EqualsAndHashCode,@RequiredArgsConstructor를 한꺼번에 적용하는 어노테이션이다.
  • 주로 테스트 용도로 사용한다.
  • 예시 코드
@Data
public class User {
    private String name;
    private int age;
}

@Builder

  • 빌더 패턴을 적용해 객체를 생성할 수 있게 합니다. 복잡한 객체 생성에 유용하며, 필드 이름을 명시적으로 지정하면서 객체를 생성할 수 있다.
  • 예시 코드
@Builder
public class User {
    private String name;
    private int age;
}
  • 사용 예시
User user = User.builder()
                .name("John")
                .age(30)
                .build();

@Slf4j

  • 클래스에 로그를 남기기 위한 Logger 객체를 자동으로 생성한다.
  • 예시 코드
@Slf4j
public class UserService {
    public void logMessage() {
        log.info("This is a log message");
    }
}

 

Framework

📌 프레임워크는 특정 프로그래밍 작업을 수행하기 위한 기반 구조를 제공하는 도구입니다. 예를 들어, 웹 애플리케이션 개발을 위한 Spring이나 Django와 같은 프레임워크는 애플리케이션 아키텍처구조를 정의하고, 개발자가 해당 구조 내에서 작업할 수 있도록 도와줍니다.

  • 프레임워크는 frame(틀) work(일하다)의 합성어로 일하기 위한 틀을 제공한다. 개발자는 해당 틀에서 일을 해야 한다.
  • 라이브러리가 도화지라면 프레임워크는 채색북과 같다. 둘다 그림을 완성시키는 도구이지만, 도화지는 완전히 자유로운 디자인을 할 수 있고 채색북은 자유롭지는 못하지만 편하게 그림을 완성시킬 수 있다.

 

[1] 프레임워크의 주요 특징:

  • 구조 제공: 프레임워크는 애플리케이션 개발의 기본 뼈대를 제공합니다. 예를 들어, 어떤 파일을 어디에 두고, 어떻게 코드를 구성할지에 대한 규칙을 제시합니다.
  • 규칙과 흐름: 프레임워크는 개발자가 따를 일정한 흐름을 정의합니다. 즉, 개발자가 애플리케이션을 어떻게 구조화할지에 대한 가이드라인을 제공합니다.
  • 확장성: 프레임워크는 애플리케이션을 개발하는 데 있어 기능을 추가하거나 수정할 수 있는 방법을 제공합니다. 그러나 기본적으로는 프레임워크 내에서 정해진 규칙을 따라야 합니다.
  • 재사용성: 프레임워크는 많은 기능을 미리 구현해두어, 개발자는 이러한 기능을 재사용할 수 있습니다. 예를 들어, 데이터베이스 연결, 보안 관리, 사용자 인증 등이 미리 구현되어 있는 경우가 많습니다.

[2] 프레임워크의 예시:

  • 웹 개발 프레임워크:
    • Spring Framework (Java): 웹 애플리케이션을 만들 때 필요한 기본 구조와 규칙을 제공합니다. Spring은 의존성 주입, AOP, 보안, 데이터베이스 연동 등 여러 기능을 제공합니다.
    • Django (Python): Python으로 웹 애플리케이션을 개발할 때 사용하는 프레임워크로, 기본적인 웹 애플리케이션의 구조와 URL 처리, 데이터베이스 연동 등의 기능을 제공합니다.
    • Ruby on Rails (Ruby): Ruby 언어로 웹 애플리케이션을 빠르게 개발할 수 있도록 도와주는 프레임워크입니다. RESTful 방식의 API 설계와 모델-뷰-컨트롤러(MVC) 아키텍처를 따릅니다.
  • 모바일 앱 개발 프레임워크:
    • React Native: JavaScript를 사용하여 iOS와 Android에서 실행되는 네이티브 앱을 개발할 수 있게 해주는 프레임워크입니다.
    • Flutter: Google에서 만든 프레임워크로, Dart 언어를 사용해 크로스 플랫폼 애플리케이션을 개발할 수 있습니다.

[3]  장점

  • 개발 프로젝트에 일관된 구조를 제공하여 코드의 일관성과 가독성을 높여주며 팀 협업이 편해진다.
  • 기본적으로 필요한 기능과 도구를 제공하여 개발자들이 핵심 비즈니스 로직에 집중할 수 있다.
  • 보안 관련 기능을 기본적으로 제공하여, 보안 취약점을 방지하는 데 도움을 준다.
  • 통합된 테스트 환경과 도구를 제공하여 테스트를 쉽게 작성하고 실행할 수 있다.
  • 인기 있는 프레임워크는 방대한 커뮤니티 지원을 받으며, 다양한 문서를 활용할 수 있다. 

[4]  단점

  • 프레임워크는 굉장히 복잡한 구조를 가지기 때문에, 처음 익히는 데 시간이 많이 소요된다.
  • 프레임워크의 새로운 버전이 기존 코드와 호환되지 않을 수 있다.
  • 정해진 규칙과 구조를 따르게 강제하여 자유롭게 변경하기 어려울 수 있다.

 

 

Library

📌 특정 기능을 수행하는 코드의 모음으로, 개발자가 필요할 때 그 기능을 호출하여 사용할 수 있는 도구입니다. 라이브러리는 애플리케이션의 흐름을 제어하지 않으며, 개발자가 원하는 기능만 골라서 사용할 수 있습니다. 즉, 라이브러리는 필요한 도구를 제공하지만, 애플리케이션의 전체적인 흐름은 개발자가 주도합니다.

 

[1] 라이브러리의 주요 특징:

  • 선택적 사용: 라이브러리는 개발자가 필요한 기능을 원할 때 호출해서 사용할 수 있습니다. 개발자가 전체적인 흐름을 제어하고, 필요한 기능만 사용할 수 있습니다.
  • 재사용성: 특정 기능을 여러 번 사용할 수 있도록 기능을 모듈화하여 제공합니다. 예를 들어, 수학 계산, 문자열 처리, HTTP 요청 보내기 등의 기능을 쉽게 사용할 수 있습니다.
  • 독립적: 라이브러리는 보통 독립적으로 동작하며, 다른 라이브러리나 애플리케이션에 종속되지 않습니다.

[2] 라이브러리의 예시:

  • JavaScript 라이브러리:
    • jQuery: HTML 문서를 다루고, 이벤트를 처리하며, AJAX 요청을 보내는 등의 기능을 쉽게 사용할 수 있도록 도와주는 JavaScript 라이브러리입니다. jQuery를 사용하면 DOM 조작을 더 간단히 할 수 있습니다.
    • Lodash: 배열, 객체, 함수 등의 데이터를 쉽게 다룰 수 있는 JavaScript 유틸리티 라이브러리입니다. 반복적인 코드 작성을 줄여주고, 다양한 유틸리티 함수들을 제공합니다.
  • Python 라이브러리:
    • NumPy: 수치 계산을 위한 Python 라이브러리로, 다차원 배열행렬 연산을 지원하여 과학적 계산을 손쉽게 할 수 있습니다.
    • Pandas: 데이터를 다루고 분석하는 데 유용한 라이브러리로, 데이터 프레임(DataFrame) 구조를 사용하여 데이터 처리 및 분석을 쉽게 합니다.
  • Java 라이브러리:
    • Apache Commons: 다양한 유틸리티 기능을 제공하는 Java 라이브러리로, 문자열 처리, 파일 입출력 등 여러 가지 기능을 간편하게 사용할 수 있습니다.
    • Google Guava: Java에서 컬렉션, 캐시, 문자열 처리 등을 편리하게 처리할 수 있도록 돕는 라이브러리입니다.

[3] 라이브러리 사용의 장점:

  • 빠른 개발: 이미 구현된 기능을 가져다 쓸 수 있어 개발 속도가 빨라집니다.
  • 모듈화: 필요한 기능만 가져다 쓰므로 코드가 깔끔하고 모듈화가 잘 됩니다.
  • 다양한 기능: 특정 작업을 처리하는 다양한 라이브러리가 존재하여, 원하는 기능을 쉽게 찾아 사용할 수 있습니다.

 

[4] 라이브러리 사용의 단점:

  • 라이브러리가 업데이트 되거나 지원이 중단될 경우 문제가 발생할 수 있다.
  • 버전 호환성 문제로 인해 다른 라이브러리나 기존 코드와 충돌이 발생할 수 있습니다.
    • 생각보다 빈번하게 발생하는 문제
  • 불필요한 기능을 포함한 라이브러리를 사용하면 비효율적이다.
  • 라이브러리의 내부 구현을 직접 수정하기 어려워, 특정 요구 사항에 맞게 조정하기 힘들 수 있다.

 

라이브러리와 프레임워크의 차이점을 표로 정리하면 다음과 같습니다:

  라이브러리 프레임워크
제어의 흐름 개발자가 흐름을 제어하고, 필요한 기능을 호출 프레임워크가 흐름을 제어하고, 개발자는 그 안에서 작업
사용 방식 필요한 기능을 선택하여 사용 전체적인 구조를 따르고, 규칙에 맞춰 작업
의존성 독립적이며, 필요할 때마다 호출하여 사용 애플리케이션 구조에 강하게 의존
구조 제공 여부 특정 기능을 제공하지만, 전체 구조는 제공하지 않음 전체적인 애플리케이션 구조를 제공
사용 예 특정 기능만 필요할 때 (예: jQuery, Lodash) 애플리케이션 개발 시 기본적인 구조가 필요한 경우 (예: Spring, Django)
개발자 역할 개발자가 원하는 기능을 필요에 맞게 선택하고 적용 개발자는 프레임워크의 규칙에 따라 작업
예시 jQuery, NumPy, Google Maps API Spring, Django, Ruby on Rails

요약:

  • 라이브러리는 개발자가 필요한 기능을 선택하여 사용하는 도구이고, 흐름 제어는 개발자에게 있습니다.
  • 프레임워크는 애플리케이션의 구조와 흐름을 제공하며 라이브러리를 이미 포함하고 있습니다. 흐름 제어는 프레임워크가 담당합니다.

Rendering

📌 웹 애플리케이션에서 콘텐츠를 화면에 표시하는 과정을 의미합니다. 이 과정은 주로 웹 브라우저에서 일어나며, HTML, CSS, JavaScript 코드가 결합되어 최종적으로 사용자가 볼 수 있는 페이지로 변환됩니다.

 

[1]  렌더링의 주요 과정

  1. HTML 파싱 (Parsing):
    • 브라우저가 웹 페이지를 로드하면 먼저 HTML 파일을 받아들입니다. 이 HTML 파일은 **DOM(Document Object Model)**으로 변환됩니다. DOM은 웹 페이지의 구조를 트리 형태로 나타내는 객체입니다.
  2. CSS 파싱:
    • HTML이 파싱되면서 CSS 파일도 함께 로드됩니다. CSS 파일은 페이지의 스타일을 정의하며, 이 스타일은 HTML 요소에 적용되어 화면에 표시됩니다. CSS는 **CSSOM(CSS Object Model)**이라는 객체 모델로 변환됩니다.
  3. 렌더 트리 생성:
    • DOM과 CSSOM이 결합되어 **렌더 트리(Render Tree)**가 만들어집니다. 렌더 트리는 화면에 실제로 표시할 요소들만 포함됩니다. 예를 들어, display: none이 설정된 요소는 렌더 트리에 포함되지 않습니다.
  4. 레이아웃(Layout):
    • 렌더 트리가 만들어지면, 각 요소의 정확한 위치와 크기를 계산하는 레이아웃 단계가 진행됩니다. 이 과정에서 각 요소가 페이지 상에서 차지할 공간을 결정합니다.
  5. 페인팅(Painting):
    • 레이아웃이 완료되면 각 요소를 실제 화면에 그리는 페인팅 단계가 시작됩니다. 이 단계에서는 색상, 텍스트, 이미지 등 시각적 요소가 화면에 그려집니다.
  6. 합성(Compositing):
    • 페이지가 여러 레이어로 구성된 경우, 각 레이어가 화면에 어떻게 합성될지를 결정하는 단계입니다. 예를 들어, 애니메이션이나 CSS 트랜지션을 포함한 요소들이 각기 다른 레이어에 배치될 수 있습니다.

[2]  렌더링의 종류

  1. 서버 사이드 렌더링 (SSR, Server-Side Rendering):
    • 서버에서 HTML을 렌더링하고 클라이언트에게 전달하는 방식입니다. 클라이언트는 서버에서 이미 완성된 HTML을 받게 되므로 페이지가 더 빨리 렌더링됩니다. 검색 엔진 최적화(SEO)에도 유리합니다.
  2. 클라이언트 사이드 렌더링 (CSR, Client-Side Rendering):
    • JavaScript가 클라이언트에서 HTML을 렌더링하는 방식입니다. 초기 로딩 시 서버에서 최소한의 HTML만 제공하고, 클라이언트에서 JavaScript가 실행되어 동적으로 콘텐츠를 로드하고 표시합니다.
  3. 하이브리드 렌더링:
    • SSR과 CSR을 결합한 방식으로, 초기 페이지를 서버에서 렌더링하고, 이후 동적인 콘텐츠는 클라이언트에서 렌더링하는 방식입니다. React의 Hydration 기법이 대표적인 예입니다.

[3]  렌더링 성능 최적화

  1. Lazy Loading (지연 로딩):
    • 페이지의 필요한 부분만 먼저 렌더링하고, 나머지 부분은 사용자가 필요할 때 로드하는 방식입니다. 이는 초기 로딩 시간을 줄이는 데 유용합니다.
  2. Critical CSS:
    • 페이지 렌더링에 필요한 최소한의 CSS만 먼저 로드하고, 나머지는 비동기적으로 로드하는 방식입니다. 이렇게 하면 페이지 렌더링 속도가 빨라집니다.
  3. Render Blocking 리소스 최적화:
    • JavaScript나 CSS가 페이지 렌더링을 차단하지 않도록 비동기 로딩하거나 async 또는 defer 속성을 활용하는 방식입니다.
  4. Request Animation Frame (RAF):
    • JavaScript 애니메이션을 최적화하는 기법으로, 화면 리프레시 주기와 맞추어 애니메이션을 실행하여 성능을 최적화합니다.

[4]  렌더링과 관련된 주요 용어

  • Reflow: DOM 요소의 크기나 위치가 변경될 때 레이아웃을 다시 계산하는 과정입니다. 이는 성능에 큰 영향을 줄 수 있습니다.
  • Repaint: 요소의 스타일이 변경되어 화면을 다시 그리는 과정입니다. 스타일만 변경되었을 때는 레이아웃을 재계산하지 않고 화면을 다시 그리기만 합니다.

[5]  렌더링 과정에서의 최적화

  • 렌더링 차단 리소스 최소화: CSS나 JavaScript와 같은 리소스가 렌더링을 차단하지 않도록 최적화합니다.
  • 이미지 최적화: 이미지를 압축하거나 적절한 포맷을 사용하여 로딩 시간을 줄이고 렌더링 성능을 향상시킵니다.
  • DOM 최소화: DOM의 크기를 최소화하고, 불필요한 DOM 업데이트를 피하는 것이 렌더링 성능에 도움이 됩니다.

 

 

SSR(Server Side Rendering)

📌 웹 애플리케이션에서 서버가 HTML을 생성하여 클라이언트에 전달하는 방식입니다. 즉, 클라이언트가 웹 페이지를 요청하면, 서버에서 HTML을 미리 렌더링하고 완성된 페이지를 클라이언트에 전달하는 방식입니다.

 

  1. 서버(WAS)에 HTML을 요청한다.
  2. 서버(WAS)에서 로직을 거친 후 DB를 조회한다.
  3. 조회 결과를 기반으로 HTML을 동적으로 생성한다.
  4. 생성된 HTML을 응답한다.

 

[1]  SSR의 개념

  • **서버 사이드 렌더링 (SSR)**은 클라이언트가 웹 페이지를 요청할 때, 서버에서 HTML을 미리 렌더링하여 클라이언트에게 전달하는 방식입니다.
  • 클라이언트는 서버에서 전달받은 완성된 HTML을 바로 표시하며, 이후 JavaScript가 추가적으로 실행되어 페이지를 동적으로 업데이트하는 방식으로 동작합니다.

[2]  SSR의 작동 원리

  1. 클라이언트 요청: 사용자가 웹 브라우저에서 페이지를 요청합니다.
  2. 서버 렌더링: 서버는 요청된 URL에 해당하는 페이지를 서버 측에서 미리 렌더링하여 완성된 HTML을 생성합니다.
  3. HTML 전달: 생성된 HTML 페이지를 클라이언트로 전달합니다.
  4. 브라우저 표시: 클라이언트는 서버로부터 받은 HTML을 즉시 렌더링하고 화면에 표시합니다.
  5. JavaScript 실행: 페이지가 로드된 후, 클라이언트는 JavaScript를 실행하여 페이지에 동적인 요소를 추가하고, 인터랙티브한 기능을 활성화합니다.

[3]  SSR의 장점

  1. 빠른 초기 로딩:
    • 서버에서 미리 렌더링된 HTML을 클라이언트에 전달하기 때문에, 초기 페이지 로딩 속도가 매우 빠릅니다. 사용자가 페이지를 요청할 때 빠르게 내용을 볼 수 있습니다.
  2. SEO(검색 엔진 최적화):
    • 서버에서 완성된 HTML을 제공하므로 검색 엔진 크롤러가 페이지의 콘텐츠를 쉽게 읽을 수 있습니다. 이는 SEO에 유리한 점으로, 검색 엔진에서 페이지를 더 잘 인식하고 인덱싱할 수 있습니다.
  3. 더 나은 사용자 경험:
    • 초기 페이지가 빠르게 렌더링되기 때문에, 사용자는 페이지를 더 빨리 볼 수 있으며, **사용자 경험(UX)**이 향상됩니다.
  4. 프로그레시브 웹 앱(PWA):
    • SSR은 클라이언트가 JavaScript를 사용할 수 없더라도 서버에서 완전한 페이지를 렌더링하여 사용자에게 표시할 수 있기 때문에, **PWA(프로그레시브 웹 앱)**에도 유용합니다.

[4]  SSR의 단점

  1. 서버 부하:
    • 모든 페이지 렌더링을 서버에서 처리해야 하므로, 서버에 부하가 증가할 수 있습니다. 특히 트래픽이 많은 웹 애플리케이션에서는 서버의 성능 저하가 발생할 수 있습니다.
  2. 느린 동적 인터페이스:
    • 초기 렌더링 후 동적인 기능을 추가하기 위해 JavaScript가 로드되고 실행되어야 하므로, 초기 화면은 빠르게 렌더링되지만 상호작용성은 JavaScript가 실행된 후에 활성화됩니다.
  3. 상태 관리:
    • 서버 측에서 렌더링된 페이지는 클라이언트의 상태를 유지하는 데 어려움이 있을 수 있습니다. 서버와 클라이언트 간의 상태 동기화가 필요할 수 있습니다.

[5]  SSR 사용 사례

  1. 블로그 및 뉴스 사이트:
    • 검색 엔진 최적화(SEO)가 중요한 블로그나 뉴스 사이트에서는 SSR을 사용하여 빠르게 검색 결과에 노출되도록 할 수 있습니다.
  2. 쇼핑몰 사이트:
    • 초기 제품 정보나 카테고리 정보가 서버에서 렌더링된 HTML로 빠르게 로드되고, JavaScript로 동적 요소가 추가되는 쇼핑몰 사이트에서도 유용합니다.
  3. 대규모 웹 애플리케이션:
    • 초기 페이지 로딩 속도를 빠르게 하고, 사용자의 반응을 더 잘 처리하기 위해 SSR을 사용하는 대규모 웹 애플리케이션도 많습니다.

[6]  SSR vs CSR (Client-Side Rendering) 차이점

항목SSR (Server-Side Rendering)CSR (Client-Side Rendering)

페이지 렌더링 서버에서 미리 렌더링 후 HTML 전달 클라이언트에서 JavaScript가 실행되어 렌더링
초기 로딩 속도 빠른 초기 로딩 느릴 수 있음 (JavaScript 로딩 후 렌더링 시작)
SEO 서버에서 완성된 HTML을 제공하므로 SEO에 유리 클라이언트에서 JavaScript로 렌더링되므로 SEO에 불리
서버 부하 서버 부하가 크고, 많은 트래픽을 처리하기 어려울 수 있음 서버 부하가 적고, 클라이언트에서 처리되므로 서버 부하가 적음
동적 기능 서버 측에서 HTML이 이미 렌더링되어 동적 기능이 지연될 수 있음 JavaScript가 실행된 후 동적 기능을 즉시 활성화

 

SEO(Search Engine Optimization)

  • 검색 엔진에서 상위에 노출될 수 있도록 최적화하는 과정을 말한다.

 

CSR(Client Side Rendering)

📌 웹 애플리케이션에서 클라이언트(브라우저)가 웹 페이지를 렌더링하는 방식입니다. 서버는 최소한의 HTML을 클라이언트에 전달하고, 이후 JavaScript가 클라이언트 측에서 실행되어 콘텐츠를 동적으로 렌더링하는 방식입니다.

  1. HTML을 요청한다. 비어있는 HTML을 응답받는다. JS가 존재하는 주소 링크를 응답한다.
  2. 자바스크립트(클라이언트 로직, 렌더링 포함)를 요청한다.
  3. HTTP API 요청을 하고 화면에 필요한 데이터를 JSON 형태(JSON이 아니어도됨)로 응답받는다.
  4. 응답받은 JSON 데이터로 HTML을 동적으로 그린다.

 

[1]  CSR의 작동 원리

  1. 클라이언트 요청:
    • 사용자가 웹 브라우저에서 특정 URL을 요청하면, 서버는 최소한의 HTML 파일을 클라이언트에 전달합니다. 이 HTML은 보통 페이지의 뼈대(구조)만 포함하고 있으며, 실제 콘텐츠는 포함되지 않습니다.
  2. JavaScript 로드:
    • 클라이언트가 받은 HTML은 주로 JavaScript 파일을 불러오는 역할을 합니다. JavaScript는 페이지를 동적으로 렌더링하는 데 필요한 데이터와 로직을 처리합니다.
  3. API 호출:
    • JavaScript는 서버와 API 요청을 통해 데이터를 받아옵니다. 이 데이터는 JSON 형식으로 전달되며, JavaScript는 이 데이터를 바탕으로 페이지를 동적으로 생성합니다.
  4. 동적 렌더링:
    • 받은 데이터를 바탕으로 JavaScript가 HTML을 동적으로 생성하여 화면에 표시합니다. 클라이언트에서 페이지 렌더링이 이루어지므로, 서버는 추가적인 렌더링 작업을 수행하지 않습니다.
  5. 인터랙티브한 페이지:
    • JavaScript는 페이지에서 사용자의 상호작용을 처리하며, 페이지 내에서 동적 콘텐츠 갱신이나 애니메이션 등을 실시간으로 구현합니다.

[2]  CSR의 장점

  1. 서버 부하 감소:
    • 클라이언트 측에서 렌더링을 처리하므로 서버 부하가 감소합니다. 서버는 페이지의 최소한의 HTML만 보내면 되며, 클라이언트에서 나머지 작업을 처리합니다.
  2. 빠른 사용자 경험:
    • 초기 페이지 로딩 후, 페이지 내의 다른 콘텐츠를 동적으로 로드할 수 있습니다. 이는 사용자가 페이지 간 이동을 할 때 빠른 응답 시간을 제공합니다.
  3. 인터랙티브한 경험:
    • CSR은 JavaScript를 사용하여 동적이고 인터랙티브한 사용자 경험을 제공합니다. 버튼 클릭, 폼 제출 등의 인터랙션에 즉각적으로 반응할 수 있습니다.
  4. 클라이언트 측 상태 관리:
    • CSR에서는 클라이언트 측에서 애플리케이션의 상태를 관리할 수 있어, 페이지를 새로고침하지 않고도 실시간으로 UI 업데이트가 가능합니다.
  5. 애플리케이션 로딩 후 빠른 탐색:
    • 한 번 페이지가 로드되면, 후속 페이지들은 빠르게 로드되고 전환됩니다. 이는 **SPA(Single Page Application)**에서 더욱 두드러지며, 페이지를 새로고침하지 않고도 새로운 콘텐츠를 동적으로 로드합니다.

[3]  CSR의 단점

  1. 초기 로딩 속도:
    • CSR은 클라이언트에서 페이지를 렌더링하므로, 초기 페이지 로딩 시에 JavaScript 파일과 데이터를 모두 로드해야 합니다. 이로 인해 초기 로딩 속도가 상대적으로 느릴 수 있습니다.
  2. SEO (검색 엔진 최적화):
    • CSR에서는 JavaScript로 동적으로 콘텐츠를 렌더링하므로, 검색 엔진 크롤러가 자바스크립트로 렌더링된 콘텐츠를 제대로 인식하지 못할 수 있습니다. 이는 SEO에 불리할 수 있습니다. 최근에는 **서버 사이드 렌더링(SSR)**과 결합하거나 프리렌더링을 통해 이 문제를 해결하기도 합니다.
  3. 자바스크립트 의존성:
    • CSR 방식은 JavaScript가 제대로 실행되지 않으면 페이지가 제대로 표시되지 않거나, 애플리케이션이 기능을 제대로 수행하지 않을 수 있습니다. 사용자가 JavaScript를 비활성화한 경우 페이지가 정상적으로 동작하지 않을 수 있습니다.
  4. 클라이언트 성능 문제:
    • 클라이언트(브라우저)가 많은 작업을 처리하므로, 저사양 기기에서는 성능 저하가 발생할 수 있습니다. 특히, 복잡한 애플리케이션에서는 클라이언트가 느려질 수 있습니다.

[4]  CSR과 SSR의 차이점

항목CSR (Client-Side Rendering)SSR (Server-Side Rendering)

렌더링 위치 클라이언트(브라우저)에서 렌더링 서버에서 렌더링 후 클라이언트로 전달
초기 로딩 시간 상대적으로 느릴 수 있음 (JavaScript 로딩이 필요) 빠름 (서버에서 HTML을 미리 렌더링)
SEO SEO에 불리 (검색 엔진 크롤러가 동적 콘텐츠를 제대로 크롤링 못할 수 있음) SEO에 유리 (완성된 HTML을 서버에서 제공)
서버 부하 서버 부하가 적음 (서버는 기본 HTML만 전달) 서버 부하가 클 수 있음 (매 요청마다 페이지를 렌더링)
사용자 경험 더 동적이고 인터랙티브함, 페이지 간 전환 빠름 초기 페이지 로딩이 빠르지만, 이후 전환에 있어 느릴 수 있음
상태 관리 클라이언트에서 상태를 관리 (SPA) 서버에서 상태를 관리 (매 요청마다 새로 렌더링)

[5]  CSR을 사용하는 주요 기술 및 라이브러리

  • React: 동적이고 인터랙티브한 UI를 구성하는 데 사용되는 라이브러리입니다. React는 **SPA (Single Page Application)**을 만들 때 주로 사용됩니다.
  • Vue.js: React와 유사하게 클라이언트 측에서 렌더링되는 웹 애플리케이션을 만들 때 사용하는 JavaScript 프레임워크입니다.
  • Angular: 구글에서 개발한 프레임워크로, CSR을 기반으로 한 대규모 웹 애플리케이션을 구축하는 데 사용됩니다.
  • Next.js: React 기반의 SSR 및 CSR을 지원하는 프레임워크입니다. CSR이 기본이며, SSR도 선택적으로 사용할 수 있습니다.

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] MVC 패턴  (0) 2024.12.13
[Net] API 설계  (0) 2024.12.12
[Net] Servlet  (1) 2024.12.04
[Net] Web Application  (1) 2024.12.03
[Net] Restful API  (1) 2024.12.02

Servlet

📌 Servlet자바(Java) 언어로 작성된 서버 측 프로그램으로, 주로 웹 애플리케이션에서 클라이언트의 요청을 처리하고 동적으로 응답을 생성하는 데 사용됩니다.

  • JAVA에서 Sevlet은 HttpServlet 클래스를 상속받아 구현되며, Java EE (Enterprise Edition)**의 중요한 구성 요소로, 웹 서버나 웹 애플리케이션 서버에서 실행되며, HTTP 요청을 처리하는 동적 웹 애플리케이션을 만들 수 있게 해줍니다.
  • Servlet은 HTTP 프로토콜 기반 요청(Request) 및 응답(Response)을 처리하는데 사용된다. 

 

[1] Servlet의 주요 기능

  1. HTTP 요청 처리
    • 클라이언트의 요청(GET, POST 등)을 받아들이고, 이를 처리하여 적절한 응답을 생성합니다.
    • 웹 애플리케이션에서 사용자 요청에 따라 동적인 콘텐츠를 반환할 때 사용됩니다.
  2. 동적 콘텐츠 생성
    • 사용자의 요청에 따라 데이터를 생성하거나 변경하고, 이를 동적으로 웹 페이지로 전달합니다.
    • 예를 들어, 사용자 인증, 데이터베이스 질의 결과, 파일 처리 등을 동적으로 수행합니다.
  3. 세션 관리
    • 웹 애플리케이션에서 클라이언트의 상태를 관리하는 데 도움을 줍니다.
    • 클라이언트가 여러 페이지를 요청할 때, 같은 사용자로 인식하도록 세션을 관리합니다.
  4. 비즈니스 로직 처리
    • 데이터베이스와의 상호작용이나 복잡한 계산을 수행하는 비즈니스 로직을 구현할 수 있습니다.
  5. 응답 처리
    • 클라이언트에게 전달할 HTML, JSON, XML 등의 형식으로 응답을 생성합니다.

[2] Servlet의 작동 방식

  1. 클라이언트의 요청
    클라이언트(보통 웹 브라우저)가 특정 URL을 요청합니다. 이 URL은 서버에 있는 Servlet을 호출합니다.

  2. Servlet 컨테이너 처리
    웹 서버 또는 애플리케이션 서버에서 Servlet 컨테이너가 요청을 받아 Servlet 클래스를 실행합니다.
    이때, Servlet 컨테이너는 요청 정보를 HttpServletRequest 객체에 담아 Servlet으로 전달합니다.

  3. 비즈니스 로직 실행
    Servlet은 요청을 처리하기 위해 필요한 비즈니스 로직을 실행합니다. 이 과정에서 데이터베이스와 연동하거나 데이터를 가공할 수 있습니다.

  4. 응답 생성
    Servlet은 응답을 생성하여 클라이언트에게 반환합니다. 이는 HTML, JSON, XML 등 다양한 형식일 수 있습니다.

  5. 클라이언트에 응답 반환
    생성된 응답은 HttpServletResponse 객체를 통해 클라이언트에게 전달됩니다.

[3] Servlet의 주요 메서드

  1. doGet(HttpServletRequest request, HttpServletResponse response)
    • GET 요청을 처리하는 메서드입니다. 웹 페이지 요청, 링크 클릭 등으로 자주 사용됩니다.
  2. doPost(HttpServletRequest request, HttpServletResponse response)
    • POST 요청을 처리하는 메서드입니다. 일반적으로 사용자로부터 데이터를 제출받을 때 사용됩니다.
  3. init()
    • Servlet이 처음 로딩될 때 호출되는 초기화 메서드입니다. 주로 Servlet 객체의 초기화 작업을 처리합니다.
  4. destroy()
    • Servlet이 종료될 때 호출됩니다. 자원 해제 및 정리 작업을 수행하는 데 사용됩니다.

[4] Servlet의 예시

HTTP Request Message 예시

POST /api/users HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded

userId=아이디&pssword=비밀번호

 

HTTP Response Message 예시

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 3423

<html>
	<body>
		...
	</body>
</html>

 

 

  1. 서버와 TCP/IP 연결
  2. HTTP Request Message 필요한 형태로 변환하여 읽기
    1. HTTP Method 및 URL 분석
    2. HTTP Header 분석
    3. HTTP Message Body 읽기 및 변환
  3. 분석한 결과를 통해 프로세스 실행
  4. 비지니스 로직 실행
  5. HTTP Response Message 생성
    1. HTTP Start Line 생성
    2. Header 생성
    3. HTTP Message Body에 응답 데이터를 요청한 형식에 맞춰 응답
    4. 처리가 불가하다면 예외처리
  6. 응답 전달
  7. 연결 종료
  • Servlet을 지원하는 WAS를 사용한다면?
    1. 비지니스 로직 실행

 

@WebServlet("/hello") // 해당 URL에 매핑되는 Servlet
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 응답 콘텐츠 타입 설정
        response.setContentType("text/html");
        
        // 클라이언트에 응답 전송
        PrintWriter out = response.getWriter();
        out.println("<h1>Hello, Servlet!</h1>");
    }
}
  • 위의 코드에서 HelloServlet은 /hello URL로 들어오는 GET 요청을 처리하며, 간단한 HTML 메시지를 반환하는 Servlet입니다

 


[5] Servlet과 JSP의 차이

구분 Servlet JSP (Java Server Pages)
구성 Java 코드로 작성된 클래스 HTML 코드 내에 Java 코드를 삽입하는 형식
주요 용도 비즈니스 로직 처리, HTTP 요청/응답 관리 사용자 인터페이스(HTML) 작성 및 동적 콘텐츠 생성
장점 강력한 제어 흐름과 비즈니스 로직 구현 가능 HTML 기반으로 작성이 쉬우며, 동적 콘텐츠 생성에 유리
단점 HTML 생성 시 복잡한 Java 코드 필요 비즈니스 로직과 UI가 혼합되어 있어 코드 관리가 어려울 수 있음

 


[6] Servlet의 배달 비유

  • 웹 서버배달원이 단순히 포장을 해서 전달하는 역할이라면,
  • Servlet은 배달원이 주문에 맞게 음식을 준비하고 포장하여 고객에게 전달하는 역할입니다.
    • 정적 콘텐츠를 제공하는 웹 서버와 달리, Servlet은 고객이 주문한 대로 동적으로 음식을 만들고 제공하는 역할을 합니다.
  • 엄연히 WAS와는 다르다. 오히려 WAS에서 클라이언트 요청을 처리하고 응답을 생성하는 역활을 하는 자바 클래스이다. = WAS에서 사용되는 클래스이다

 

Servlet 동작 순서

 

1. WAS의 Servlet Container가 servlet 객체를 생성

2. 클라이언트가 해당 servlet을 사용하는 http 요청을 하면, Servlet Container에서 request,response 객체 생성

3. 이때, 쓰레드가 Servlet 객체 호출하고 request,response 객체를 Servlet 객체에 넘겨줌. 

4. request 객체를 활용해 Servlet의 비즈니스 로직 실행. 

5. 응답 결과를 response 객체에 담은 후, Servlet Container에 전달

6. Servlet Container가 http 응답 메시지 생성 후 클라이언트에게 전달 

서블릿은 로딩 시점에 생성될 수도 있고, 최초 요청 시점에서 생성될 수도 있다고 합니다. 그래서 요청시 서블릿 인스턴스가 메모리에 존재하지 않는다면  서블릿 컨테이너는 해당 서블릿을 로드하고 init() 메서드를 통해 초기화한 후, 적재한다고 합니다.
  • 개발자가 하는 일
    1. Request 객체에 담겨져있는 HTTP 요청 정보를 꺼내서 사용한다.
      • 요청 정보(URL, Method, Message Body)를 통해 필요한 기능(비지니스 로직)을 수행한다.
    2. 생선된 Response 객체에 HTTP 응답 정보를 입력한다.

Servlet Container

📌 Servlet을 지원하는 WAS 내부에는 서블릿 컨테이너가 있다. 서블릿 컨테이너는 서블릿을 초기화, 생성, 관리, 호출, 종료하는 역할을 수행한다.

  • Servlet 관리하고 jsp파일을 실행할 수 있게 해주는 것이 Servlet Container입니다. 

  • Servlet의 생명주기
    • Servlet은 서블릿 컨테이너가 생성 및 관리한다.
    • WAS(서블릿 컨테이너 포함)가 종료될 때 Servlet도 함께 종료된다.
  • Servlet 객체 생성시점
    • 개발자가 직접 인스턴스화 하여 사용하는것이 아닌, 코드만 작성하면 서블릿 컨테이너가 생성한다.
@WebServlet(name="ExampleServlet", urlPatterns = "/example")
public class ExampleServlet extends HttpServlet { // HttpServlet을 상속받아 구현한다.
	
	@Override
	protected void service(
		HttpServletRequest request,  // HTTP 요청 정보를 쉽게 사용할 수 있게 만드는 Servlet
		HttpServletResponse response // HTTP 응답 정보를 쉽게 제공할 수 있게 만드는 Servlet
	) {
		// application logic
	}

}
@WebServlet(name="Example2Servlet", urlPatterns = "/example2")
// 위와 같은 코드

@WebServlet(name="Example3Servlet", urlPatterns = "/example3")
// 위와 같은 코드

@WebServlet(name="Example4Servlet", urlPatterns = "/example4")
// 위와 같은 코드
  • Servlet Container가 하는 일
    1. 서블릿을 초기화, 생성, 관리, 호출, 종료하는 역할을 수행한다.
      • Servlet 객체를 싱글톤으로 관리한다.
    2. 동시 요청에 대한 처리를 위해 Multi Thread를 지원한다.
싱글톤은 객체를 하나만 생성하여 생성된 인스턴스를 공유하여 사용하는것을 의미합니다. 특정 클래스의 인스턴스가 여러개 생성되지 않도록 하여 자원의 낭비를 방지하고, 인스턴스를 공유함으로써 상태를 일관되게 유지하기 위함입니다. 하지만, 공유 변수 사용을 주의해야 합니다.

 

 

 

Thread

📌 프로세스 내에서 실행되는 가벼운 작업 단위입니다. 프로세스는 프로그램이 실행되는 환경을 의미하고, 쓰레드는 프로세스 내에서 독립적으로 실행되는 코드의 흐름입니다. 여러 쓰레드는 하나의 프로세스 내에서 공유된 자원(메모리, 파일 등)을 사용하면서 동시에 실행될 수 있습니다.

  • 애플리케이션 코드를 하나하나 순차적으로 실행하는 것, Java에서 main method를 실행하면 main이라는 이름을 가진 Thread가 실행되며 하나의 Thread는 한번에 하나의 코드 라인만 수행한다.
  • 만약 동시 처리가 필요하다면 Thread를 추가적으로 생성 해야한다.

 

Servlet 객체의 호출

  • 클라이언트에서 Request가 전달되면 Thread가 Servlet 객체를 호출한다.

 

[1]  단일 요청 - Single Thread

  1. 클라이언트 요청 및 TCP/IP 연결
  2. Thread 할당 후 Servlet 호출 ( Servlet도 쓰레드에 적재되어 실행하게 된다. 프로그램이 당연하지만)
  3. 응답 후 Thread 반환

[2]  동시 요청 - Single Thread

  1. 첫번째 요청의 작업을 Single Thread가 수행중이다.
  2. 두번째, 세번째 요청이 들어오고 연결을 완료했다.
  3. Thread를 사용하기 위해 작업이 끝날때 까지 대기한다.
  4. 요청이 모두 사라질 때 까지 (대기 → 작업 수행 → 스레드 반환)작업을 반복한다.

 

  • 만약, 첫번째 요청의 작업이 지연되거나 Error가 발생한다면?
더보기

모든 요청이 Time out 오류가 발생한다.

 

[1]  요청마다 새로운 Thread 생성  - Multi Thread

  • 요청이 들어올 때 마다 Thread를 생성한다.
  • 요청 처리가 완료되면 Thread를 종료한다.
  • 멀티 쓰레드는 수행 속도가 빨라 동시에 처리하는 것 같지만 사실 엄청나게 짧은 시간 안에 수십, 수천 번 실행할 프로세스를 교체하고 있는 것이다.

 

  • 장점
    • 동시 요청을 처리할 수 있다.
    • 하나의 Thread에 지연등의 문제가 발생하여도 나머지 Thread는 정상적으로 동작한다.
  • 단점
    • Thread 생성에 제한이 없고 생성 비용이 높다.
      • 수많은 동시 요청이 발생하면 리소스(Memory, CPU 등)부족으로 서버가 다운된다.
    • Thread를 사용하면 Context Switching 비용이 발생한다.
Context Switching



Task1에서 Task2로 Task2에서 Task1로 교체되는 시점마다 Task1이 Ready 상태로 돌아간다는 정보, 진행정보, Task2는 어디부터 작업을 시작하면 되는지에 대한 정보들을 로딩할 시간이 필요하게 된다. 이 순간의 시점이 바로 Context Switching이다.

 

 

[2]  Thread Pool   - Multi Thread

  • 요청이 들어오면 Thread Pool에서 Thread를 받아 사용한다.
  • 사용 완료된 Thread는 Thread Pool에 반납한다.
더보기

Q. Thread Pool에 존재하는 Thread가 모두 사용 중이라면?

A. Thread Pool에 Thread가 생길 때까지 대기하거나 거절할 수 있습니다.

 

정리

  1. WAS는 Multi Thread를 지원한다.
    • 개발자가 Multi Thread 관련 코드는 고려하지 않아도 된다.
    • Multi Thread 환경이므로 싱글톤 객체(Servlet, Spring Bean)는 주의해서 사용해야한다.
    → 공유변수 사용 조심 또 조심!
  2. Thread Pool
    • Thread는 Thread Pool에 보관 및 관리한다.
    • Thread Pool에 생성 가능한 Thread 최대치를 관리한다. Tomcat은 최대 200개 기본 설정이 되어있다.(변경 가능)
      • 성능테스트를 통해 적정 Thread 수를 찾으면 된다.
    • 장점
      1. 요청 마다 Thread를 생성하는 단점을 보완하였다.
      2. Thread가 미리 생성되어 있어서 Thread를 생성, 종료하는 비용이 절약된다. → 응답이 빠름
      3. 생성 가능한 Thread 최대치가 제한되어 있어서 많은 요청이 들어와도 안전하게 처리할 수 있다.
    • 단점
      1. Thread Pool의 최대 Thread 수를 낮게 설정한다면 응답이 지연된다.
      2. 최대 Thread 수가 너무 높으면 즉, 요청이 많아지면 리소스 부족으로 서버가 다운된다.

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] API 설계  (0) 2024.12.12
[Net] Rendering  (1) 2024.12.05
[Net] Web Application  (1) 2024.12.03
[Net] Restful API  (1) 2024.12.02
[Net] HTTP 요청 데이터  (0) 2024.12.02

Web Server

📌 클라이언트(보통 웹 브라우저)의 요청을 받아 정적 리소스(HTML, CSS, JavaScript) 같은 정적 파일 또는 동적 콘텐츠를 제공하는 소프트웨어 또는 하드웨어를 말합니다.

= 클라이언트 요청에 따라 정적 파일(HTML, CSS, JS) 또는 동적 콘텐츠를 제공하는 소프트웨어나 하드웨어

  • 웹 서버는 HTTP 또는 HTTPS 프로토콜을 사용하며, 주로 사용자와 웹 애플리케이션[스프링] 사이에서 데이터를 주고받는 역할을 합니다.
  • 정적 리소스란 리소스가 이미 완성된 채로 서버에 존재하여 원본 그대로 응답하는 데이터를 의미한다.
  • = 다른 데이터는 가공을 처리해서 보내는 것에 반에 정적 리소스는 요청 시 서버에서 따로 데이터를 수정하거나 변형하지 않기 때문에, 서버와 클라이언트 간 추가 작업 없이 바로 사용 가능합니다.
  • 이쯤이면 헷갈릴건데 클라이언트 → 프록시 서버 → 웹 서버 → 웹 애플리케이션 → RDS 현대적인 백엔드 시스템의 흔한 구조를 간단히 표현하면 이렇다

 

미리 로드맵을 알고 가는 것이 좋다 판단하여 아래의 요약본을 보고가는 것을 추천한다.

  하는 일 주요 역할
클라이언트 - HTTP 요청 생성 (예: HTML, API 호출)
- 브라우저, 모바일 앱, 또는 다른 서비스가 요청 전송
- 서버의 응답을 사용자에게 표시
- 데이터를 요청하는 주체.
- 사용자 인터페이스 제공.
- 서버로 요청하고 결과를 화면에 출력.
프록시 서버 - 클라이언트 요청을 분석 및 필터링
- 로드 밸런싱: 요청을 여러 웹 서버로 분배
- 자주 요청되는 데이터 캐싱- 보안 강화 (예: SSL 처리)
- 중개 역할: 클라이언트와 웹 서버 사이에서 요청 처리.
- 캐싱: 정적 리소스를 저장하여 빠른 응답.
- 트래픽 관리 및 부하 분산.
웹 서버 - HTTP 요청 처리
- 정적 리소스(HTML, CSS, JS 등) 제공
- 동적 요청을 WAS로 전달
- 정적 리소스 제공.- 요청이 정적인지 동적인지 구분.
- 동적 요청을 WAS로 전달하여 처리.
WAS (웹 애플리케이션 서버) - 클라이언트 요청 처리(예: 비즈니스 로직 실행)
- 데이터베이스와 통신하여 CRUD 작업 수행
- 요청 결과를 JSON, HTML 등으로 생성 및 반환
- 요청 처리: 클라이언트 요청에 따라 데이터를 생성, 수정, 조회, 삭제.
- 비즈니스 로직 구현.
- RDS와 통신하여 필요한 데이터 제공.
RDS (관계형 데이터베이스) - 데이터를 저장, 관리 및 조회
- SQL 쿼리 처리
- 요청 데이터를 반환하거나 저장
- 영구 데이터 저장.- SQL을 통해 데이터를 읽고 쓰는 작업 수행.
- 관계형 데이터베이스로 데이터 무결성 보장.

요약: 각 파트의 주요 역할

  1. 클라이언트: 요청 생성, 서버로 전송, 응답 데이터 표시.
  2. 프록시 서버: 요청 필터링, 캐싱, 로드 밸런싱, 보안 강화.
  3. 웹 서버: 정적 리소스 제공, 동적 요청은 WAS로 라우팅.
  4. WAS: 비즈니스 로직 처리, 데이터베이스와 통신, 동적 응답 생성.
  5. RDS: 데이터를 저장하고, 읽기/쓰기 요청 처리.

 

 

 

[1] 웹 서버의 주요 기능

  1. HTTP 요청 처리
    • 클라이언트가 보낸 요청(GET, POST 등)을 수신하고 응답을 반환.
    • 정적 콘텐츠(HTML, 이미지) 또는 동적 콘텐츠(애플리케이션 서버와 연계).
  2. 정적 콘텐츠 제공
    • HTML 파일, CSS, JavaScript, 이미지 파일 등을 클라이언트에게 전달.
  3. 동적 콘텐츠 처리
    • PHP, Python, Java 등 애플리케이션 서버와 통신하여 동적으로 생성된 데이터를 반환.
  4. 보안 관리
    • HTTPS를 통한 데이터 암호화.
    • 인증 및 접근 제한 기능 제공.
  5. 로드 밸런싱
    • 여러 서버에 요청을 분산하여 성능을 최적화하고, 고가용성을 유지.

[2] 웹 서버의 작동 방식

  1. 클라이언트(웹 브라우저)가 URL을 통해 서버에 요청을 보냄.
  2. 웹 서버는 요청을 분석하여 처리할 리소스를 결정.
    • 정적 콘텐츠 요청: HTML, CSS 같은 파일을 그대로 반환.
    • 동적 콘텐츠 요청: 애플리케이션 서버에 요청을 전달하고 결과를 받아 반환.
  3. 처리 결과를 HTTP 응답으로 클라이언트에게 전달.

[3] 웹 서버의 예시와 용도

웹 서버 소프트웨어특징

Apache HTTP Server 가장 널리 사용되는 오픈소스 웹 서버. 다양한 플랫폼 지원.
Nginx 가벼운 구조와 높은 성능으로 정적 파일 제공 및 로드 밸런싱에 강점.
IIS Microsoft가 개발한 윈도우 전용 웹 서버. .NET 애플리케이션과의 통합이 강점.
LiteSpeed Nginx와 비슷한 고성능 웹 서버로, 특히 WordPress와의 호환성이 좋음.

[4] 웹 서버와 애플리케이션 서버의 차이

구분 웹 서버 애플리케이션 서버
주요 역할 정적 콘텐츠 제공 동적 콘텐츠 생성
예시 Apache, Nginx Tomcat, WebLogic, JBoss
작동 방식 클라이언트 요청에 HTML, CSS, 이미지 등 반환 서버 로직을 실행하여 동적으로 데이터를 생성하고 반환
연계 단독 또는 애플리케이션 서버와 함께 사용 웹 서버와 연동하여 동작

[5] 웹 서버의 배달 비유

웹 서버는 배달 창구 직원에 비유할 수 있습니다.

  • 요청 분석: 고객(브라우저)이 요청하면 창구 직원이 요청 내용을 확인.
  • 정적 리소스 제공: 창고에서 물건(HTML, CSS, 이미지)을 찾아 전달.
  • 동적 리소스 요청: 필요시 창고 관리자(애플리케이션 서버)에게 요청을 전달하고 결과를 받아 고객에게 전달.
  • 로드 관리: 한 번에 여러 고객을 효율적으로 처리하도록 줄을 정리.

[6] 웹 서버의 장점과 단점

장점 단점
- 빠르고 효율적인 정적 콘텐츠 제공. - 동적 처리를 단독으로 지원하지 못함.
- HTTP 프로토콜 최적화로 요청 처리 속도 향상. - 복잡한 요청(데이터 처리, 비즈니스 로직 등)은 애플리케이션 서버에 의존.
- 다양한 플랫폼과의 호환성. - 상태 비저장 특성으로 특정 작업 지속성을 유지하기 어려움.

 

 

 

WAS(Web Application Server)

📌 웹 애플리케이션을 실행하고 관리하는 서버입니다. 웹 애플리케이션 서버는 동적 콘텐츠 생성비즈니스 로직 처리를 담당하며, 클라이언트의 요청에 따라 애플리케이션 로직을 실행하고 결과를 반환합니다.

  • 웹 서버와는 달리 WAS는 서버 측의 애플리케이션을 실행하고 관리하는 역할을 하며, 일반적으로 웹 서버와 함께 사용되어 동적 콘텐츠 처리를 지원합니다.

 

[1] WAS의 주요 기능

  1. 애플리케이션 실행
    • 클라이언트의 요청에 따라 동적으로 데이터를 생성하고 비즈니스 로직을 실행합니다.
    • 예를 들어, 데이터베이스와 연결하여 정보를 가져오거나, 파일을 처리하거나, 복잡한 계산을 수행하는 등의 작업을 처리합니다.
  2. 세션 관리
    • 사용자 상태를 유지하기 위해 세션을 관리합니다.
    • 클라이언트가 여러 요청을 보내더라도, 서버는 동일한 사용자로 인식하여 일관된 정보를 제공합니다.
  3. 트랜잭션 관리
    • 데이터베이스와의 트랜잭션 처리를 관리하여 일관성 있는 데이터를 제공합니다.
  4. 보안 관리
    • 애플리케이션의 보안을 관리하고, 인증 및 권한 부여를 처리합니다.
  5. 서비스 배포 및 확장
    • 애플리케이션을 배포하고 관리하는 기능을 제공합니다.
    • 확장성을 고려하여 여러 인스턴스로 분산 처리가 가능합니다.

 


[2] WAS와 웹 서버의 차이

특징 웹 서버 웹 애플리케이션 서버 (WAS)
기본 역할 정적 콘텐츠 제공 (HTML, 이미지, CSS 등) 동적 콘텐츠 생성 및 비즈니스 로직 실행
응답 처리 방식 파일을 그대로 전달 (정적 파일 처리) 애플리케이션 로직을 실행하여 데이터를 동적으로 생성
세션 관리 일반적으로 세션 관리가 없거나 제한적 세션 관리 및 트랜잭션 처리
애플리케이션 서버 기능 없음 비즈니스 로직 실행, 데이터베이스 연동, 트랜잭션 관리
사용 예시 웹 페이지의 HTML, 이미지, CSS 파일 제공 온라인 쇼핑몰, 은행 시스템, 사용자 인증 등
  • Web Server와 WAS(Web Application Server)의 차이점
    1. 실제로는 Web Server도 Application 로직을 포함할 수 있다.
    2. WAS는 Application 코드를 실행하는 것에 더욱 특화되어 있다.
    3. Java에서는 Servlet Container 기능을 제공하면 WAS 이다.

[3] WAS의 예시

WAS 소프트웨어특징

Apache Tomcat Java Servlet과 JSP를 지원하는 오픈소스 WAS. 가장 널리 사용됨.
JBoss (WildFly) Java EE 표준을 지원하며, 엔터프라이즈급 애플리케이션을 처리하는 WAS.
WebLogic Oracle의 Java EE 기반 WAS, 고급 트랜잭션 관리와 확장성 제공.
WebSphere IBM의 WAS로, 대규모 기업 환경에서 고급 기능과 안정성 제공.

 


[4] WAS의 배달 비유

  • 웹 서버배달원이 단순히 포장을 해서 전달하는 역할이라면,
  • **웹 애플리케이션 서버(WAS)**는 배달원이 주문에 맞춰 요리를 준비하고, 포장한 뒤 정확하게 전달하는 역할입니다.
    • 즉, 웹 서버는 이미 준비된 음식을 그대로 전달하지만, WAS는 주문에 맞는 음식을 준비하고 그 결과를 고객에게 전달하는 역할을 합니다.

 

 

Web System 구성

 

[1]  WAS만 사용하는 경우

  1. WAS가 너무 많은 역할을 담당한다
    • 서버 과부하 발생 가능성이 높아진다.
  2. 실행에 가장 중요한 Application 로직이 정적 리소스로 인해 수행되지 않을 수 있다.
  3. WAS에 장애가 생기면 아무런 화면도 보여주지 못한다.
    • 오류 페이지를 클라이언트에게 응답할 수 없다.

 

[2]  실제 웹 시스템 구성

  1. 정적 리소스는 Web Server에서 처리한다.
  2. Web Server는 Application 로직이 필요한 요청만을 WAS에 전달한다.

 

[3]  실제 웹 시스템 구성의 장점

  1. 효율적으로 리소스를 관리할 수 있다.
    • 정적 자원이 많이 사용된다면 Web Server를 ScaleOut 한다.
    • Application 관련 자원이 많이 사용된다면 WAS를 ScaleOut 한다.
  2. 오류 화면을 제공할 수 있다.
    • Web Server는 오류가 발생할 확률이 아주 낮다.
    • WAS는 오류가 발생할 확률이 아주 높고, 장애가 자주 발생한다.
    • WAS는 DB와 상호작용 하기 때문에 DB에 문제가 생겨도 문제가 발생한다.

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] Rendering  (1) 2024.12.05
[Net] Servlet  (1) 2024.12.04
[Net] Restful API  (1) 2024.12.02
[Net] HTTP 요청 데이터  (0) 2024.12.02
[Net] HTTP Header  (0) 2024.12.01

Restful API

📌 REST(Representational State Transfer) 아키텍처 스타일을 준수하여 설계된 API입니다. 주로 HTTP 프로토콜을 기반으로 클라이언트와 서버 간에 리소스를 주고받기 위해 사용되며, 간결하고 확장 가능한 웹 서비스 설계를 제공합니다.

  • REST를 잘 준수하는 API로 HTTP 프로토콜을 사용하여 클라이언트와 서버 간의 통신을 통해 자원(Resource)을 관리한다.
  • 원은 고유한 URI로 식별되며, HTTP 메서드(GET, POST, PUT, DELETE 등)를 통해 다양한 작업을 수행하며 요청과 응답은 일반적으로 JSON 또는 XML 형식으로 이루어진다.

 

REST(Representational State Transfer)란?

  • 자원(Resource)을 이름(Name)으로 구분하여 해당 자원의 상태(정보)를 주고받는 것을 의미한다.
  • → URI를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE,PATCH 등)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 REST라 칭한다.
  • = REST란 자원을 URI로 식별하고, HTTP 메서드를 사용해 자원의 상태를 주고받는 아키텍처 스타일이다.
  • = RESTful API란 REST 원칙을 준수하여 설계된 API로, 클라이언트와 서버 간에 자원의 상태를 HTTP 메서드와 URI를 통해 일관되게 주고받는 방식이다.

 

 

[1]  RESTful API의 주요 특징

  1. 리소스 중심 설계
    • 모든 데이터는 **리소스(Resource)**로 표현되며, 고유한 URL을 통해 접근합니다.
    • 예: /users는 사용자 리소스를 나타냅니다.
  2. 표준 HTTP 메서드 사용
    • RESTful API는 HTTP 메서드(GET, POST, PUT, DELETE 등)를 사용해 CRUD(Create, Read, Update, Delete)를 구현합니다.
  3. 상태 비저장(Stateless)
    • 서버는 클라이언트의 상태를 저장하지 않으며, 각 요청은 독립적으로 처리됩니다.
    • 클라이언트가 필요한 모든 정보를 요청에 포함해야 합니다.
  4. URI를 통한 리소스 표현
    • RESTful API는 명확하고 의미 있는 URI를 사용합니다.
    • 예: /products/123는 특정 상품(ID: 123)을 나타냅니다.
  5. JSON을 통한 데이터 교환
    • 요청 및 응답 데이터 형식으로 주로 JSON을 사용하지만, XML 등 다른 형식도 가능.
  6. 계층화 구조
    • API 호출자는 서비스의 내부 구현이나 계층을 알 필요 없이 요청을 보낼 수 있습니다.

 


 

[2]  RESTful API의 구성 요소

구성 요소 설명 예시
리소스 API에서 관리되는 데이터. users, products, orders
URI 리소스를 나타내는 고유한 경로. /users/123
HTTP 메서드 리소스에 대한 동작을 정의. GET, POST, PUT, DELETE
표현(Representation) 리소스의 데이터 표현 형식 (주로 JSON). { "id": 123, "name": "John" }
상태 코드 요청 처리 결과를 나타내는 HTTP 응답 코드. 200 OK, 404 Not Found

 



[3]  RESTful API의 HTTP 메서드와 리소스 설계

HTTP 메서드 리소스 URI  배달 비유
GET 리소스 조회 /users (전체 조회) "모든 배달 내역을 확인해 주세요."
    /users/123 (특정 조회) "123번 주문 내역을 보여 주세요."
POST 리소스 생성 /users "새로운 주문을 넣어 주세요."
PUT 리소스 전체 수정 /users/123 "123번 주문의 모든 항목을 수정해 주세요."
PATCH 리소스 일부 수정 /users/123 "123번 주문 중 주소만 바꿔 주세요."
DELETE 리소스 삭제 /users/123 "123번 주문을 취소해 주세요."

 



[4]  RESTful API의 설계 원칙

  1. 자원 중심의 URI 설계
    • URI는 명확하고 직관적이어야 합니다.
      • 올바름: /users/123/orders
      • 잘못된 예: /getUserOrder?id=123
  2. HTTP 상태 코드 활용
    • 상태 코드는 클라이언트가 요청 결과를 이해하는 데 도움을 줍니다.상태 코드설명
      200 OK 요청이 성공적으로 처리됨
      201 Created 새로운 리소스가 생성됨
      400 Bad Request 잘못된 요청
      404 Not Found 리소스를 찾을 수 없음
      500 Internal Server Error 서버 오류
  3. 상태 비저장 설계
    • 서버는 요청 간 클라이언트의 상태를 기억하지 않아야 하며, 요청에 필요한 정보를 클라이언트가 제공해야 합니다.
  4. 일관성 유지
    • 모든 API는 일관된 설계와 명명 규칙을 따릅니다.

 



[5]  RESTful API의 배달에 비유

  • RESTful API는 배달 시스템과 비슷합니다.
    • URI: 배달 주소 (e.g., /users/123 → 특정 고객의 배달 내역).
    • HTTP 메서드: 배달 요청의 종류 (GET → 확인, POST → 새로운 주문, DELETE → 취소).
    • 상태 코드: 배달 결과 알림 (200 → 성공, 404 → 주소를 못 찾음).
    • JSON: 주문서의 상세 내용.

RESTful API는 이러한 비유처럼 직관적이고 간결한 방식으로 데이터를 주고받는 웹 서비스입니다.

 

더보기

참고자료 정리

  1. 리소스는 명사를 사용해야 한다.
  2. 단수가 아닌 복수 형태를 사용해야 한다.
  3. 만약, REST만으로 해결하기 어려운 경우라면 동사를 허용한다.
  4. 자원의 계층 관계를 슬래시(/)로 표현한다.
  5. 마지막 문자에는 슬래시(/)가 있으면 안된다.
  6. 언더바(_)가 아닌 하이픈(-)을 사용해야 한다.
  7. 소문자를 사용해야 한다.
  8. URI에 파일 확장자를 포함하면 안된다.
  9. CRUD 함수명은 사용하지 않고, HTTP Method를 활용해야 한다.
  10. 정렬, 필터링, 페이징은 신규 API를 만드는것이 아닌 Query Parameter를 사용해야 한다.

 

 

Maturity Model (성숙도 모델)

🐳  시스템, 프로세스, 조직, 또는 기술이 특정 목적을 얼마나 잘 달성하고 있는지를 단계별로 평가하는 구조적 접근 방식입니다. 이를 통해 조직이나 시스템이 현재 상태를 진단하고, 더 높은 수준으로 발전하기 위해 필요한 개선 사항을 명확히 할 수 있습니다.

 

[1] 성숙도 모델의 핵심 요소

  1. 단계적 성장
    • 성숙도 모델은 일반적으로 5단계 또는 그 이상의 단계를 정의하며, 초기 상태부터 완성된 상태까지 점진적으로 발전하는 과정을 나타냅니다.
  2. 평가 기준
    • 각 단계는 명확한 평가 기준을 가지고 있어, 현재 상태와 목표 상태를 비교하고 발전 방향을 설정할 수 있도록 돕습니다.
  3. 객관적 진단
    • 조직이나 시스템의 성숙도를 객관적이고 체계적으로 진단하여 개선의 우선순위를 설정할 수 있습니다.

 



[2] 대표적인 성숙도 모델

1. CMMI (Capability Maturity Model Integration)

소프트웨어 개발, 서비스 관리 등의 프로세스를 개선하기 위한 대표적인 성숙도 모델.

단계설명특징

Level 1 초기화(Initiating) 비체계적, 성공은 개인 역량에 의존.
Level 2 관리(Managed) 기본 프로젝트 관리 체계가 갖춰져 있음.
Level 3 정의(Defined) 표준 프로세스 정의 및 조직 내 일관성 확보.
Level 4 정량적 관리(Quantitatively Managed) 데이터 기반 관리 및 프로세스 개선.
Level 5 최적화(Optimizing) 지속적 개선과 혁신이 이루어짐.

 

2. 데이터 성숙도 모델

데이터 관리를 중심으로 조직의 데이터 활용 능력을 평가.

단계설명특징

Level 1 초기화(Initial) 데이터 관리가 비체계적이며 중복과 오류 발생.
Level 2 관리(Managed) 데이터 품질 관리 체계 도입.
Level 3 정의(Defined) 데이터 표준화와 통합 관리 체계 확립.
Level 4 예측(Predictive) 데이터 분석을 통해 예측 가능.
Level 5 혁신(Innovative) 데이터 중심 의사결정이 가능한 혁신 조직.

 



[3] 성숙도 모델의 주요 활용 사례

  1. 조직 관리
    • 조직의 프로세스 성숙도를 진단하고 개선 방향 설정.
  2. 소프트웨어 개발
    • 개발 프로세스의 체계화와 품질 향상을 위한 CMMI 적용.
  3. 데이터 관리 및 분석
    • 데이터를 전략적으로 활용하기 위한 데이터 성숙도 모델 활용.
  4. 디지털 트랜스포메이션
    • 디지털화 성숙도를 평가하고 디지털 전략 수립.

 



[4] 성숙도 모델의 장점과 단점

구분장점단점

장점 - 현재 상태를 명확히 진단 가능. - 모든 조직이나 시스템에 동일한 기준을 적용하기 어려움.
  - 개선 방향과 우선순위를 설정할 수 있음. - 각 단계로 이동하는 데 시간이 오래 걸릴 수 있음.
  - 지속적 개선 문화를 정착시키는 데 도움. - 실제 업무 상황을 반영하지 못할 경우 개선 효과가 떨어질 수 있음.
단점 - 측정 및 진단이 복잡할 수 있음. - 초기 단계에서는 비용 대비 효과가 크지 않을 수 있음.

 



[5] 배달에 비유: 성숙도 모델

단계배달 예시

Level 1 "메뉴를 잘못 기록하고, 배달이 늦고, 고객 불만이 많음."
Level 2 "주문 확인 절차를 통해 기본적인 실수는 줄었으나, 고객 맞춤 서비스는 부족."
Level 3 "배달 경로와 고객 데이터를 분석하여 효율성을 높임."
Level 4 "고객의 이전 주문 기록을 바탕으로 맞춤형 추천 메뉴 제공."
Level 5 "AI를 활용한 배달 시간 예측 및 개인화된 서비스로 고객 만족도 최고조."

 

 

API Maturity Model (성숙도 모델)

  • Level0
    • 웹 서비스를 제공하기 위해 URL만 매핑해 놓은 상태
    • 요청 예시(모든 요청이 단일 URI로 전송된다)
POST /operation
{
    "operation": "createUser",
    "data": {
        "name": "sparta",
        "password": "codingclub"
    }
}

 

  • Level1
    • 외부로 공개하려는 리소스에 대해서 의미있는 URL로 표현하기 시작한 단계
    • 적절한 패턴을 가지고 작성 되었지만 HTTP의 메소드 별로 서비스를 구분하여 사용하고 있지는 않다.
    • 즉, 서비스 형태나 작업의 종류에 맞추어 적절한 HTTP 메소드를 지정하고 있지 않다.
    • 사용자의 요청을 GET, POST로 대부분 처리하고 에러를 반환한다.
    • 요청 예시(리소스에 대해 분리된 엔드포인트를 가진다)
POST /users
{
    "name": "sparta",
    "password": "codingclub"
}

 

  • Level2
    • 우리가 제공하고자 하는 리소스를 적절하게 용도와 상태에 따라서 HTTP Methods에 맞게 설계하고 서비스하는 단계.
    • 만약 리소스의 상태가 읽기 용도로 사용되는 데이터라고 한다면 GET Method를 사용한다.
    • 새로운 리소스를 추가하는 경우는 POST Method
    • 기존 리소스의 상태를 변경하기 위해서는 PUT, PATCH Method
    • 리소스를 삭제하고자 할 때에는 Delete Method를 사용하여 서비스의 상태를 표현한다.
    • RESTful Service의 DB에 저장된 리소스를 확인하고 이러한 데이터를 조작하기 위해서 CRUD와 매칭되는 HTTP Methods를 이용하여 서비스 하는 것을 Level2 단계라고 한다.
    • HTTP의 메소드를 이용하여 리소스의 상태를 구분하여 서비스 하게 되면 비슷한 이름의 URI라 하더라도 HTTP Method에 따라서 다른 형태의 서비스를 제공할 수 있게 된다.
    • 요청 예시(HTTP Method 활용)
GET /users/123     // 특정 사용자 조회

POST /users        // 사용자 생성
{
    "name": "sparta",
    "password": "codingclub"
}

PUT /users/123     // 사용자 정보 수정
{
    "name": "java",
    "password": "spring"
}

DELETE /users/123  // 사용자 삭제

 

  • Level3
    • 데이터를 가지고 그 다음 작업에서 어떠한 작업을 할 수 있는지 상태 정보를 함께 넘겨준다.
    • 클라이언트 측에서는 서버가 제공하는 서비스를 일일이 찾는 수고를 겪지 않아도 된다.
    • 엔드포인트만 가지고 있으면 서버가 제공할 수 있는 다음, 그 다음 URI값을 알 수 있다.
    • 요청 예시(응답 내에 링크를 포함한다)
💡 HATEOAS(Hypermedia As The Engine Of Application State) 회원 가입 후 회원 정보 수정은 어떻게 해야 하는지, 조회는 어떻게 해야 하는지 회원 조회를 하면서 그다음 단계로 진행할 수 있는 또 다른 리소스에 대한 정보는 어떠한 것이 있는지. 이러한 모든 정보를 같이 알려주는 기능을 HATEOAS라고 한다.

 

GET /users/123
{
    "id": 123,
    "name": "sparta",
    "links": {
        "self": "/users/123",
        "update": "/users/123",
        "delete": "/users/123"
    }
}

 

 

★ RESTful API 설계 시 고려해야 할 사항들

 

1. Consumer first

  • 개발자 중심의 설계방식보다 해당 API의 소비자 입장에서 간단하고 직관적인 API를 설계 해야한다.
  • 위에서의 소비자는 엔드유저가 아닌 API를 사용 하고있는 또다른 시스템, 개발자 등을 얘기한다.

2. Make best use of HTTP

  • HTTP Method와 Request, Response, Header와 같은 HTTP의 장점을 살려서 개발 해야한다.

3. Request methods

  • 최소한 성숙도 모델 Level2로는 사용하여야 한다.

4. Response Status

  • 각각의 API 요청에 따라서 적절한 HTTP 상태코드가 전달되어야 한다.
  • 성공했다, 실패했다가 아닌 왜 실패하고 성공 하였는지 함께 반환 시켜주어야 한다.

5. No secure info in URI

  • URI에는 사용자의 정보를 포함해서는 안된다.

6. Use plurals

  • 제공하는 데이터에 대하여 단수가 아닌 복수형태로 쓰는것이 일반적이다.
  • 특정 유저를 찾고자 한다면 엔드포인트에 값을 추가한다.
  • ex) /user -> /users
  • ex) /users/1

 

7. User nouns for resources

  • 모든 리소스는 가능하면 동사가 아닌 명사형태로 표시한다.
  • API URI만 보고도 어떠한 API인지 파악할 수 있는것이 좋다.

8. For exceptions - define a consistent approach

  • 일괄적인 엔드포인트를 사용하는것이 좋다.

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] Servlet  (1) 2024.12.04
[Net] Web Application  (1) 2024.12.03
[Net] HTTP 요청 데이터  (0) 2024.12.02
[Net] HTTP Header  (0) 2024.12.01
[Net] HTTP Method  (2) 2024.11.30

Client에서 Server로 Data를 전달하는 방법

📌 Client에서 Server로 Data를 전달하는 방법은 Query Parameter, HTTP Form Data, HTTP Request Body 크게 세가지가 있다.

 

GET + Query Parameter(=Query String)

  • URL의 쿼리 파라미터를 사용하여 데이터 전달하는 방법
http://localhost:8080/request-params?key1=value1&key2=value2
  • HttpServletRequest 사용
@Slf4j
@Controller
public class RequestParamController {

    @GetMapping("/request-params")
    public void params(
						            HttpServletRequest request,
												HttpServletResponse response
											 ) throws IOException {
															 
        String key1Value = request.getParameter("key1");
				String key2Value = request.getParameter("key2");
				
				log.info("key1Value={}, key2Value={}", key1Value, key2Value);
        response.getWriter().write("success");
    }
}

 

  • response.getWriter().write()
    • HttpServletResponse를 사용해서 응답값을 직접 다룰 수 있다.
    • @Controller 지만 @ResponseBody를 함께 사용한 것과 같다.
  • Postman 요청

 

  • log 출력결과

 

 

POST + HTML Form(x-www-form-urlencoded)

  • HTTP Request Body에 쿼리 파라미터 형태로 전달하는 방법
  • HTTP Request
POST /form-data
content-type: application/x-www-form-urlencoded

key1=value1&key2=value2

 

  • HttpServletRequest 사용
@Slf4j
@Controller
public class RequestBodyController {

    @PostMapping("/form-data")
    public void requestBody(
						            HttpServletRequest request,
												HttpServletResponse response
											 ) throws IOException {
											 
        String key1Value = request.getParameter("key1");
				String key2Value = request.getParameter("key2");
				
				log.info("key1Value={}, key2Value={}", key1Value, key2Value);
        response.getWriter().write("success");
    }
}
  • Postman

  • Log 출력

 

HttpServletRequest.getParameter(”key”);를 사용하면 Query Parameter, HTML Form Data 두가지 경우 모두 데이터 형식(key=value)이 같기 때문에 해당값에 접근할 수 있다.

 

 

HTTP Request Body

  • 데이터(JSON, TEXT, XML 등)를 직접 HTTP Message Body에 담아서 전달한다.
  • 주로 @RestController에서 사용하며, 대부분 JSON 형식으로 데이터를 전달한다.
    • POST, PUT, PATCH Method에서 사용한다.
    • GET, DELETE Method는 Body에 데이터를 담는것을 권장하지 않는다.
  • HttpServletRequest 사용
@Getter
@Setter
public class Board {

	private String title;
	private String content;

}

 

package com.example.springbasicannotation.controller;

import com.example.springbasicannotation.entity.Board;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.PostMapping;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

@Slf4j
@Controller
public class RequestBodyController {

    // JSON을 객체로 변환해주는 Jackson 라이브러리
    private ObjectMapper objectMapper = new ObjectMapper();

    @PostMapping("/request-body")
    public void requestBody(
            HttpServletRequest request,
            HttpServletResponse response
    ) throws IOException {

        ServletInputStream inputStream = request.getInputStream();
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

        log.info("messageBody={}", messageBody);

        Board board = objectMapper.readValue(messageBody, Board.clss);

        log.info("board.getTitle()={}, board.getContent()={}", board.getTitle(), board.getContent());

        response.getWriter().write("success");

    }
    
}

 

  • Postman

 

  • 출력결과

 

 

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] Web Application  (1) 2024.12.03
[Net] Restful API  (1) 2024.12.02
[Net] HTTP Header  (0) 2024.12.01
[Net] HTTP Method  (2) 2024.11.30
[Net] HTTP  (0) 2024.11.29

HTTP Header

📌 클라이언트(웹 브라우저 등)와 서버 간의 요청 또는 응답에 대한 추가 정보를 전달하는 데이터입니다. 요청(Request)과 응답(Response) 메시지의 헤더는 각각의 목적에 맞는 다양한 필드를 포함합니다.

  • Header 구조

  • field-name: OWS field-value OWS (OWS : 띄어쓰기 허용)
  • field-name은 대소문자 구분을 하지 않는다.
  • HTTP 전송에 필요한 모든 부가정보를 표현할 수 있다.
  • 임의의 Header를 추가할 수 있다. 단, 서버가 값을 알고있어야 함
  • 텍스트 (plain text)로 이루어져 있다.
  • 각각의 헤더는 하나의 줄로 구분된다.

 

[1] HTTP 헤더의 역할

  • 클라이언트 요청: 브라우저가 서버에 요청할 때 추가 정보를 전달.
  • 서버 응답: 서버가 클라이언트에게 응답할 때 추가적인 메타정보를 전달.

[2] HTTP 헤더의 주요 필드

 

헤더  설명 예시
일반 헤더 (General Header) 요청과 응답에 공통으로 사용되는 헤더. 주로 메시지 자체에 관한 정보를 포함. Cache-Control: no-cache
요청 헤더 (Request Header) 클라이언트에서 서버로 요청할 때 제공하는 헤더. 주로 클라이언트의 환경, 인증 정보 등을 포함. User-Agent: Mozilla/5.0, Authorization: Bearer <token>
응답 헤더 (Response Header) 서버가 클라이언트에 응답할 때 전달하는 헤더. 주로 서버 정보나 요청 처리 상태를 설명. Server: Apache, Set-Cookie: SESSIONID=12345
엔티티 헤더 (Entity Header) 요청/응답 메시지의 본문(body) 데이터를 설명. 주로 데이터의 길이, 타입 등을 명시. Content-Type: text/html, Content-Length: 348

[3] 대표적인 HTTP 헤더 필드

1. 요청(Request) 헤더

헤더 설명 예시
Host 요청이 보내질 서버의 호스트 이름과 포트. Host: www.example.com
User-Agent 요청을 보낸 클라이언트의 정보 (브라우저, OS 등). User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64)
Accept 클라이언트가 받을 수 있는 데이터 형식. Accept: text/html, application/json
Authorization 인증 정보 전달 (주로 Bearer Token이나 Basic Auth). Authorization: Bearer <token>

 

2. 응답(Response) 헤더

헤더 설명 예시
Content-Type 응답 본문의 데이터 형식(Content)의 타입을 명시. Content-Type: application/json
Set-Cookie 클라이언트에 쿠키를 저장하도록 지시. Set-Cookie: SESSIONID=abc123; Path=/; HttpOnly
Cache-Control 캐싱 정책 지정 (브라우저나 프록시에서의 캐싱 제어). Cache-Control: no-cache
Location 리다이렉션 응답에서 새로운 URL을 제공. Location: http://example.com/new-page

 

3. 일반(공통) 헤더

헤더 설명 예시
Cache-Control 요청 또는 응답의 캐싱 동작을 제어. Cache-Control: no-store
Connection 네트워크 연결 설정을 제어 (e.g., keep-alive). Connection: keep-alive
Date 메시지가 생성된 시간과 날짜. Date: Tue, 15 Nov 2024 08:12:31 GMT

[4] HTTP 헤더 배달에 비유

  • HTTP 헤더택배 상자에 붙은 송장
    • 송장에는 받는 사람, 발신지, 상품 내용, 배송 시 요청사항 등 다양한 정보가 적혀 있다.
    • 예를 들어, User-Agent는 보내는 사람이 어떤 장비를 사용했는지를 알려주는 정보
    • Content-Type은 상자 안에 무엇이 들어있는지를 알려준다.

 

더보기
  • 실제 HTTP Header 확인하는 방법
    • 실제 브라우저는 하나의 화면을 구성하기 위해 수많은 HTTP 통신을 진행한다!
    • 개발자도구(F12) → Network 탭 클릭 → Fetch/XHR 탭 클릭 → 우측 Header 정보
     

 

 

표현 헤더(Representation)

  • 실제 데이터를 전송할 때는 특정 형식으로 변환하여 보내게된다.
  • 리소스에 대한 표현 정보(어떤 데이터 형식으로 보낼지)를 나타낸다.
  • 요청, 응답에 모두 사용되는 Header이다.
  • 종류
    • Content-Type : 형식
      • 전송할 데이터의 미디어 타입, 문자 인코딩을 나타낸다.
      • text/html; charset=utf-8
      • application/json
    • Content-Encoding : 압축 방식
      • 데이터를 압축 후 Encoding 헤더를 추가하면, 읽는 쪽에서 해당 정보로 압축을 해제한다.
      • gzip
      • identity : 압축하지 않음을 나타낸다.
    • Content-Language : 언어
      • 데이터의 언어를 표현한다.
      ex) ko로 되어있으면 한글을 보여주고, en으로 되어있으면 영어로된 페이지를 보여줄 수 있다.
      • ko
      • en
    • Content-Length : 길이
      • 실제로는 표현 헤더가 아닌, 페이로드(Payload) 헤더이다.
      • byte 단위로 나타낸다.

 

컨텐츠 협상(Content Negotiation)

  • 클라이언트가 선호하는 표현을 요청한다.
  • 요청시에만 사용되는 Header이다.
  • 우선 순위가 존재한다.
    • Quality Values 줄여서 q 값을 사용한다.
    • 0 ~ 1 사이의 값이 존재하며 1에 가까울수록 우선순위가 높다.
    • Value가 1인 경우 생략이 가능하다.
    ex) Accept-Language: ko-KR,en-US;q=0.9,en;q=0.8
  • → 서버에서 지원 가능하다면 우선순위를 기반으로 응답 데이터를 표현한다.
  • q가 생략되었다면 선언된 순서대로 우선순위를 가진다.→ application/json ⇒ text/plain ⇒ */*
  • ex2) Accept: application/json, text/plain, */*
  • 구체적으로 선언된 것이 우선순위가 높다.→ text/plain;format=flowed ⇒ text/plain ⇒ text/* ⇒ */*
  • ex1) Accpet: text/*, text/plain, text/plain;format=flowed, */*
  • 종류
    • Accept : 선호하는 미디어 타입
    • Accept-Charset : 선호하는 문자 인코딩
    • Accept-Encoding : 선호하는 압축 인코딩
    • Accept-Language : 선호하는 언어

 

일반 정보

  • 단순한 정보들을 나타내는 Header 이다.
  • 종류
    • From : 클라이언트 이메일 정보
      • 잘 사용하지 않는다.
    • Referer : 현재 요청된 페이지의 이전 웹 페이지 주소
      • 유입 경로 파악 가능
      • 요청시 사용하는 Header
    • User-Agent : 클라이언트 애플리케이션 정보(PC, Mobile 브라우저)
      • 어떤 환경에서 주로 접속하는지 통계
      • 어떤 종류의 환경에서 장애가 발생하는지 파악 가능
      • 요청시 사용하는 Header
    • Server : 요청을 처리하는 ORIGIN 서버의 Software 정보
      • 응답에서 사용한다.
    • Date : HTTP 요청이 발생한 날짜와 시간
      • 응답에서 사용한다.

 

특별 정보

  • 종류
    • Host : 요청한 도메인 정보
      • 필수적으로 포함해야하는 Header 이다.
      • 요청시 사용한다.
    • Location : 생성된 리소스 URI, 리다이렉트 주소
      • 응답코드 3xx와 함께 응답되면 리다이렉트 주소이다.
      • 응답코드 201(Created)와 함께 응답되면 생성된 리소스의 URI 이다.
    • Allow : 허용 가능한 HTTP Method
      • 405 (Method Not Allowed)와 함께 응답된다.
      ex) Allow: GET, POST

    • Retry-After : 다음 요청까지 대기 해야하는 시간
      • 503 (Service Unavailable)와 함께 서비스가 언제까지 사용이 불가한지 알려준다.
      • 초단위, 날짜단위 모두 표현이 가능하다.

 

인증

  • 종류
    • Authorization : 클라이언트 인증 정보
      • 선택한 인증 방법에 따라 Value를 작성한다.
    • WWW-Authenticate : 리소스에 필요한 인증 방법
      • 401 (Unauthorized) 응답과 함께 사용된다.

 

Cookie

  • 클라이언트(주로 웹 브라우저)에 저장되는 작은 데이터 조각으로, 웹 애플리케이션이 클라이언트 상태 정보를 저장하고 사용할 수 있도록 설계되었습니다. 서버와 클라이언트 간의 상태를 유지하거나 사용자 맞춤형 경험을 제공하는 데 사용됩니다.
  • HTTP는 Stateless 특성을 가지고 있어서 상태를 매번 보내주어야 한다.
  • Cookie를 사용하여 모든 요청마다 상태를 전달한다.
  • 사용자 세션 관리, 광고 정보 트래킹에 많이 사용된다.

 

[0]  Stateless

  • HTTP는 무상태(Stateless) 프로토콜이다.
  • 클라이언트와 서버가 요청과 응답을 주고 받으면 연결이 끊어진다.
  • 클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못한다.
  • 클라이언트와 서버는 서로 상태를 유지하지 않는다
  • 그래서 Cookie가 생겼다

 

[1]  Cookie의 주요 특징

  1. 클라이언트 저장: 쿠키는 클라이언트(브라우저)에 저장되며, 동일한 도메인으로의 요청 시 서버로 자동 전송됩니다.
  2. 짧은 크기 제한: 쿠키 데이터는 일반적으로 약 4KB로 제한됩니다.
  3. 보안 옵션 제공: 쿠키는 HttpOnly, Secure, SameSite 등의 옵션으로 보안을 강화할 수 있습니다. 
  4. 만료 시간 설정: 쿠키는 일정 시간 동안만 유효하거나, 브라우저가 종료되면 삭제될 수 있습니다.
  5. 항상성 : 쿠키 정보는 항상 서버에 전송됩니다. 그로인해 네트워크 트래픽이 추가 유발되며 이를 최소화하기 위해 최소한의 정보(세션 id, 인증 토큰)만을 사용합니다. 서버에 전송하지 않고 웹 브라우저 내부에 저장할 경우 웹 스토리지를 사용합니다.
  6. 정보 보호 : 서버처럼 데이터를 철저히 관리하기는 힘든 클라이언트 환경 상 보안에 민감한 데이터는 저장해서는 안됩니다.

 

  • 종류
    • Set-Cookie : 서버에서 클라이언트로 쿠키 전달(응답)
      • 만료기간(expire, max-age), 사용될 위치(domain, path)를 설정할 수 있다.
      • 주의
        • 항상 서버에 전달되니 최소한의 정보만 사용하여 트래픽을 최적화 시켜야 한다.
        • 탈취 당하기 쉬우니 보안에 민감한 개인정보 등은 저장하지 않는다.
    • Cookie : 클라이언트가 서버에서 받은 쿠키를 Cookie 헤더를 통해 전송한다.
    • Secure : 해당 헤더가 적용되면 https인 경우에만 쿠키를 전송한다.
      • 기본적으로 http, https 구분하지 않고 쿠키를 전송한다.
      • HTTP + Secure 가 HTTPS 이다.
    • HttpOnly : http 전송에만 사용한다.
      • 자바스크립트에서 쿠키를 접근하지 못하게 만든다.
    • SameSite : 쿠키에 설정된 도메인이 같은 경우만 쿠키를 전송한다.

 

쿠키의 구성요소

 

[2]  쿠키 생명주기

  • Set-Cookie: expires=Sat, 26-Dec-2020 04:39:21 GMT  =  만료일이 되면 쿠키 삭제
  • Set-Cookie: max-age=3600 (3600초)  =  0이나 음수를 지정하면 쿠키 삭제
  • 세션 쿠키: 만료 날짜를 생략하면 브라우저 종료시 까지만 유지
  • 영속 쿠키: 만료 날짜를 입력하면 해당 날짜까지 유지

 

[3]  쿠키 도메인

예) domain=example.org

  • 명시: 명시한 문서 기준 도메인 + 서브 도메인 포함 접근 가
    • domain=example.org를 지정해서 쿠키 생성
      • example.org는 물론이고
      • dev.example.org도 쿠키 접근

생략: 현재 문서 기준 도메인만 적용

  • example.org 에서 쿠키를 생성하고 domain 지정을 생략
    • example.org 에서만 쿠키 접근
    • dev.example.org는 쿠키 미접근

 

[4]  쿠키 경로

예) path=/home

이 경로를 포함한 하위 경로 페이지만 쿠키 접근

일반적으로 path=/ 루트로 지정

예)

  • path=/home 지정
  • /home -> 가능
  • /home/level1 -> 가능
  • /home/level1/level2 -> 가능
  • /hello -> 불가능

 

[5]  쿠키 보안

Secure

  • 쿠키는 http, https를 구분하지 않고 전송
  • Secure를 적용하면 https인 경우에만 전송

HttpOnly

  • XSS 공격 방지
  • 자바스크립트에서 접근 불가(document.cookie)
  • HTTP 전송에만 사용

SameSite

  • XSRF 공격 방지
  • 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송

 

 

Cache

  • 데이터나 요청의 결과를 임시로 저장하여, 같은 데이터나 요청이 반복될 때 성능을 향상시키는 기술입니다. 주로 자주 사용되는 데이터에 빠르게 접근하거나, 네트워크 트래픽을 줄이는 데 사용됩니다.
  • 캐시가 없다면 같은 요청에 대한 응답 데이터가 같아도 매번 데이터를 새로 다운로드 받는다.
  • 새로 다운로드 받는만큼 속도가 느려지고, 비용이 발생한다.
  • 덕분에 캐시 가능 시간동안 네트워크를 사용하지 않아도 된다. 네트워크 사용량이 감소하고 로딩 속도가 증가하여 빠른 사용자 경험을 만들 수 있다.
  • 캐시 가능시간이 지나면 다시 서버에서 데이터를 받아와 브라우저 캐시에 저장하여 다시 캐시로 사용한다.

 

 

 

[1] Cache의 주요 특징

  1. 빠른 응답: 캐시된 데이터를 사용하면 서버에 요청하지 않고도 데이터를 제공하여 빠른 응답을 제공합니다.
  2. 네트워크 절약: 동일한 요청을 줄임으로써 네트워크 트래픽을 줄입니다.
  3. 만료 시간: 캐시는 유효 기간(expiration)이 있으며, 설정된 시간이 지나면 새롭게 데이터를 받아옵니다.
  4. 다양한 계층: 클라이언트(브라우저 캐시), 서버(서버 캐시), 네트워크 중간(프록시 캐시) 등 다양한 계층에서 작동합니다.

[2] Cache의 주요 사용 사례

  1. 웹 브라우저 캐시: 이미지, CSS, JavaScript 파일을 브라우저에 저장해 페이지 로딩 속도를 향상.
  2. 데이터베이스 캐시: 자주 조회되는 데이터를 캐시에 저장해 데이터베이스 부하 감소.
  3. API 요청 캐시: 동일한 API 요청의 결과를 캐시해 서버의 작업 부담 완화.

[3] Cache 관련 HTTP 헤더

캐시는 HTTP 요청과 응답에 포함된 **캐시 제어 헤더(Cache-Control, Expires 등)**로 관리됩니다.

헤더 설명 예시
Cache-Control 캐싱 정책을 정의. Cache-Control: max-age=3600
Expires 캐시가 만료되는 시점을 명시 (HTTP 1.0). Expires: Wed, 15 Nov 2024 08:12:31 GMT
ETag 리소스의 고유 식별자. 변경 여부를 판별. ETag: "abc123"
Last-Modified 리소스가 마지막으로 수정된 시간. Last-Modified: Tue, 14 Nov 2024 12:00:00 GMT
Vary 캐싱 조건을 설정 (e.g., Accept-Language에 따라 다르게 캐싱). Vary: Accept-Language
Pragma HTTP/1.0에서 캐시 무효화를 위한 지시어(주로 no-cache). Pragma: no-cache

[4] Cache 동작 방식

  1. 클라이언트 요청 → 서버 응답 (캐시 저장)
    클라이언트가 리소스를 요청하면 서버는 응답과 함께 캐시 지시어(Cache-Control)를 전송합니다.
    예: Cache-Control: max-age=3600 → 1시간 동안 캐싱.
  2. 캐시된 데이터 사용
    같은 요청이 반복되면 서버에 다시 요청하지 않고, 캐시된 데이터를 사용합니다.
  3. 검증 후 캐시 사용
    • 만약 서버에서는 데이터가 바뀌었는데 캐시에서는 내용이 안 바뀐경우 정보의 불일치성이 나타나니 그걸 막기위해 서버와 캐시의 데이터가 같은지 확인할 필요가 있다.
    • ETag 또는 Last-Modified 헤더를 사용해 리소스가 변경되지 않았는지 확인합니다.
    • 서버가 변경되지 않았음을 확인하면 304 Not Modified 응답과 함께 캐시된 데이터를 재사용합니다.
더보기

 

 

 


[5] Cache 무효화와 갱신

캐시는 만료되거나 조건에 따라 갱신됩니다.

  1. Cache-Control 지시어
    • no-cache: 캐시 사용 전에 반드시 서버에서 검증.
    • no-store: 데이터를 캐시에 저장하지 않음.
    • max-age: 캐시된 데이터의 유효 기간(초 단위).
  2. Expires 헤더
    • HTTP/1.0에서 사용. 특정 시간 이후 캐시 만료.
  3. ETag과 Last-Modified
    • 변경 여부를 서버에서 확인하여 필요한 경우만 새 데이터를 받아옵니다.

[6] Cache 배달에 비유

  • 캐시자주 주문하는 음식의 레시피 메모와 같습니다.
    • 음식점에서 자주 주문하는 음식을 미리 메모해 두면 다음 주문 시 빠르게 준비할 수 있습니다.
    • Cache-Control: max-age=3600 → "1시간 동안은 이 메모를 믿고 준비해도 괜찮아요."
    • ETag → "음식 레시피가 바뀌었는지 확인하는 체크리스트."
    • no-cache → "항상 먼저 사장님에게 레시피가 최신인지 물어보고 사용해요."

이 비유를 통해 캐시의 동작 방식과 설정을 쉽게 이해할 수 있습니다.

 

  • 종류
    • Cache-Control
      • 응답시 사용하는 헤더이다.
      • Cache-Control: max-age
        • 캐시 유효 시간(초)
        • 캐시 유효 시간이 지나면 다시 서버를 통해 데이터를 응답받고 캐시를 갱신한다.
      • Cache-Control: no-cache
        • 캐시 가능한 데이터지만, 서버에 검증하고 사용해야 한다.
      • Cache-Control: no-store
        • 보안에 민감한 데이터, 캐시하지 않는다.
    • if-modified-since : 캐시로 저장된 데이터 최종 수정일
      • 요청시 사용하는 헤더이다.
    • Last-Modified : 데이터가 마지막으로 수정된 시간
      • if-modified-since 요청이 오면 응답한다.
      • 304 (Not Modified) 상태코드와 함께 응답되면 수정되지 않았다는 의미
        • HTTP Message Body가 존재하지 않는다. 캐시 사용
      • 응답시 사용하는 헤더이다.
    • ETag : 캐시용 데이터에 날짜, 시간이 아닌 이름을 지정한다.
      • if-modified-since + Last-Modified 방식은 수정된 데이터가 같거나 캐시가 불필요한 경우를 구분하지 못한다.
      • 요청시 사용하는 헤더이다.

 

캐시(Cache)와 쿠키(Cookie)의 차이

  • 캐시는 자주 시키는 음식의 레시피를 가게에 저장하여 빠르게 조리하는 것 = "저번에 먹었던 메뉴 그대로 주세요."
  • 쿠키는 단골 손님을 메모하여 고객 맞춤 서비스를 제공 = "이 고객은 항상 매운맛을 선택하시지"

 

검증 헤더와 조건부 요청

검증 헤더 조건부 요청 헤더
캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
Last-Modied , ETag
검증 헤더로 조건에 따른 분기
If-Modied-Since: Last-Modied 사용
If-None-Match: ETag 사용
조건이 만족하면 200 OK
조건이 만족하지 않으면 304 Not Mod

 

[0]  예시

If-Modied-Since: 이후에 데이터가 수정되었으면?

  • 데이터 미변경 예시
    • 캐시: 2020년 11월 10일 10:00:00 vs 서버: 2020년 11월 10일 10:00:00
    • 304 Not Modied, 헤더 데이터만 전송(BODY 미포함)
    • 전송 용량 0.1M (헤더 0.1M)
  • 데이터 변경 예시
    • 캐시: 2020년 11월 10일 10:00:00 vs 서버: 2020년 11월 10일 11:00:00
    • 200 OK, 모든 데이터 전송(BODY 포함)
    • 전송 용량 1.1M (헤더 0.1M, 바디 1.0M)

 

[1]  Last-Modied, If-Modied-Since 단점

  • 1초 미만(0.x초) 단위로 캐시 조정이 불가능
  • 날짜 기반의 로직 사용
  • 데이터를 수정해서 날짜가 다르지만, 같은 데이터를 수정해서 데이터 결과가 똑같은 경우
  • 서버에서 별도의 캐시 로직을 관리하고 싶은 경우
    • 예) 스페이스나 주석처럼 크게 영향이 없는 변경에서 캐시를 유지하고 싶은 경우

 

[2]  ETag, If-None-Match

  • ETag(Entity Tag)
  • 캐시용 데이터에 임의의 고유한 버전 이름을 달아둠
    • 예) ETag: "v1.0", ETag: "a2jiodwjekjl3"
  • 데이터가 변경되면 이 이름을 바꾸어서 변경함(Hash를 다시 생성)
    • 예) ETag: "aaaaa" -> ETag: "bbbbb"

 

ETag의 동작 방식 요약

  • 클라이언트는 서버에서 받은 ETag 값을 저장하고, 이후 동일한 데이터를 요청할 때 이 값을 서버에 보냄.
  • 서버는 클라이언트가 보낸 ETag와 현재 데이터의 ETag를 비교:
    • ETag가 같으면: 데이터가 변경되지 않았으므로 304 Not Modified를 응답. 클라이언트는 기존 캐시 데이터를 그대로 사용.
    • ETag가 다르면: 데이터가 변경되었으므로, 새 데이터를 제공하고 새로운 ETag 값을 함께 반환.
    • 기존의 방식이면 동일한 요청을 하면 계속 데이터를 보내줬는데, ETag만 보고 같은 요청이면 데이터 안보내고, 같은 요청을 보냈습니다. 라고만 답변하면 되니, 네트워크 트래픽이 감소한다.

 

  • 진짜 단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받기!
  • 캐시 제어 로직을 서버에서 완전히 관리(해시값[ ETag ]을 여기서 지정, 클라에 전송, 클라에서 인증을 위해 보내면 인증까지 여기서 싹다 한)
  • 클라이언트는 탄순히 이 값을 서버에 제공하다보니(해시값을 전달받고 클라에 저장해두는게 끝이라) 클라이언트는 캐시 메커니즘을 모른다.
  • ex) 서버는 배타 오픈 기간인 3일 동안 파일이 변경되어도 ETag를 동일하게 유지, 배포주기에 맞춰 갱신

 


ETag가 필요한 이유

1. 네트워크 트래픽 감소

  • 클라이언트가 서버에 요청할 때, 항상 데이터를 다시 다운로드하면 네트워크 트래픽이 증가해.
  • ETag를 사용하면, 서버는 데이터를 변경하지 않았을 때 304 Not Modified로 응답만 보내고, 데이터를 다시 전송하지 않아도 돼.
    • 효과: 불필요한 데이터 전송을 줄여 네트워크 사용량 절감.

2. 서버 부하 감소

  • 리소스가 변경되지 않은 경우, 서버는 ETag 비교만으로 빠르게 응답할 수 있어.
  • 이를 통해:
    • CPU와 메모리 사용량 감소.
    • 디스크 I/O 감소 (특히 정적 파일이나 대규모 데이터 처리 시).
    • 대규모 트래픽 처리 효율 향상.

3. 사용자 경험(UX) 향상

  • 클라이언트가 데이터 변경 여부를 빠르게 확인하고, 변경되지 않은 경우 캐시 데이터를 즉시 사용.
  • 데이터가 변경되지 않았으면 응답 속도가 더 빨라져 페이지 로딩 시간 단축.
    • 예: 사용자가 이미 본 이미지나 데이터를 다시 다운로드하지 않아도 되니까 웹사이트가 더 빠르게 반응.

4. 효율적인 캐싱 관리

  • 서버가 데이터의 변경 여부를 완전히 제어하기 때문에, 클라이언트는 캐싱 메커니즘을 신경 쓰지 않아도 돼.
  • 서버는 ETag를 활용해 다음을 보장:
    • 데이터가 변경되면 클라이언트가 항상 최신 데이터를 받음.
    • 데이터가 변경되지 않았으면 기존 데이터를 재사용.

예시: 실생활에서의 필요성

1. 이미지 파일 변경

  • 상황:
    • 웹사이트가 매일 새로운 배너 이미지를 제공.
    • 사용자는 이미 배너 이미지를 다운로드했는데, 이미지가 변경되지 않았다면 재다운로드할 필요가 없어.
  • 해결:
    • 서버가 이미지에 대해 ETag를 설정.
    • 사용자가 다시 이미지를 요청할 때, 기존 ETag를 서버에 보내 변경 여부를 확인.
    • 변경 없음: 클라이언트는 기존 캐시된 이미지를 사용.
    • 변경 있음: 서버가 새로운 이미지를 제공.

2. 웹 애플리케이션의 정적 리소스 (JS, CSS, HTML)

  • 상황:
    • 대규모 웹사이트에서 JavaScript와 CSS 파일은 자주 변경되지 않지만, 가끔 업데이트됨.
    • 매번 모든 사용자가 모든 정적 파일을 다운로드하면 서버 부하가 커져.
  • 해결:
    • ETag를 사용해 파일 변경 여부를 판단.
    • 변경되지 않은 정적 파일은 클라이언트가 캐시에서 로드.

3. API 응답 관리

  • 상황:
    • 클라이언트가 REST API를 호출해 데이터를 요청.
    • 서버 데이터가 자주 변경되지 않는 경우가 많음(예: 공공 데이터, 날씨 정보).
  • 해결:
    • 서버는 API 응답에 ETag를 포함.
    • 클라이언트가 다시 데이터를 요청할 때 ETag를 제공.
    • 변경 없음: 304 Not Modified 응답.
    • 변경 있음: 새로운 데이터를 제공.

ETag가 필요한 이유 정리

문제점 ETag가 제공하는 해결책

네트워크 트래픽 과다 변경되지 않은 데이터는 다시 다운로드하지 않음.
서버 부하 증가 데이터 변경 여부만 확인하여 처리 효율화.
사용자 경험 저하 클라이언트가 빠르게 캐시된 데이터 재사용 가능.
캐싱 데이터의 유효성 보장 필요 서버가 데이터 변경 여부를 제어하여 최신 데이터 제공.

ETag가 없으면?

  1. 모든 요청마다 전체 데이터를 다운로드:
    • 변경되지 않은 데이터라도 항상 새로 요청하고 다운로드해야 해서 네트워크와 서버 리소스를 낭비.
  2. 클라이언트가 최신 데이터를 사용하지 못할 가능성:
    • 서버가 변경된 데이터를 제공했지만, 클라이언트가 여전히 오래된 캐시 데이터를 사용할 수 있음.
  3. 규모가 큰 서비스에서 성능 저하:
    • 대규모 트래픽 환경에서, 불필요한 요청 처리가 쌓이면 서버 성능이 저하될 수 있음.

결론

ETag는 네트워크와 서버 리소스를 절약하고, 최신 데이터를 빠르게 제공하며, 클라이언트와 서버 간 데이터 일관성을 유지하기 위해 필요한 기술이야. 특히, 정적 리소스나 API 응답 같은 데이터를 효율적으로 관리할 때 유용해! 🚀

 

 

캐시와 조건부 요청 헤더

 

[0]  Cache-Control: 캐시 제어

Cache-Control: max-age

  • 캐시 유효 시간, 초 단위

Cache-Control: no-cache

  • 데이터는 캐시해도 되지만, 항상 원(origin) 서버에 검증하고 사용

Cache-Control: no-store

  • 데이터에 민감한 정보가 있으므로 저장하면 안됨 (메모리에서 사용하고 최대한 빨리 삭제)

 

[1]  Pragma: 캐시 제어(하위 호환)

  • Pragma: no-cache
  • HTTP 1.0 하위 호환

 

[2]  Expires: 캐시 유효 기간(하위 호환)

  • expires: Mon, 01 Jan 1990 00:00:00 GMT

 

  • 캐시 만료일을 정확한 날짜로 지정
  • HTTP 1.0 부터 사용
  • 지금은 더 유연한 Cache-Control: max-age 권장
  • Cache-Control: max-age와 함께 사용하면 Expires는 무시

 

 

프록시 캐시

📌 클라이언트와 서버 사이에 위치한 중간 캐시 시스템으로, 요청을 처리할 때 리소스를 대신 저장하고 제공하는 역할을 합니다. 주로 웹 서버와 클라이언트 사이에서 네트워크 트래픽을 줄이고 응답 시간을 개선하며 서버 부하를 줄이기 위해 사용됩니다.

  • 유튜브 영상을 생각하면 편하다. 미국 서버에 있는 데이터를 직접 불러오면 당연히 서버내의 모든 데이터를 불러올 수 있지만 당연히 느려진다. 하지만 한국 서버에 많이 시청하는 영상이 따로 저장이 되어 있다면? 한국에서도 해당 영상들은 빠르게 시정 가능하다.

 

 

Cache-Control

캐시 지시어(directives) - 기타

 

  • Cache-Control: public
    • 응답이 public 캐시에 저장되어도 됨
  • Cache-Control: private
    • 응답이 해당 사용자만을 위한 것임, private 캐시에 저장해야 함(기본값)
  • Cache-Control: s-maxage
    • 프록시 캐시에만 적용되는 max-age
  • Age: 60 (HTTP 헤더)
    • 오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간(초)

 

 

캐시 무효화

📌 웹페이지에서 자기들끼리 캐시를 멋대로 생성하는 경우가 있는데, 이걸 막는 것을 말한다.

  • 통장 잔고처럼 계속 업데이트 되는 것의 경우 캐시를 지정해도 계속 변경을 해줘야하니 비효율적이다. 이런 경우는 캐시를 지정했다면 무효화하는게 좋다.

 

[0]  확실한 캐시 무효화 응답

  • Cache-Control: no-cache, no-store, must-revalidate
  • Pragma: no-cache
    • HTTP 1.0 하위 호환

 

[1]  캐시 지시어(directives) - 확실한 캐시 무효화

 

Cache-Control: no-cache

  • 데이터는 캐시해도 되지만, 항상 원 서버에 검증하고 사용(이름에 주의!)

Cache-Control: no-store

  • 데이터에 민감한 정보가 있으므로 저장하면 안됨 (메모리에서 사용하고 최대한 빨리 삭제)

Cache-Control: must-revalidate

  • 캐시 만료후 최초 조회시 원 서버에 검증해야함
  • 원 서버 접근 실패시 반드시 오류가 발생해야함 - 504(Gateway Timeout)
  • must-revalidate는 캐시 유효 시간이라면 캐시를 사용함

Pragma: no-cache

  • HTTP 1.0 하위 호환

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] Restful API  (1) 2024.12.02
[Net] HTTP 요청 데이터  (0) 2024.12.02
[Net] HTTP Method  (2) 2024.11.30
[Net] HTTP  (0) 2024.11.29
[Net] JSON  (1) 2024.11.29

 

HTTP Method

📌 클라이언트 - 서버 사이에 이루어지는 요청, 응답 데이터를 전송하는 방식을 뜻한다.

 

[1]  POST

  • 리소스 생성
  • 요청 데이터 처리, 메시지 바디를 통해 서버로 요청 데이터 전달
  • 요청 데이터 처리 방식은 요청마다 다르므로 여기가 코딩하는 부분
  • 메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행한다.
  • 주로 전달된 데이터로 신규 리소스 등록, 프로세스 처리에 사용
더보기

POST 요청 데이터를 어떻게 처리한다는 뜻일까?

 

예시

• 스펙: POST 메서드는 대상 리소스가 리소스의 고유 한 의미 체계에 따라 요청에 포함 된 표현을 처리하도록 요청합니다. (구글 번역)

• 예를 들어 POST는 다음과 같은 기능에 사용됩니다.

 

• HTML 양식에 입력 된 필드와 같은 데이터 블록을 데이터 처리 프로세스에 제공

예) HTML FORM에 입력한 정보로 회원 가입, 주문 등에서 사용

 

• 게시판, 뉴스 그룹, 메일링 리스트, 블로그 또는 유사한 기사 그룹에 메시지 게시

예) 게시판 글쓰기, 댓글 달기

 

• 서버가 아직 식별하지 않은 새 리소스 생성

예) 신규 주문 생성

 

• 기존 자원에 데이터 추가

예) 한 문서 끝에 내용 추가하기

 

• 정리: 이 리소스 URI에 POST 요청이 오면 요청 데이터를 어떻게 처리할지 리소스마다 따로 정해야 함 -> 정해진 것이 없음

  • 클라 요청 - 서버 신규 Resource 생성 - 응답
  • 주로 HTML FORM(회원가입, 게시글 작성 등)에 사용된다.
  • 요청 데이터를 처리하는 방식에 정해진것은 없다.
    1. 요청 데이터 처리(로그인 등)에 사용한다.
    2. 조회시 JSON 요청 데이터가 필요한 경우에도 사용될 수 있다.
  • Message Body를 통해 요청 데이터를 전달한다.

정리

1. 새 리소스 생성(등록)

• 서버가 아직 식별하지 않은 새 리소스 생성

 

2. 요청 데이터 처리

단순히 데이터를 생성하거나, 변경하는 것을 넘어서 프로세스를 처리해야 하는 경우

• 예) 주문에서 결제완료 -> 배달시작 -> 배달완료 처럼 단순히 값 변경을 넘어 프로세스의 상태가 변경되는 경우

• POST의 결과로 새로운 리소스가 생성되지 않을 수도 있음

• 예) POST /orders/{orderId}/start-delivery (컨트롤 URI)

 

3. 다른 메서드로 처리하기 애매한 경우

• 예) JSON으로 조회 데이터를 넘겨야 하는데, GET 메서드를 사용하기 어려운 경우

애매하면 POST


[2]  GET

  • 리소스 조회
  • 서버에 전달하고 싶은 데이터는 query(쿼리 파라미터, 쿼리 스트링)를 통해서 전달
  • 메시지 바디를 사용해서 데이터를 전달할 수 있지만, 지원하지 않는 곳이 많아서 권장하지 않음

1. Query String 미포함하는 경우

  • GET의 경우 Message Body가 지원되지 않는 경우가 많아 권장하지 않는다.

 

 

2. Query String 포함하는 경우

 

  • 서버에 추가적인 데이터 전송을 해야한다면, Message Body가 아닌 Query String(Query Parameter)를 사용한다.

[3]  PUT

  • 리소스 덮어쓰기, 없으면 생성도 함
  • POST와는 다르게 클라이언트 측에서 리소스를 식별하여 URI를 지정한다.

1. 기존 리소스가 존재하는 경우

리소스 전체 수

 

2. 기존 리소스가 존재하고 일부만 변경하는 경우 중요!

기존 리소스가 존재하면 완전히 덮어쓰기가 된다.

 

3. 기존 리소스가 없는 경우

새로 생성된다


[4]  PATCH

  • 리소스 부분 수정


[5]  DELETE

  • 리소스 삭제


[6]   기타 Method

  • HEAD
    • GET에서 Message Body를 제외하고 상태 줄과 헤더만 반환한다.
  • OPTIONS
    • 대상 리소스에 대한 통신 가능한 Method를 설명한다.
  • CONNECT
    • 대상 자원으로 식별되는 서버에 대한 터널을 설정한다.
    • 잘 사용하지 않는다.
  • TRACE
    • 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행한다.
    • 잘 사용하지 않는다.

 

메서드 설명 배달에 비유한 예시 용도
GET 서버에서 데이터를 조회하는 메서드 배달된 상품을 조회하는 과정: "배달 상태를 확인하기 위해 배달업체에 연락" 데이터를 가져오기 위한 요청 (예: 웹 페이지 조회) GET /index.html HTTP/1.1
POST 서버에 데이터를 보내는 메서드 새로운 상품 주문하기: "새로운 피자를 주문하여 배달을 요청" 데이터를 서버에 제출하거나 생성 (예: 새 사용자 등록) POST /users HTTP/1.1
PUT 서버의 기존 데이터를 수정하거나 새 데이터를 생성하는 메서드 기존 주문 수정하기: "기존 주문한 피자 크기를 바꾸거나 새로 주문" 데이터 업데이트 또는 생성 (예: 기존 정보를 수정하거나 새로운 리소스를 추가) PUT /users/1 HTTP/1.1
DELETE 서버의 데이터를 삭제하는 메서드 배달된 상품 취소하기: "이미 주문한 피자를 취소하고 배달을 중지" 리소스를 삭제 (예: 사용자 계정 삭제) DELETE /users/1 HTTP/1.1
HEAD GET과 유사하지만, 응답 본문을 제외한 헤더만 반환하는 메서드 배달의 세부 사항만 확인: "배달된 상품이 무엇인지, 배달 상태를 확인" 헤더만 조회하고 본문을 무시 (예: 서버의 메타데이터 확인) HEAD /index.html HTTP/1.1
OPTIONS 서버가 지원하는 HTTP 메서드 목록을 반환하는 메서드 배달 가능한 옵션 확인: "어떤 상품이 가능한지, 또는 선택 가능한 배달 방법이 무엇인지 확인" 서버가 지원하는 메서드 및 기능을 확인 (예: 서버 기능 검사) OPTIONS /users HTTP/1.1
PATCH 리소스의 일부를 수정하는 메서드 부분 주문 수정: "피자의 일부만 수정해서 추가 주문" 리소스의 일부만 수정 (예: 사용자 정보 일부 수정) PATCH /users/1 HTTP/1.1
TRACE 요청이 서버에 도달하기까지의 경로를 추적하는 메서드 배달 경로 추적: "주문이 어떻게 배송되는지 확인하기 위해 배달업체에 문의" 요청 경로 추적 (예: 디버깅용, 요청이 서버에 어떻게 도달했는지 확인) TRACE / HTTP/1.1
CONNECT 터널을 설정하여 클라이언트와 서버 간에 데이터를 전달하는 메서드 배달 중간에 통로 연결: "배달을 위한 안전한 경로를 설정" 프록시 서버를 통한 보안 연결 설정 (예: SSL 연결을 위한 터널링) CONNECT www.example.com:443 HTTP/1.1

 

 

HTTP Method 속성

📌 HTTP Method는 안전성(Safe), 멱등성(Idempotent), 캐시가능성(Cacheable) 속성을 가지고 있다. 각각의 속성이 무엇인지와 어떤 HTTP Method가 해당 특성을 가지고 있는지 알아보자.

  • HTTP Method별 속성표

사진출처 : https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

 

  • Optional은 Java의 Optional과 같이 있을 수 있다라는 말과 같다.

[1]  안전성(Safe)

호출해도 리소스를 변경하지 않는다.

• Q: 그래도 계속 호출해서, 로그 같은게 쌓여서 장애가 발생하면요?

• A: 안전은 해당 리소스만 고려한다. 그런 부분까지 고려하지 않는다

  • GET 메소드(조회)는 안전하다.
    • 저장된 데이터를 변환하지 않는다.
  • POST, DELETE, PUT, PATCH는 안전하지 않다.
    • 데이터를 생성, 수정, 삭제한다.

 

[2]  멱등성(Idempotent)

  • 한번을 호출하거나 수천번을 호출하거나 항상 결과는 같다.
    1. GET → 같은 결과가 계속 조회된다.
    2. PUT → 수정해서 대체된 후의 결과는 계속 같다.
    3. DELETE → 같은 요청을 여러번해도 삭제된 결과는 같다.
    4. POST → 멱등성을 보장하지 않는다.
    ex) 계좌 송금을 두번한다면?, 게시판 글쓰기, 회원가입

  • 요청이 실패한 경우 재시도 하기위해 필요하다.
    1. 항상 결과가 같다면 마음껏 재시도 해도된다.
    2. 만약 멱등하지 않다면, 중복 요청을 보내서는 안된다.
    3. 복구 매커니즘에 사용한다.
    ex) 요청 실패시 서버에서 자동으로 재시도

  • 리소스 조회(GET Method) 재요청 중간에 변경된다면?

  • 재요청 중간에 리소스가 변경되는것은 멱등성으로 고려하지 않는다.

ex) 도서관 책 재고 조회(실시간으로 대여 혹은 판매됨)

 

[3]  캐시가능성 (Cacheable)


HTTP 메서드와 캐싱 가능성

  • HTTP 캐싱서버 응답을 클라이언트(브라우저)나 중간 캐시 서버에 저장하여, 동일한 요청에 대해 다시 서버와 통신하지 않고도 응답을 재사용할 수 있게 하는 기능입니다.
  • 캐시 가능성은 특정 HTTP 메서드가 반환하는 응답이 캐시에 저장될 수 있는지 여부를 나타냅니다.

HTTP 메서드와 캐싱

  1. GET
    • 캐시 가능하며, 주로 정적 자원(HTML, CSS, JS, 이미지 등)에 사용됩니다.
    • 변경 가능성이 적은 데이터를 효율적으로 제공하기 위해 캐시가 널리 사용됩니다.
  2. HEAD
    • 캐시 가능하며, GET 메서드와 유사하게 작동하지만 응답 본문 없이 헤더만 반환합니다.
    • 응답 본문이 없으므로 캐시를 검증하거나 메타데이터를 요청하는 데 적합합니다.
  3. POST
    • 일반적으로 캐싱하지 않음.
    • POST는 데이터 생성 또는 서버 상태 변경 요청에 사용되므로, 캐싱이 의미 없는 경우가 많습니다.
    • 다만, 명시적으로 캐싱이 허용된 경우(예: 특정 API)에는 캐싱이 가능합니다.
    • GET은 서버로 데이터를 불러오기만 하지만 POST는 요청 내용이 항상 다른데, 전의 요청 내용 답변을 캐시에 저장해 둬도, 다음 대답에서 해당 캐시를 사용하게 될지는 미지수이기 때문 = 캐시 시 의도하지 않은 동작을 하는 경우가 있음 [의도하지 않은 동작은 아래 접은 글 참조]
더보기

1. POST 요청 중복 처리

상황:

  • 사용자가 POST 요청으로 서버에 데이터를 생성.
  • 서버는 요청에 따라 새 주문을 생성하고, 성공 응답을 반환.

예시:

  1. 사용자가 상품을 주문:
    POST /orders
    Request Body: {"productId": 101, "quantity": 1}
    
  2. 서버는 새 주문을 생성하고 응답:
    HTTP/1.1 200 OK
    Response Body: {"orderId": 123, "status": "created"}
    
  3. 캐시 활성화로 인해 동일한 POST 요청이 캐시됨.
  4. 사용자가 동일한 요청을 다시 보냄:
    • 브라우저나 네트워크 레벨에서 캐시된 응답을 반환.
    • 그러나 실제로는 서버에서 새 주문이 생성되지 않았음.
  5. 결과:
    • 사용자에게 잘못된 응답을 제공하거나,
    • 의도치 않게 중복 주문이 발생.

2. 사용자 인증 토큰 갱신 실패

상황:

  • 사용자가 POST 요청으로 인증 토큰을 갱신(refresh)하려고 함.
  • 서버는 요청 시마다 새로운 토큰을 생성하여 반환.

예시:

  1. 사용자가 토큰 갱신 요청:
    POST /auth/refresh
    
  2. 서버가 새 토큰 반환:
    HTTP/1.1 200 OK
    Response Body: {"token": "new-token-123"}
    
  3. 캐시가 응답을 저장.
  4. 사용자가 토큰 갱신 요청을 다시 보냄.
    • 캐시된 응답이 반환되어 새 토큰이 아닌 이전 토큰을 사용.
  5. 결과:
    • 토큰 만료로 인해 인증 실패.
    • 사용자가 시스템에 접근 불가.

3. 결제 요청 중복 처리

상황:

  • 사용자가 결제를 요청하여 서버가 거래를 처리.
  • 서버는 POST 요청으로 결제 데이터를 받고 승인 응답을 반환.

예시:

  1. 사용자가 결제 요청:
    POST /payments
    Request Body: {"amount": 100, "method": "credit_card"}
    
  2. 서버가 결제를 처리하고 응답:
    HTTP/1.1 200 OK
    Response Body: {"transactionId": 456, "status": "approved"}
    
  3. 캐시가 POST 응답을 저장.
  4. 사용자가 동일한 요청을 재전송하거나 네트워크가 요청을 재시도:
    • 서버가 요청을 중복 처리하여 결제가 두 번 이루어짐.
    • 사용자가 의도치 않게 이중 결제를 하게 됨.

4. 회원가입 요청 중복 처리

상황:

  • 사용자가 POST 요청으로 회원가입을 시도.
  • 서버는 데이터를 저장하고 성공 응답 반환.

예시:

  1. 사용자가 회원가입 요청:
    POST /users
    Request Body: {"email": "user@example.com", "password": "secure"}
    
  2. 서버가 데이터를 저장하고 응답:
    HTTP/1.1 201 Created
    Response Body: {"userId": 789, "status": "registered"}
    
  3. 요청이 캐시됨.
  4. 사용자가 다시 요청을 보냄:
    • 캐시된 응답이 반환되거나 서버가 요청을 중복 처리.
    • 동일한 이메일로 중복 회원가입 발생.

5. 상품 재고 업데이트 오류

상황:

  • 서버는 특정 상품의 재고를 업데이트하는 POST 요청을 처리.
  • 재고는 매번 요청할 때 다른 값으로 업데이트되어야 함.

예시:

  1. 요청:
    POST /inventory/update
    Request Body: {"productId": 202, "quantity": 50}
    
  2. 서버가 재고를 업데이트:
    HTTP/1.1 200 OK
    Response Body: {"status": "updated"}
    
  3. 응답이 캐시됨.
  4. 동일한 요청 반복 시 캐시된 응답 반환:
    • 재고 업데이트가 실패하거나,
    • 이전 값으로 덮어써짐.

결론

  • POST 요청의 캐싱은 의도치 않은 동작을 초래할 가능성이 높음.
    • 데이터 생성/수정 작업이 반복될 수 있음.
    • 응답이 캐시되면 서버 상태와 클라이언트가 보관하는 데이터가 불일치할 수 있음.
  • GET 요청은 캐싱에 적합하지만, POST 요청은 신중하게 캐싱해야 함.
    • POST 요청을 캐싱하려면 Cache-Control 헤더를 명시적으로 설정하고, 중복 요청 방지 로직을 추가해야 함.
Cache-Control 헤더는 HTTP/1.1에서 응답 및 요청의 캐싱 동작을 제어하기 위해 사용, 클라이언트(브라우저)와 중간 캐시 서버(프록시, CDN 등)가 리소스를 어떻게 캐싱하고 얼마나 오랫동안 유지해야 하는지에 대한 지침을 제공합니다.

캐싱의 일반적인 활용

  • 캐싱 대상
    • 변경 가능성이 적은 정적 자원:
      • HTML
      • CSS
      • JavaScript
      • 이미지 (JPG, PNG, GIF 등)
    • API 응답 (GET 요청의 경우)
  • 캐싱 설정
    • HTTP 헤더를 통해 캐싱 동작을 제어:
      • Cache-Control: 캐시의 동작 방식을 명시.
      • ETag: 캐시된 리소스가 변경되었는지 확인.
      • Last-Modified: 리소스의 최종 수정 시간을 알려줌.

정리

  • GET, HEAD: 캐싱에 적합하며, 주로 정적 리소스를 대상으로 활용.
  • POST: 일반적으로 캐싱하지 않지만, 명시적으로 허용된 경우 예외적으로 캐싱 가능.
  • 캐싱의 목적: 네트워크 부하 감소, 응답 시간 단축, 성능 최적화.

위와 같이 간결하게 정리된 내용으로 캐싱 가능성을 설명할 수 있습니다. 😊

  • 캐싱 가능성(Cacheable)이란?
💡 캐시(Cache)란? 클라이언트가 서버에 한번 요청했던 데이터에 대해서 매번 요청할 때 마다 다시 전송할 필요가 없도록 웹 브라우저가 임시적으로 데이터를 보관하고 있는 장소이다.

 

 

 

HTTP 상태 코드

📌 HTTP 요청에 대한 처리 상태를 응답하는 코드로 Data를 함께 응답한다. Spring에서는 Response를 커스텀하여 의미있는 메세지를 만들어 사용하기도 한다. ex) 201 Created, Message: 회원 가입이 완료되었습니다!

 

1xx (Informational): 요청이 수신되어 처리중

2xx (Successful): 요청 정상 처리

3xx (Redirection): 요청을 완료하려면 추가 행동이 필요

4xx (Client Error): 클라이언트 오류, 잘못된 문법등으로 서버가 요청을 수행할 수 없음

5xx (Server Error): 서버 오류, 서버가 정상 요청을 처리하지 못함

  • HTTP Response Message 구조



HTTP Status Code

[1]  1xx

  • 요청 수신 후 처리중인 상태
  • 잘 사용하지 않는다.

[2]  2xx

  • 정상 처리 완료된 상태

 

 

202 Accepted

요청이 접수되었으나 처리가 완료되지 않았음

 

• 배치 처리 같은 곳에서 사용

• 예) 요청 접수 후 1시간 뒤에 배치 프로세스가 요청을 처리함

 

204 No Content

서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없음

 

• 예) 웹 문서 편집기에서 save 버튼

• save 버튼의 결과로 아무 내용이 없어도 된다.

• save 버튼을 눌러도 같은 화면을 유지해야 한다.

• 결과 내용이 없어도 204 메시지(2xx)만으로 성공을 인식할 수 있다.

= "야 됐어" - "안됐는데" - "암튼 됨 ㅇㅇ" - "?"

 

 

 

리다이렉션

 🐳 클라이언트가 요청한 URL이 다른 URL로 자동으로 변경되는 과정을 의미합니다. 주로 웹 서버나 애플리케이션에서 사용되며, 사용자가 원래 요청한 리소스의 위치가 변경되었을 때 이를 알려주기 위해 사용됩니다.

  • 리다이렉션은 주로 HTTP 응답 코드와 함께 발생하며, 클라이언트(브라우저 등)는 새로운 URL로 요청을 자동으로 보내게 됩니다. 리다이렉션에는 여러 가지 유형이 있습니다.
  • 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동 (리다이렉트)

 

 

리다이렉션 종류

영구 리다이렉션 - 특정 리소스의 URI가 영구적으로 이동

  • 예) /members -> /users
  • 예) /event -> /new-event

일시 리다이렉션 - 일시적인 변경

  • 주문 완료 후 주문 내역 화면으로 이동
  • PRG: Post/Redirect/Get

특수 리다이렉션

  • 결과 대신 캐시를 사용

 

[1] 리다이렉션 코드 종류

리다이렉션 응답 코드는 3xx로 시작하며, 대표적인 코드들은 다음과 같습니다.

상태 코드 설명 용도
301 Moved Permanently 요청한 리소스가 영구적으로 이동되었음을 의미 리소스의 위치가 변경되었고, 앞으로 해당 리소스를 새로운 URL에서 사용해야 한다는 것을 알려줌
302 Found (또는 Moved Temporarily) 요청한 리소스가 임시로 이동되었음을 의미 임시 리다이렉션, 리소스가 일시적으로 다른 URL로 이동한 경우 사용
303 See Other 요청한 리소스의 결과를 다른 URL에서 확인할 수 있음을 의미 POST 요청 후 리다이렉션 시 주로 사용 (예: 폼 제출 후 결과 페이지로 이동)
307 Temporary Redirect 302와 유사하지만, 메서드가 변경되지 않도록 유지 임시 리다이렉션, 원래의 HTTP 메서드(POST 등)가 그대로 사용되도록 보장
308 Permanent Redirect 301과 유사하지만, 메서드를 그대로 유지 영구적인 리다이렉션으로 원래의 HTTP 메서드를 그대로 사용

 

[2] 리다이렉션의 예시

리다이렉션은 일반적으로 웹 애플리케이션에서 URL을 변경하거나 리소스의 위치가 변경되었을 때 사용됩니다. 예를 들어:

  1. 301 Moved Permanently
  2. 302 Found
  3. 303 See Other
    • 사용자가 폼을 제출한 후 결과 페이지로 리다이렉션하려면 303 상태 코드가 사용됩니다.
    • 예시: 사용자 로그인 폼을 제출 후 결과를 보여주는 다른 페이지로 리다이렉션.
  4. 307 Temporary Redirect
    • 임시 리다이렉션이지만, 메서드를 그대로 유지하려면 307 상태 코드를 사용합니다.
    • 예시: 사용자가 POST 요청을 보낸 후 임시로 다른 페이지로 이동.

 

[3] 영구 리다이렉션

  • 리소스의 URI가 영구적으로 이동
  • 원래의 URL를 사용X, 검색 엔진 등에서도 변경 인지
  • 기존의 예전 URI로 접속해도 새로운 URI로 정상 접속된다.

301 Moved Permanently

  • 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음(MAY)

308 Permanent Redirect

  • 301과 기능은 같음
  • 리다이렉트시 요청 메서드와 본문 유지(처음 POST를 보내면 리다이렉트도 POST 유지)

 

[4] 영구 리다이렉션

  • 리소스의 URI가 일시적으로 변경 
  • 따라서 검색 엔진 등에서 URL을 변경하면 안됨

302 Found

  • 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음(MAY)

307 Temporary Redirect

  • 302와 기능은 같음
  • 리다이렉트시 요청 메서드와 본문 유지(요청 메서드를 변경하면 안된다. MUST NOT)

303 See Other

  • 302와 기능은 같음
  • 리다이렉트시 요청 메서드가 GET으로 변경

그래서 뭘 써야 하나요?

잠깐 정리

• 302 Found -> GET으로 변할 수 있음

• 307 Temporary Redirect -> 메서드가 변하면 안됨

• 303 See Other -> 메서드가 GET으로 변경

 

역사

• 처음 302 스펙의 의도는 HTTP 메서드를 유지하는 것

• 그런데 웹 브라우저들이 대부분 GET으로 바꾸어버림(일부는 다르게 동작)

• 그래서 모호한 302를 대신하는 명확한 307, 303이 등장함(301 대응으로 308도 등장)

 

현실

• 307, 303을 권장하지만 현실적으로 이미 많은 애플리케이션 라이브러리들이 302를 기본값으로 사용

• 자동 리다이렉션시에 GET으로 변해도 되면 그냥 302를 사용해도 큰 문제 없음

 

 

[5] 기타 리다이렉션

  • 캐시를 활용할 것인지에 대한 여부
  • 대표 상태코드
    • 304 Not Modified
      • 캐시 목적으로 사용된다.
      • 리소스가 수정되지 않았다는 뜻, 클라이언트가 캐시된 데이터를 조회하도록 유도한다.
      • 응답에 바디가 있으면 안된다.

 

[6] 리다이렉션 배달에 비유

  • 리다이렉션은 배달의 경로가 바뀌는 것과 비슷합니다. 예를 들어, 고객이 원래 주문한 피자 배달 경로가 변경되었을 때, 배달업체는 고객에게 "이제 다른 경로로 가야 한다"고 알려주고, 고객은 새로운 경로를 따라 가게 됩니다.
    • 301 (영구적 이동): "이제부터 이 길로만 가세요! 영원히 이 길을 따라가세요."
    • 302 (임시 이동): "이번에만 이 길로 가세요. 다음번엔 원래 길로 돌아가세요."
    • 303 (다른 곳에서 확인): "주문을 끝내고 나서 다른 곳에서 결과를 확인하세요."
    • 307 (임시 이동, 메서드 유지): "이 경로로 가긴 하지만, 원래 주문 방식을 그대로 유지하세요."

 


 

[4]  4xx

  • 클라이언트측 오류, 잘못된 문법 등으로 서버가 요청을 수행할 수 없다.
  • 클라이언트의 요청이 잘못되었기 때문에, 같은 요청의 재시도는 실패한다.
  • 오류의 원인이 클라이언트에 있음

 

  • 대표 상태코드
    • 400 Bad Request
      • 요청 구문, 메시지 등등 오류
      • 클라이언트가 HTTP 요청 내용을 수정 후 보내야 한다.
      ex) GET 메소드로 만들어진 API인데 POST로 보낸다?
    • ex) API 스펙과 일치하지 않을 때, 숫자를 문자로, 문자를 숫자로 등

 

    • 401 Unauthorized
      • 클라이언트가 리소스에 대한 **인증(Authentication)**이 필요하다.
      • 인증(Authentication) 되지 않음
      • 응답에 WWW-Authenticate 헤더와 함께 인증 방법을 설명한다.
      • 인증=누구세요 / 인가=권한있음?
      ex) 로그인
  •  
    • 403 Forbidden
      • 서버가 요청을 받았지만 승인 거부
      • 주로 인가(Authorization) 관련문제
      ex) 일반 유저, 관리자
  •  
    • 404 Not Found
      • 요청한 리소스가 서버에 없다.
      • 이를 이용하여 리소스를 숨겨놓기도 한다. 리소스가 있지만 없는척 하는 경우도 있다.

 

[5]  5xx

  • 서버 오류, 요청은 정상이지만 서버가 처리하지 못함
  • 재시도하면 성공할 수 있다.

ex) 서버가 일정시간 다운되었다가 다시 살아난 경우

  • 실제 서버에서 문제가 발생한 경우 5xx Error이기 때문에 발생하지 않는것이 최선이다.
  • 대표 상태코드
    • 500 Internal Server Error
      • 대부분 500으로 처리한다.
    • 503 Service Unavailable
      • 서비스 이용 불가
      • Retry-After Header를 사용하면 얼마뒤에 복구되는지 응답할 수 있다.
  • 새로운 상태 코드가 추가되어도 변경할 필요가 없다.
  • 디테일한 코드를 몰라도 몇 번대 코드인지만 알면 된다.
  • 응답 코드를 상황에 맞게 잘 작성 해야 한다. 매우 기본이고 매우 중요하다.

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] HTTP 요청 데이터  (0) 2024.12.02
[Net] HTTP Header  (0) 2024.12.01
[Net] HTTP  (0) 2024.11.29
[Net] JSON  (1) 2024.11.29
[Net] Web 기초  (1) 2024.11.29

+ Recent posts