직렬화(Serialization), 역직렬화(Deserialization) 완벽 이해

zdpk·2024년 8월 25일

Fundamental

목록 보기
3/3
post-thumbnail

Serialization, Deserialization은 Spring, Nestjs, Django, .NET, Axum 등 어떤 백엔드 프레임워크를 사용하더라도 마주하게 되는 개념이다.

왜 이러한 단어로 불리는지, 정확히 어떤 의미인지를 이해하기 위해서는 메모리 구조에 대한 기본적인 이해가 필요하다.

다음 코드로 예시를 들겠다.

생성자는 생략했다.

class User {
	name: string;
	info: UserInfo;
}

class UserInfo {
	age: number;
	gender: 'man' | 'woman';
}

const userInfo = new UserInfo(10, 'man');
const user = new User('me', userInfo);

이를 그림으로 표현하면 다음과 같다.

Ref to User, Ref to UserInfo는 실제로는 가리키는 객체의 Heap 상에서의 메모리 주소를 담고 있다.

임의로 User0x100, UserInfo0x200에 위치한다고 가정하면 다음과 같은 그림이 된다.

그럼 위에서 만든 User 객체는 단순히 0x100이라는 정수값이 된다.

HTTP Protocol에 대해 알고 있다면 HTTP로 Request, Response를 보낼 때는 항상 '문자열' 형태로 보내야 한다는 사실을 알고 있을 것이다.

HTTP/1.1 200 OK
Content-Type: application/json

[Body ...]

HTTP Response로 보내는 메세지 형식은 위와 같은데, Body 부분에 User 객체를 담아서 보낸다면 단순 정수값이 들어갈 것이다.

HTTP/1.1 200 OK
Content-Type: application/json

0x100

위와 같은 경우, 0x100을 서버에서 클라이언트로 보낸다고 해도 유의미한 데이터는 존재하지 않는다.

그러나 웹 개발 경험이 있다면 Content-Typeapplication/json 형식이기 때문에 이러한 데이터를 기대했을 것이다.

{
	"name": "a",
	"info": {
		"age": 10,
		"gender": "man"
	}
}

단순 주소값 0x100을 담고 있는 변수 user을 위와 같은 형태로 치환 시켜야 위와 같은 형태의 데이터로 가공할 수 있다.


Serialization

즉, 클라이언트에서 의미 없는 주소값이 아닌, 실제로 요청한 데이터가 들어 있는 JSON 형식의 문자열을 받기 위해 위와 같이 메모리 상의 객체를 문자열 형태로 변환하는 것을 직렬화(Serialization)라고 부른다.

물론 객체를 JSON이 아닌 XML, YAML 등의 다른 포맷의 문자열로 변환하는 것 역시 Serialization이다.
포맷에 상관 없이 객체 -> 문자열 변환 작업을 Serialization이라 생각하면 된다.

User 객체가 Heap에 할당될 때마다 계속해서 주소가 바뀔 것이기 때문에 언제는 0x100, 또 언제는 0x300이 될 수 있다.
일관적이지 않은 데다가 유효한 데이터도 없다.
클라이언트의 0x100도 뭐가 있을 지 매 번 달라지기 때문이다.

문자열은 기술적으로 그저 문자의 배열일 뿐이기 때문에 메모리 상에 1자로 연속된 바이트 열이라고 볼 수 있다.

객체가 Stack과 Heap에 여기 저기 퍼져 있는 것을 연속된 1자 바이트 열로 배치시키는 행위이기 때문에 '직렬화'라 불리우는 것이다.

데이터를 직선으로 열거하는 것, 정도로 생각하면 될 것 같다.
Heap 상에 여기 저기 퍼져있던 데이터를 1자로 열거하니 말이다.

어떤 프레임워크를 쓰더라도 서버에서 클라이언트 측으로 Response를 보내게 되면 다음과 같이 Socket의 Buffer(그냥 바이트열, 배열이라고 생각)에 문자열 형태의 Response를 바이트로 쓰게 된다.(문자열도 결국 바이트 열이므로)

이렇게 Socket Buffer에 쓰여진 바이트 열은 네트워크를 통해 클라이언트로 전송된다.


Deserialization

반대로 Deserialization은 Socket Buffer에 Request가 바이트 열 형태로 들어오면, 이를 객체 형태로 변환하는 것이다.

Socket Buffer에 1자로 놓인 메모리를 객체로 변환하면, Heap 상에 여기 저기로 퍼지게 된다.

그래서 역직렬화 라고 부른다.

일자로 나열되어 있던 것을(직렬화) 것을 역으로 퍼지게 만드니 말이다.

용어와 메모리 구조를 정확히 이해하면 Serialization, Deserialization이 이해하기 그리 어렵지 않은 개념이라는 것을 깨달을 수 있을 것이다.

0개의 댓글