Skip to content

Latest commit

 

History

History
193 lines (180 loc) · 14.2 KB

REST_API.md

File metadata and controls

193 lines (180 loc) · 14.2 KB

REST_API

REST(Representational State Transfer) api

  • 웹 서비스의 아키텍처 스타일 중 하나로, 클라이언트와 서버 간의 통신을 위한 규칙과 원칙을 정의하는 방법
    • HTTP 프로토콜을 기반
    • 자원(Resource)을 고유한 URI로 식별
    • HTTP 메서드(GET, POST, PUT, DELETE 등)를 사용하여 자원에 대한 상호작용
  • 특징
    • 자원 중심적: 각 자원은 고유한 URI를 가지며, URI를 통해 자원에 접근하고 조작
      • 사용자 정보 API가 있다고 하면 GET /users/{user_id} 등과 같이 자원 중심적인 URI
    • 상태 없음(Stateless): 각 요청은 필요한 모든 정보를 포함하며, 서버는 클라이언트의 상태를 저장하지 않음
      • 클라이언트에서 로그인을 하면 서버에서 인증 정보를 가지고 있는 것이 아니라, 인증 토큰을 클라이언트에 반환하고, 클라이언트에서 인증 토큰을 지속적으로 받으면서 결과를 반환함
      • 서버의 확장성과 클라이언트의 독립성을 높여줌
      • If not stateless
        • 서버의 부담이 증가, 복잡성이 증가
        • 서버에서 장애가 발생하면 클라이언트 정보가 손실될 수 있음 (데이터 무결성 문제)
        • 여러 서버 간에 클라이언트 상태를 공유하는 것은 확장성에 문제가 발생함
    • 표준 메서드: REST API는 HTTP 메서드(GET, POST, PUT, DELETE 등)를 사용하여 자원에 대한 작업을 정의
    • 자체 표현: REST API는 자원에 대한 정보를 응답으로 제공. (일반적으로 JSON 또는 XML 형식으로 표현)

HTTP 프로토콜

  • 웹 상에서 데이터를 주고받기 위한 프로토콜
    • 웹 브라우저와 웹 서버 간의 요청과 응답을 처리하는 데 주로 사용
  • 특징
    • Stateless 프로토콜: HTTP는 상태를 유지하지 않는 Stateless 프로토콜
    • 클라이언트-서버 모델: H클라이언트는 요청을 보내고, 서버는 요청에 대한 응답을 반환하는 모델
    • 요청 메서드: HTTP는 다양한 요청 메서드를 제공 (GET, POST, PUT, DELETE)
    • 상태 코드: 상태 코드는 요청의 성공, 실패 또는 다른 상태를 반환 (200(성공), 404(찾을 수 없음), 500(내부 서버 오류))
    • 헤더: 헤더는 추가적인 메타데이터를 전달하며, 요청의 속성이나 응답의 정보를 포함
    • URI: HTTP 요청은 URI를 사용하여 특정 리소스를 지정. URI는 URL(Uniform Resource Locator) 또는 URN(Uniform Resource Name)의 형태로 사용됨
    • 세션 관리: HTTP는 기본적으로 상태를 유지하지 않기 때문에, 세션 관리를 위해 쿠키(cookie)와 같은 메커니즘을 사용. 쿠키를 사용하여 클라이언트의 상태 정보를 서버에 저장하고 유지

쿠키

  • 웹 서버가 클라이언트의 웹 브라우저에 저장하는 작은 데이터 조각
    • 클라이언트의 상태 정보를 저장하고 유지하는 데 사용 (세션 관리)
  • 과정
    1. 서버에서 클라이언트에 응답: Set-Cookie 헤더를 사용하여 쿠키를 생성하고 클라이언트에게 전달 (쿠키의 이름, 값, 만료 날짜 및 경로 등)
      • 고유한 세션 식별자를 할당하고 해당 식별자를 쿠키에 저장
    2. 클라이언트에 저장: 쿠키는 클라이언트의 로컬에 저장되며, 만료 날짜에 따라 유효기간을 가짐
    3. 클라이언트에서 서버로 요청: Cookie 헤더를 사용하여 저장된 쿠키를 서버에 전달
    4. 서버에서 쿠키 읽기: 서버는 클라이언트의 상태 정보를 파악하고 이전 상태를 유지

인증과 인가

  • 사용자 및 클라이언트 신원 확인, 권한 부여를 위한 보안 개념
  • 인증(Authentication)
    • 클라이언트가 서버로 부터 자신의 신원을 확인하는 프로세스
      • 주로 클라이언트의 로그인 정보, API 키, 토큰 등을 통해서 확인
    • 인증이 성공하면, 사용자는 신원이 확인된 것으로 간주되고, 그 후 API 호출
  • 인가(Authorization)
    • 클라이언트가 특정 리소스에 접근할 수 있는 권한을 확인하고 부여하는 것을 의미
    • 보통은 역할(Role) 또는 권한(Authority) 기반으로 인가 규칙이 정의
    • 인가는 API 엔드포인트 레벨, HTTP 메소드 레벨 또는 특정 동작에 대한 권한 설정 등 다양한 방식으로 구현 가능

JWT

  • 토큰 기반 인증 방법 중 하나. (JSON 형식)
    • 서버에 있는 리소스를 얻기 위해서 클라이언트가 인증/인가를 하는 과정
  • 인증(Authentication)
    1. 클라이언트가 로그인 또는 인증 요청을 보냄
    2. 서버는 사용자의 신원을 확인하고 유효한 사용자인 경우에 JWT를 발급
      • JWT는 사용자를 식별하는 정보와 서버에서 발행한 서명(signature)이 포함
    3. 서버는 발급된 JWT를 클라이언트에게 전달
  • 인가(Authorization)
    1. 클라이언트가 인가가 필요한 API 엔드포인트에 요청을 보냄 (헤더에 JWT를 포함)
    2. 서버는 JWT의 유효성을 검증하고 사용자의 권한을 확인
    3. JWT의 서명을 검증하여 변조되지 않았고, 유효 기간이 남아있는 경우 클라이언트의 요청을 처리하고 인가된 작업을 수행
  • 특징
    • 장점
      • 클라이언트와 서버 간의 상태를 저장하지 않으므로, 서버의 확장성이 향상
      • 토큰에 포함된 정보를 신뢰할 수 있으므로, 추가적인 데이터베이스 조회 없이 토큰 자체로 사용자를 인증
    • 주의점
      • JWT는 클라이언트가 토큰을 보유하므로, 토큰이 탈취되면 해당 사용자의 권한이 노출될 수 있음
        • 따라서 SSL/TLS와 같은 안전한 통신 채널을 사용해야 함
      • JWT의 크기가 커질 수 있으므로, 필요한 정보만 포함하여 사용

OAuth2.0

  • 웹 및 모바일 애플리케이션에서 사용자 인증 및 권한 부여를 위한 개방형 표준 프로토콜
    • 리소스 소유자가 본인 정보에 접근할 수 있는 자격을 직접 승인
    • 유저가 서버에 있는 자신의 정보를 얻어 클라이언트에 제공하기 위해서 직접 인증/인가를 하는 과정
    • 구글, 페이스북, 카카오, 네이버 등에서 제공하는 간편 로그인 기능
  • 역할
    • Resource Owner
      • 본인 정보에 접근할 수 있는 자격을 승인하는 주체
      • 인증을 하는 역할을 수행, 완료되면 Client에 권한 부여
    • Client
      • 접근 요청을 하는 애플리케이션
    • Resource Server
      • Resource Owner의 정보가 저장되어 있는 서버
    • Authorization Server
      • 인증/인가를 수행하는 서버
      • 클라이언트의 접근 자격을 확인, Access Token을 발급하여 권한을 부여
  • 예시
    1. User가 Client에 사용 요청 > Client가 Authorization Server에 승인 요청 > 로그인 팝업 > User 로그인
    2. User 로그인이 확인 되었으니, Authorization Server에서 권한 부여 승인 코드 전달
    3. 권한이 생긴 Client에서 Authorization Server로 Access Token 요청 > 반환
    4. Client에서 Access Token을 통해서 Resource Server에 자원 요청 > 반환

보안

API키

  • 외부 애플리케이션이나 서비스가 인증 및 인가를 위해 사용하는 비밀 토큰
    • 식별: 서비스 제공자는 API 키를 통해 어떤 애플리케이션이 요청을 보내는지 식별
    • 인증: 올바른 API 키를 가진 클라이언트만이 서비스에 액세스
    • 인가: 서비스 제공자는 API 키를 기반으로 클라이언트가 특정 리소스 또는 기능에 액세스할 수 있는지 결정
  • 일반적으로 클라이언트가 API 요청을 보낼 때 HTTP 헤더 또는 요청 매개변수로 전달
    • API 키를 안전하게 저장하고 관리
    • 보안 저장소에 저장하고 접근 권한을 제한

SSL(Secure Sockets Layer)/TLS(Transport Layer Security)

  • 네트워크 통신에서 보안을 제공하기 위해 사용되는 프로토콜
    • TLS는 SSL의 후속 버전으로 발전하면서 더 안전하고 강력한 보안 기능을 제공
  • 특징
    • 암호화 (Encryption)
      • SSL/TLS는 통신하는 데이터를 암호화하여 가로채기 방지
      • 클라이언트와 서버 간의 데이터는 공개키 암호화 및 대칭키 암호화 방식을 사용하여 안전하게 전송
    • 인증 (Authentication)
      • SSL/TLS는 클라이언트와 서버 간의 상호 인증을 제공
      • 서버 인증은 서버의 신원을 확인하고 클라이언트가 신뢰할 수 있는 서버와 통신하고 있는지 확인
      • 선택적으로 클라이언트 인증도 수행할 수 있으며, 클라이언트의 신원을 확인 가능
    • 데이터 무결성 (Data Integrity)
      • SSL/TLS는 전송되는 데이터의 무결성을 보장
      • 데이터가 전송 중에 변경되거나 조작되지 않았는지 확인하기 위해 메시지 인증 코드(MAC) 또는 해시 기능을 사용
    • 인증서 (Certificate)
      • SSL/TLS에서 사용되는 디지털 인증서는 신뢰할 수 있는 제3자 인증 기관(CA)에 의해 발급되며, 서버의 신원을 확인
      • 인증서에는 서버의 공개키와 서버 정보가 포함
  • 연결 예시
    1. 클라이언트가 웹 브라우저를 통해 HTTPS로 액세스하려는 웹 사이트에 접속
    2. 서버는 클라이언트의 요청을 받고 SSL/TLS 연결을 설정
    3. 서버는 클라이언트에게 공개키 인증서를 제공 (서버의 공개키와 서버 정보가 포함)
    4. 클라이언트는 서버의 인증서를 확인 > 클라이언트는 미리 신뢰할 수 있는 인증 기관의 루트 인증서를 가지고 있어서 서버의 신뢰성을 확인
    5. 클라이언트는 세션키를 생성 > 서버의 공개키를 사용하여 암호화 > 서버에 전송
    6. 서버는 자신의 개인키를 사용하여 세션 키를 복호화
      • 공개키로 암호화한 것 > 개인키로만 복호화 가능
    7. 이제 클라이언트와 서버는 서로 대칭키를 사용하여 데이터를 암호화하고 복호화할 수 있는 안전한 연결을 설정

API 디자인 가이드

  • 일관성, 가독성, 유지보수성, 확장성이 향상되며, 개발자와 클라이언트 간의 상호작용을 원활
  • 가이드
    1. 리소스와 URI 설계
      • 각 리소스는 고유한 식별자를 가지고 URI에 표현
    2. HTTP 메서드 활용
      • HTTP 메서드(GET, POST, PUT, DELETE 등)는 리소스 조작 작업을 나타내는 용도로 사용
      • 각 메서드는 적절한 의미와 의도에 따라 사용되어야 함
    3. 적절한 상태 코드 반환
      • 요청의 결과에 따라 적절한 HTTP 상태 코드를 반환 + 적절한 응답 본문
      • 잘못된 요청이나 예외 상황에 대한 적절한 에러 응답을 반환 + 에러 응답은 명확하고 유용한 메시지
    4. 버전 관리
      • API의 변경이나 업데이트에 유연하게 대응하기 위해 API 버전 관리를 고려
      • 예를 들어, /v1/users와 같이 버전 번호를 URI에 포함

디자인 패턴

  1. 컬렉션과 요소
    • 컬렉션: 리소스의 집합을
    • 요소: 컬렉션 내 개별 리소스
    • 예를 들어, /users는 사용자 컬렉션을 나타내고, /users/{userId}는 특정 사용자 요소
  2. 필터링과 정렬
    • API 사용자가 리소스를 필터링하고 정렬할 수 있는 기능을 제공
    • 예를 들어, /users?name=john와 같이 이름으로 사용자를 필터링할 수 있고, /users?sort=age와 같이 나이로 사용자를 정렬
  3. 중첩된 리소스
    • 관계가 있는 리소스를 중첩하여 표현하는 패턴
    • 예를 들어, /users/{userId}/posts는 특정 사용자의 게시물을 나타냄
  4. 페이징
    • 대량의 데이터를 처리하기 위해 API 사용자가 결과를 페이지별로 요청할 수 있는 패턴
    • 예를 들어, /users?page=2&limit=10와 같이 페이지 번호와 결과 제한을 지정
  5. HATEOAS (Hypermedia as the Engine of Application State)
    • 클라이언트가 서버로부터 받은 리소스와 관련된 다음 가능한 동작을 파악할 수 있어야 한다
    • API의 응답에 하이퍼미디어 링크를 포함하여 클라이언트가 API를 탐색하고 상태 전이를 수행할 수 있는 패턴
    • 예를 들어, 클라이언트가 사용자 정보를 요청한 경우 서버는 사용자 리소스에 대한 데이터를 제공하면서 해당 사용자의 프로필 편집, 주문 내역 조회, 관련 블로그 게시물 탐색 등과 같은 링크를 응답에 포함
    • API의 자기 설명성과 탐색 가능성을 향상
      • API의 문서나 사전 지식 없이도 응답을 통해 이용 가능한 동작을 파악

네이밍 룰

  1. 자원 (Resource) 표현
    • API 엔드포인트는 자원을 나타내며, 단수 명사나 복수 명사로 표현
    • 예를 들어, /users는 사용자 자원을 나타내는 엔드포인트입니다.
  2. HTTP 메서드 사용
    • HTTP 메서드를 적절하게 활용하여 원하는 동작
    • 메서드
      • GET: 자원 조회
      • POST: 자원 생성
      • PUT: 자원 전체 업데이트
      • PATCH: 자원 일부 업데이트
      • DELETE: 자원 삭제
  3. 계층 구조
    • 계층 구조를 나타내는 방식으로 엔드포인트를 구성
    • 예를 들어, /users/{userId}/orders는 특정 사용자의 주문 목록을 조회하는 엔드포인트
  4. 동사 사용
    • 동사를 사용하여 특정 동작을 나타내는 경우도 있음
    • 예를 들어, /users/{userId}/activate는 특정 사용자를 활성화하는 동작을 수행하는 엔드포인트
  5. 하이픈 또는 밑줄
    • 엔드포인트 내 단어를 구분하기 위해 하이픈 - 또는 밑줄 _을 사용하는 것이 일반적
    • 예를 들어, /user-profiles 또는 /user_profiles와 같이 사용할 수 있습니다.