SMALL

JPA ( Java Persistence API )

- 자바 ORM 기술에 대한 API 표준 명세

- 자바 애플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스

 

ORM ( Object Relational Mapping )

- 객체와 관계형 데이터베이스를 매핑하는 기술

  ( DB Data --- Mapping --- Object ) 

- 비교되는 개념으로는 SQL Mapper가 있다

  ( SQL --- Mapping --- Object )

 

이 각각의 개념을 머리속에 생각해보면, 

자바에서 ORM기술을 사용하여 애플리케이션을 짜고 싶으면, 그의 표준인 JPA를 사용하여 작성해야 한다. 

( ORM을 사용하기 위해서는 표준인 JPA가 있지만, SQL Mapper를 사용하기 위해서는 표준이라고 딱히 정의된 부분은 없는 것 같다. 그냥 SQL를 통해 실행된 DB Data를 애플리케이션 레벨에 맞는 객체로 전환한다고 생각하면 될 것 같다.) 

 

위에서 말한것 처럼, JPA는 기술 명세이다.

어떻게 사용할지 가이드만 제공한 것이지, 실제 구현체가 아니다.

단순 인터페이스이다. 

 

그렇다면, 왜 JPA라는 표준까지 정해 놓으면서, ORM을 사용하려 하는 것인가

- DBMS에 대한 종속성을 줄일 수 있다.

- 객체 지향적인 코드로 더 직관적이고 비즈니스 로직에 더 집중할 수 있다.

 

더 나아가 JPA 기술 명세의 구현체인 ORM 프레임워크를 사용하면

개발자가 직접 query를 작성하지 않고, 메서드 호출로 원하는 데이터를 조회할 수 있고, 애플리케이션 레벨의 객체로 전환도 해주는 편리함을 누릴 수 있다. 

( ex : Hibernate ) 

 

LIST
SMALL

Hateoas에 대한 정의 

REST API에 대한 정의 

Hateoas 사용 예시


Hateoas에 대한 정의 

Hypermedia As The Engine Of Application State의 약자로, 기본적인 아이디어는 

하이퍼미디어를 애플리케이션의 상태를 관리하기 위한 메커니즘으로 사용한다는 것입니다.

 

위의 정의 내용을 이해하고, 구글링을 하다 보면 보이는 정의 내용을 다시 보면 조금은 더 이해하는데 도움이 된다.

Hateoas란 REST Api를 사용하는 클라이언트가 전적으로 서버와 동적인 상호작용이 가능하도록 하는 것을 의미합니다. 이러한 방법은 클라이언트가 서버로부터 어떠한 요청을 할 때, 요청에 필요한 URI를 응답에 포함시켜 반환하는 것으로 가능하게 할 수 있습니다.

 

REST API에 대한 정의 

Hateoas는 REST API를 잘 설계하기 위해 나온 개념이다. 그렇다면 REST API는 무엇인가 간단히 알아보자.

REST API는 Representational State Transfer API의 약자로,

“웹 애플리케이션이 제공하는 각각의 데이터를 리소스, 즉 자원으로 간주하고 각각의 자원에 고유한 URI(Uniform Resource Identifier)를 할당함으로써 이를 표현하는 API를 정의하기 위한 소프트웨어 아키텍처 스타일이다.

 

잘 설계된 REST API를 구현하기 위한 단계가 존재하는데 , 그 마지막 단계가

Hypermedia Controls (하이퍼미디어 컨트롤) - HATEOAS라는 개념을 통해, 자원에 호출 가능한 API 정보를 자원의 상태를 반영하여 표현하는것이다.

(자세한 구현 단계에 대한 설명은 다른 포스팅을 통해서 소개하도록 하겠습니다)

REST 구현 단계 ( 출처 : https://images.app.goo.gl/tp6yVbK2Lrs16dcB8)
REST API 구현 단계별 예시 (출처 : https://grapeup.com/blog/how-to-build-hypermedia-api-with-spring-hateoas/)

Hateoas 사용 예시

이제 대략적으로 Hateoas, REST API가 무엇인지 알았으니, 해당 개념에 대한 예제를 보고 더욱 구체적으로 이해해 보자.

 

계좌번호가 "12345"인 계좌의 정보를 조희 하는 경우에 해당 계좌의 상태 ( 잔여 금액 등등..)에 따라 접근 가능한 추가 API들이 LINKS라는 이름으로 제공된다.

 

기존의 전형적인 REST API 응답

 

Hateoas가 적용된 응답 ( URI 정보를 응답에 추가)

위와 같이 Hateoas를 사용하게 되면 누릴 수 있는 장점은 아래와 같다 

  • Client 사이드에서는 "rel"의 이름으로 요청 URI를 사용하기 때문에 URI 수정이 발생하더라도 Client 사이드는 수정이 이루어지지 않는다. 

 

LIST
SMALL
  • JWT에 대한 간단한 정의
  • 기존 서버 기반 인증의 문제점 ( MSA 환경 )
  • JWT의 세부 구조 

 

JWT는 JSON Web Token의 약자로 

클라이언트와 서버, 서비스와 서비스 사이 통신 시 권한 인가를 위해 사용하는 토큰이다. 

URL에 대해 안전한 문자열로 구성되어 있어서 HTTP 어디든 ( URL, Header.. ) 토큰 정보가 위치할 수 있다.

 

기존의 권한 인증 인가는 대부분 서버 기반으로 이루어져 있었다. 

서버 기반의 권한 인증 인가는 MSA ( MicroService Architecture)에 적합하지 않아 그의 대안으로 JWT가 등장하였다.


기존 서버 기반 인증의 문제점

사용자 수가 늘어날수록 세션에 담아야 할 정보가 함께 증가하기 때문에 메모리 과부하 문제가 발생한다.

많은 트래픽을 감당하기 위해 프로세스를 늘리거나 서버 장비를 추가하는 경우 확장이 쉽지 않다.

쿠키는 단일 도메인 및 서브 도메인에서만 작동하기 때문에 여러 도메인에서 관리하는 것은 번거롭다.

즉, 서버 기반 인증인 세션과 쿠키는 MSA환경에 적합하지 않다.

 


JWT 인증 과정에 대한 간략 Flow

  • 사용자 로그인
  • 서버 : 사용자 정보 인증 -> 맞는 경우 클라이언트에게 signed token 발급 
    ( signed tocken : 정상 토큰인지 증면된 signature를 담고 있는 토큰) 
  • 클라이언트 : 서버로부터 받은 토큰 저장, 서버에 요청할 때마다 토큰을 서버에 전달
  • 서버 : 요청이 올 때마다 함께 전달된 토큰 검증 

JWT의 구조 

header, payload, signature로 이루어져 있고, 각각의 정보는 "."을 통해서 구분된다.

각각의 정보는 Base64 URL-Safe 인코딩 된 문자열이다.

header . payload . signature 

 

Header에는 JWT를 어떻게 검증하는가에 대한 내용을 담고 있다. 

{
    "type" : "JWT", // 토큰의 타입
    "ALG" : "H256" // 서명 시 사용하는 알고리즘 ( HMAC SHA256, RSA ) 
}

headerStr = Base64.encodeBase64URLSafeString(objectMapper.writeValueAsBytes(header));

Payload에는 토큰에 담을 정보가 포함되어있다.

토큰은 클레임으로 이루어져 있으며 "name : value" 쌍으로 이루어져 있다.

토큰 안에는 여러 개의 클레임을 넣을 수 있으며 크게 세 분류로 나눌 수 있다.

  • registered claim : 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들을 담기 위해 이름이 이미 정해진 클레임이다.
  • public claim : 사용자 정의 클레임으로 공개용 정보를 위해 사용된다. 충돌 방지를 위해 URL 포맷을 이용해야 한다.
  • private claim : 서버와 클라이언트 사이에 임의로 지정한 정보를 저장하기 위해 만들어진 사용자 지정 클레임
{
    "iss": "joojoo.com",
    "exp": "1485270000000",
    "https://joojoo.com/jwt_claims/is_student": true,
    "userId": "11025454527102",
    "username": "joojoo"
}

payloadStr = Base64.encodeBase64URLSafeString(objectMapper.writeValueAsBytes(payload));

 

Signature에는 헤더의 인코딩 값, payload의 인코딩 값을 합친 후 주어진 비밀키로 해쉬를 하여 생성된 값이 들어있다. 

HMACHASH256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secretKey)

 

 

 

 

LIST
SMALL

gradle 빌드를 하게 되면, 내가 dependency를 잡아주었는데 compile error가 나는 상황이 발생한다. 이러한 경우에 내가 정확하게 dependency를 잡았나 확인하기 위해서 현재 build중인 compile dependency를 출력하는 방법을 알아보도록 하자.

task tempTask () {
	configurations.compile.each {
        c -> println(c)
    }
}

물론, configurations뒤의 compile을 원하는 내용으로 바꾸면 , 해당 내용에 대한 dependency를 확인할 수 있다. ( runtime, testCompile... 등등) 


다음으로 cmd창에 gradle dependencies라고 치면 기본으로 gradle에서 제공하는 task로 해당 프로젝트에서 사용하는 dependency를 확인할 수 있다. 

gradle dependencies --configuration=compile
gradlew dependencies --configuration=compile

LIST

+ Recent posts