이 글은 컴퓨터학부 수업인
데이터베이스
와데이터베이스 개론
을 공부하고 정리한 내용입니다.
데이터베이스는 다수의 사용자가 동시에 사용하더라도 항상 모순이 없는 정확한 데이터를 유지해야 한다.
데이터베이스 관리 시스템은 데이터베이스가 항상 정확하고 일관된 상태를 유지할 수 있도록 다양한 기능을 제공하는데, 그 중심에는 트랜잭션
이 있다.
트랜잭션
은 작업 하나를 수행하는 데 필요한 데이터베이스의 연산들을 모아놓은 것으로, 데이터베이스에서 논리적인 작업의 단위가 된다. 그리고 데이터베이스에 장애가 발생했을 때 데이터를 복구하는 작업의 단위도 된다.
예를 들어, 인터넷뱅킹을 통해 계좌이체 작업을 완벽하게 수행하기 위해 2개의 데이터베이스 연산을 처리해야 한다면, 계좌이체 트랜잭션은 2개의 연산으로 구성할 수 있다.
이체하기 전의 팬시의 잔액은 20,000원이고 케빈의 잔액은 0원인 경우을 다음과 같이 정리했다.
[이체하기 전의 DB 상태]
팬시 잔액 : 20,000원
케빈 잔액 : 0원
이때 팬시가 브루스에게 10,000원을 이체한 경우 계좌이체 트랜잭션은 다음과 같이 2개의 연산으로 구성할 수 있다.
(팬시의 계좌번호는 100, 케빈의 계좌번호는 200으로 가정한다)
[1] 팬시 계좌에서 10,000원 인출
UPDATE 계좌
SET 잔액 = 잔액 - 10,000
WHERE 계좌번호 = 100;
[2] 케빈 계좌에 10,000원 입금
UPDATE 계좌
SET 잔액 = 잔액 + 10,000
WHERE 계좌번호 = 200;
[이체한 이후의 DB 상태]
팬시 잔액 : 10,000원
케빈 잔액 : 10,000원
여기서 중요한 점은 2개의 UPDATE 문이 모두 완전하게 처리되어야 트랜잭션이 성공적으로 수행한다는 것이다. 만약 둘 중 하나라도 처리 과정에서 오류가 발생한다면, 모든 명령문의 실행을 취소하고 트랜잭션 작업 전의 데이터베이스 상태로 되돌아가야 한다.
트랜잭션은 데이터베이스에 장애가 발생했을 때 복구 작업을 수행하거나, 다수의 사용자가 동시에 사용할 수 있도록 제어 작업을 하는데 중요한 단위로 사용된다.
그러므로 데이터베이스의 무결성과 일관성을 보장하려면 작업을 수행하는 데 필요한 연산들을 하나의 트랜잭션으로 제대로 정의하고 관리해야 한다.
트랜잭션이 성공적으로 처리되어 데이터베이스의 무결성과 일관성이 보장되려면 네 가지 특성을 모두 만족해야 한다. 트랜잭션의 네 가지 특성을 각 특성에 해당하는 영어 단어 첫 자를 따로 ACID 특성이라고 한다.
[1]
원자성
(Atomicity) : 트랜잭션을 구성하는 연산들이 모두 정상적으로 실행되거나 하나도 실행되지 않아야 한다는 All-Or-Nothing 방식을 의미한다.
만약 트랜잭션을 수행하다가 장애가 발생하여 작업을 완료하지 못했다면, 지금까지 실행한 연산 처리를 모두 취소하고 데이터베이스를 트랜잭션 작업 전의 상태로 되돌려 트랜잭션의 원자성을 보장해야 한다.
그러므로 트랜잭션의 원자성을 보장하려면 이처럼 장애가 발생했을 때 데이터베이스의 원래 상태로 복구하는 회복 기능이 필요하다.
커밋
(Commit) : 여러 쿼리가 성공적으로 처리되었다고 확정하는 명령어로 트랜잭션 단위로 수행되며 변경된 내용이 모두 영구적으로 저장되는 것을 말한다. “커밋이 수행되었다.”라는 것은 “하나의 트랜잭션이 성공적으로 수행되었다.“를 말한다.
롤벡
(Rollback) : 에러나 여러 이슈 때문에 트랜잭션 전으로 돌려야 할 때 사용하는 것을 말한다.
[2]
일관성
(Consistency) : 트랜잭션이 성공적으로 수행된 이후에도 데이터베이스가 일관된 상태를 유지해야 함을 의미한다.
[3]
격리성
(Isolation) : 고립성이라고도 하는데 현재 수행 중인 트랜잭션이 완료될 때까지 트랜잭션이 생성한 중간 연산 결과에 다른 트랜잭션들이 접근할 수 없음을 의미한다.
각 트랜잭션이 독립적으로 수행될 수 있도록 다른 트랜잭션의 중간 연산 결과에 서로 접근하지 못하게 한다.
[4]
지속성
(Durability) : 영속성이라고도 하는데 트랜잭션이 성공적으로 완료된 후 데이터베이스에 반영된 수행 결과는 어떠한 경우에도 손실되지 않고 영구적이어야 함을 의미한다.
즉, 시스템에 장애가 발생하더라도 트랜잭션 작업 결과는 없어지지 않고 데이터베이스에 그대로 남아 있어야 한다는 의미이다.
그러므로 트랜잭션의 지속성을 보장하려면 시스템에 장애가 발생했을 때 데이터베이스를 원래 상태로 복구하는 회복 기능이 필요하다.
원자성과 지속성의 공통점은 장애가 발생했을 때 데이터베이스를 원래 상태로 복구하는 회복 기능이 필요하다.
트랜잭션은 아래의 그림처럼 5가지 상태 중 하나에 속하게 된다.
활동
상태(Active) : 트랜잭션이 수행되기 시작하여 현재 수행 중인 상태를 말한다.
부분 완료
상태(Partially committed) : 트랜잭션의 마지막 연산이 실행된 직후의 상태를 말한다. 모든 연산의 처리가 끝났지만 트랜잭션이 수행된 최종 결과를 DB에 아직 반영하지 않은 상태이다.
완료
상태(Committed) : 트랜잭션이 성공적으로 완료되서 commit
연산을 실행한 상태를 말한다. 트랜잭션이 수행한 최종 결과를 DB에 반영하고 종료된다.
실패
상태(Failed) : H/W 혹은 S/W의 문제, 트랜잭션의 내부의 오류 등 여러 이유로 인해 장애가 발생하여 트랜잭션의 수행이 중단된 상태를 말한다. 더는 정상적으로 수행할 수 없을 때 실패 상태가 된다.
철회
상태(Aborted) : 트랜잭션을 수행하는 데 실패하여 rollback
연산을 실행한 상태를 말한다. 철회 상태가 되면 지금까지 실행한 트랜잭션의 연산을 모두 취소하고 트랜잭션이 수행되기 전의 DB 상태로 되돌리면서 트랜잭션이 종료된다.
트랜잭션이란 무엇인가요?
트랜잭션의 특성 4가지에 대해 설명해 주세요.
트랜잭션의 상태 5가지에 대해 설명해 주세요.
트랜잭션의 특성 중 한 가지인 격리성
(Isolation)은 현재 수행 중인 트랜잭션이 완료될 때까지 트랜잭션이 생성된 중간 연산 결과에 다른 트랜잭션들이 접근할 수 없음을 의미한다.
격리성은 여러 개의 격리 수준으로 나뉘어 격리성을 보장한다.
격리 수준은 아래와 같이 4개가 있다.
위로 갈수록 동시성이 강해지지만 격리성은 약해지고, 아래로 갈수록 동시성은 약해지지만 격리성은 강해진다.
또한 각 단계마다 나타나는 현상이 있다.
READ_UNCOMMITTED
- 팬텀 리드, 반복 가능하지 않는 조회, 더티 리드가 발생할 수 있다.
READ_COMMITTED
- 팬텀 리드, 반복 가능하지 않는 조회가 발생한다.
REPEATABLE_READ
- 팬텀 리드가 발생한다.
더티 리드(Dirty Read)는 반복 가능하지 않은 조회와 유사하며 한 트랜잭션이 실행 중일 때 다른 트랜잭션에 의해 수정되었지만 아직 ‘커밋되지 않은’행의 데이터를 읽을 경우 발생한다.
예를 들어 사용자 A의 계좌(A 트랜잭션)가 $100을 $0으로 변경한 내용이 아직 커밋되지 않은 상태라도 그 이후에 사용자 B가 조회했을 때 결과가 $0으로 나온 경우를 말한다.
만약 수정한 트랜잭션 A가 그 변경 사항을 롤백하면, 그 데이터를 읽은 다른 트랜잭션 B가 더티 데이터를 가지고 있다고 말한다.
반복 가능하지 않은 조회(Non-Repeatable Read)는 한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 경우를 가리킨다.
예를 들어 팬시의 계좌가 1번인 잔고 안에 $100가 들어 있다.
처음에 계좌 1번의 데이터를 읽으면, $100를 읽게 된다.
하지만 이 때 팬시가 계좌가 1번인 잔고에서 $10을 다른 계좌로 송금했다.
그러면 두 번째로 계좌 1번의 데이터를 읽을 때에는 $90를 읽게 된다.
이처럼 한 트랜잭션 내에서 같은 Key를 가진 Row를 두 번 읽었는데 그 사이에 값이 변경되거나 삭제되어 결과가 다르게 나타나는 현상을 말한다.
팬텀 리드(Phantom Read)는 한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 해당 조회 결과가 다른 경우를 말한다.
다른 트랜잭션 의한 변경 사항으로 인해 현재 사용중인 트랜잭션의 Where 절의 조건에 맞는 새로운 행이 생길 수 있는 경우에 관한 것이다.
예를 들어, 팬시의 잔고가 $100 미만인 계좌가 2개인 DB에서
$100 미만인 계좌를 찾는 트랜잭션이 있고, 그 트랜잭션안에서 Select 쿼리를 2번 수행한다고 가정하자.
처음에 데이터를 읽으면 2개의 계좌를 찾게 된다.
하지만 이 때 다른 트랜잭션에서 $0인 계좌를 새로 만들고 난 이후에
두 번째 데이터를 읽을 때에는 3개의 계좌를 찾게 된다.
이처럼 Where 절의 조건에 맞는 새로운 행이 생길 수 있는 경우를 말한다.
위의 표에서 알 수 있듯이 엄격해질수록 이상 현상을 허용하지 않는다.
격리 수준은 세 가지 이상 현상을 정의한 뒤 어떤 현상을 허용/허용하지 않는지에 따라 격리 수준이 나뉜다.
개발자는 이 격리 수준을 통해 전체 처리량(Throughput)과 데이터 일관성 사이에서 trade 할 수 있다.
DB는 데이터 무결성을 보장하는 것이 중요하다. 데이터 무결성
은 데이터의 정확성과 일관성을 유지하고 보증하는 것을 말한다.
그리고 그 무결성을 보장하기 위한 특징이 ACID(Atomicity, Consistency, Isolation, Durability)이다.
데이터베이스는 ACID 특징과 같이 트랜잭션이 독립적인 수행을 하도록 한다. 그래서 등장한 개념이 Locking이다.
Locking
은 트랜잭션이 DB를 다루는 동안 다른 트랜잭션이 관여하지 못하게 막는 역할이다.
하지만 무조건적인 Locking으로 동시에 수행되는 수많은 트랜잭션들을 순서대로 처리하면 DB의 성능은 현저히 떨어지게 될 것이다.
그렇다고 해서 성능을 높이기 위해 Locking 범위를 줄인다면, 잘못된 값이 처리될 수 있다.
그래서 최대한 효율적인 Locking 방법이 필요하다.
이와 관련된 Locking 방법이 격리 수준(Isolation Level)이다.
가장 낮은 격리 수준으로, 하나의 트랜잭션이 커밋되기 이전에 다른 트랜잭션에 노출되는 문제가 있지만 가장 빠르다.
이는 데이터 무결성을 위해 되도록이면 사용하지 않는 것이 이상적이나, 몇몇 행이 제대로 조회되지 않더라도 괜찮은 거대한 양의 데이터를 어림잡아 집계하는 데는 사용하면 좋다.
발생할 수 있는 문제
Phantom Read
Non-Repeatable Read
Dirty Read
가장 많이 사용하는 격리 수준이며, PostgreSQL, SQL Server, 오라클에서 기본값으로 설정되어 있다.
READ_UNCOMMITTED 와 달리 다른 트랜잭션이 커밋 되지 않은 정보는 읽을 수 없다.
즉, 커밋 완료된 데이터만 조회를 허용한다.
하지만, 어떤 트랜잭션이 접근한 행을 다른 트랜잭션이 수정할 수 있다.
예를 들어 트랜잭션 A가 수정한 행을 트랜잭션 B가 수정할 수 있다.
발생할 수 있는 문제
Phantom Read
Non-Repeatable Read
“REPEATABLE READ: This is the default isolation level for InnoDB.” - MySQL 공식문서 -
MySQL의 InnoDB엔진
의 기본 격리수준으로, 하나의 트랜잭션이 수정한 행을 다른 트랜잭션이 수정할 수 없도록 막아주지만 새로운 행을 추가하는 것은 막지 않는다.
따라서 이후에 추가된 행이 발견될 수 있다.
발생할 수 있는 문제
말 그대로 트랜잭션을 순차적으로 진행시키는 것을 말한다.(직렬화)
여러 트랜잭션이 동시에 같은 행에 접근할 수 없다.
이 수준은 매우 엄격한 수준으로 해당 행에 대해 격리시키고, 이후 트랜잭션이 이 행에 대해 일어난다면 기다려야 한다.
그렇기 때문에 교착 상태가 일어날 확률도 많고 가장 성능이 떨어지는 격리수준이다.
교착 상태(Dead Lock)란 두 트랜잭션이 각각 Lock을 설정한 다음 서로의 Lock에 접근하여 값을 얻어오려고 할 때 이미 각각의 트랜잭션에 의해 Lock이 설정되어 있기 때문에 양쪽 트랜잭션 모두 무한정 기다려야 하는 상태를 말한다.
트랜잭션 격리 수준이 필요한 이유는 무엇일까요?
트랜잭션 격리 수준에 대해 설명해 주세요.
트랜잭션 격리 수준에 따라 발생하는 현상에 대해 설명해 주세요.
면접을 위한 CS 전공지식 노트
이 글의 사진과 내용은 공룡책 과 컴퓨터학부 수업인 운영체제 강의자료를 기반으로 작성했습니다.
Concurrency(동시성)을 구현하기 전에, 먼저 Thread
에 대해 알아보자.
Thread
(스레드)란 하나의 프로세스 안에서 독립적으로 실행될 수 있는 개별 실행 단위(Each execution unit)이다.위의 그림처럼 스레드는 단일 실행 프로세스에 대한 새로운 추상화 개념이다.
프로그램은 이처럼 동시에 다중의 스레드를 사용하여 실행된다.
Multi-threaded Process
란 하나 이상의 스레드보다 많은 것을 가진 프로세스를 의미한다.
Context Switching unit
이 thread를 의미하며, 각각의 스레드는 자신만의 실행 상태(PC, register, stack)을 가진다.
그리고 각 스레드의 실행 상태(execution state)는 OS에 의해 관리되는 TCB(Tread Control Block)에 저장된다.
실행하고 있는 T1에서 다른 T2로 Switching이 발생했을 때,
T1의 실행 상태는 TCB에 복사(저장)되어야 하고, T2의 실행 상태는 TCB로부터 복원(저장)되어야 한다.
이때 T1, T2은 주소 공간을 공유한다는 점이다.
Stack
이다왼쪽 그림에서는 싱글 스레드고, 오른쪽 그림은 멀티 스레드다.
멀티 스레드의 경우 몇 개의 스레드가 주소 공간을 공유하기 때문에 하나의 주소 공간만을 사용하는 것을 볼 수 있고, 각각의 스레드들은 개별적인 스택 공간을 갖고 있어서 위와 같이 주소 공간에 Stack 부분이 분산되어 있다.
스레드들은 자신만의 Stack을 가지고 있고 Code, Data, Heap은 공유한다는 점에서 프로세스와 차이점을 지닌다.
Multi-threaded Process
(멀티 스레드)란 하나의 프로세스안에 여러 개의 스레드로 구성하여 하나의 스레드가 하나의 작업을 처리하도록 하는 것이다.
스레드를 사용하는 이유는 크게 2가지다.
첫 번째는 병렬 처리가 간단하다. 단일 프로세스에서 여러 스레드가 각자 하나의 작업을 처리하기 때문에 시간을 절약할 수 있다. 이렇게 단일 프로세스에서 각각의 스레드들이 여러 CPU에서 실행하는 것을 병렬화
라고 하며 이를 구현할 때 스레드를 사용하는 것이 일반적인 방법이다.
두 번째는 I/O로 인해 프로그램 수행이 차단되는 것을 막기 위해서이다. 다양한 유형의 I/O가 수행하는 프로그램이 있을 때, 프로그램의 자식 스레드가 오류가 나거나 긴 작업으로 인해 중단되었을 때 다른 스레드로 Context Switching하여 수행하면 I/O와 다른 작업들을 함께 수행할 수 있다.
하지만, 이런 스레드에서도 문제점이 존재한다.
첫 번째는 실행 순서가 OS 스케줄러에 의해 누가 먼저 수행될지를 모른다는 것이다.
다음 그림을 통해 제대로 이해해보자.
[첫 번째 경우의 수]
1. starts running
2. create thread 1
3. create thread 2
4. running thread 1
5. running thread 2
[두 번째 경우의 수]
1. starts running
2. create thread 1
3. running thread 1
4. create thread 2
5. running thread 2
[세 번째 경우의 수]
1. starts running
2. create thread 1
3. create thread 2
4. running thread 2
5. running thread 1
두 번째는 멀티 스레드에서 공유하는 데이터에 동시에 접근할 때(업데이트 할 때) 문제가 발생한다.
다음 그림을 통해 제대로 이해해보자.
여기서 counter
는 data 영역(전역 변수)라고 가정한다.
왼쪽은 예상된 결과인 counter 값이 12로 나오고, 오른쪽은 예상치 못한 결과인 counter 값이 11로 나오는 것을 확인할 수 있다.
오른쪽에서 2번째 순서인 tmp = tmp + 1
를 끝나고 갑자기 Context Switching이 발생했을 때, 2번에서 counter 값이 업데이트 되지 않았기 때문에 3번에서 counter = 10으로 다시 시작된다.
그래서 4-5번을 거쳐 counter = 11로 끝나고 다시 Tread1로 넘어오면서 counter = 11 로 끝나는 결과를 보여준다.
이렇게 전역 변수와 같이 스레드에서 공유하는 데이터에 접근하는 상황을 Race condition(경쟁 상태)라고 하며,
여기서 전역 변수와 같은 공유되는 값을 Critical section(임계 영역)이라고 하며 위와 같이 임계 영역에 여러 개의 스레드가 동시에 접근하면 원하는 결과를 얻지 못하는 상황이 발생하게 된다.
그리고 임계 영역에 접근하는 스레드들 중에서 어떤 스레드가 먼저 읽었는지
와 같은 접근 순서, 타이밍과 같은 것이 결과에 영향을 끼치는 상태를 Indeterminate(불확실성) 라고 말한다.
Critical section
(임계영역)은 여러개의 스레드가 동시에 접근해서는 안되는, 즉 하나의 스레드만 접근할 수 있는 영역이다.
다수의 스레드가 critical section 접근하면 Race condition(경쟁 상태)의 결과를 가져온다.
만약 어떤 스레드가 critical section에 접근하는 중이라면 다른 스레드가 접근할 수 없도록 atomicity(원자성)을 보장해야 하며, 이를 mutual exclusion(상호 배제)라고 부른다.
REST
(Representation State Transfer)란 자원을 이름으로 구분하여 해당 자원의 상태를 주고 받는 모든 것을 의미한다.
HTTP URI(Uniform Resource Identifier)를 통해 자원을 명시하고, HTTP 메소드(GET, POST, PUT, PATCH, DELETE)를 통해 해당 자원(URI)에 대한 CRUD Operation을 적용하는 것을 의미한다.
CRUD Operation
이란 Create, Read, Update, Delete를 묶어서 읽컫는 말이다.
REST 에서 CRUD Operation 동작 예시는 다음과 같다.(HTTP 메소드와 비교)
Create
: 데이터 생성 <-> POST
Read
: 데이터 조회 <-> GET
Update
: 데이터 수정 <-> PUT, PATCH
Delete
: 데이터 삭제 <-> DELETE
참고) HTTP 메소드에 가면, HTTP 메소드의 종류와 속성을 따로 정리해 두었다.
자원(Resource) : HTTP URI 형태로 나타낸다.
자원에 대한 행위(Verb) : HTTP Method를 나타낸다.
자원에 대한 행위의 내용(Representations) : HTTP Message Pay Load를 타나낸다.
[1] Uniform Interface(인터페이스 일관성)
HTTP 표준에만 따른다면, 안드로이드/IOS 플랫폼이든, 특정 언어나 기술에 종속하지 않고 모든 플랫폼에 사용할 수 있으며, URI로 지정한 리소스에 대한 조작이 가능한 아키텍쳐 스타일을 의미한다.
이러한 범용성을 갖추기 위해 REST API의 HTTP Response Body는 HTML 보다는 JSON, XML 등 여러 플랫폼에서 사용하기 적절한 단순한 텍스트 포맷을 사용한다.
(REST를 이야기 하면, HTTP + JSON을 쉽게 떠올리는데, JSON은 하나의 옵션일 뿐, 메시지 포맷을 꼭 JSON으로 적용해야할 필요는 없다)
[2] Stateless(무상태)
작업을 위한 상태 정보를 따로 저장하지 않고 관리하지 않는다. 즉, 각 요청에 대한 컨텍스트(세션, 로그인 정보)가 서버에 저장되어선 안된다.
세션 정보나 쿠키 정보를 별도로 저장, 관리하지 않기 때문에 API 서버는 들어오는 요청만을 단순히 처리하면 된다.
그래서 서비스의 자유도가 높아지고 서버에서 불필요한 정보를 관리하지 않으므로 구현이 단순해진다.
[3] Cacheable(캐시 처리 가능)
REST의 가장 큰 특징 중 하나는 HTTP라는 기존 웹 표준을 그대로 사용하므로 웹에서 사용하는 기존 인프라를 그대로 활용이 가능하다.
HTTP 프로토콜 기반의 로드 밸런서나 암호화(SSL)은 물론이고 HTTP가 가진 가장 강력한 특징중의 하나인 캐싱 기능을 적용할 수 있다.
HTTP 프로토콜 표준에서 사용하는 Last-Modified
태그나 E-Tag
를 이용하면 캐싱 구현이 가능하다.
[4] Client-Server(클라이언트-서버 구조)
REST 서버는 API를 제공하고, 제공된 API를 이용해서 비즈니스 로직 처리 및 저장을 책임진다.
클라이언트는 사용자 인증이나 컨텍스트(세션, 로그인 정보) 등을 직접 관리하는 구조로 각각의 역할이 확실히 구분되기 때문에 클라이언트와 서버에서 개발해야 할 내용이 명확해지고 서로 간에 의존성이 줄어들게 된다.
[5] Layered System(계층형 구조)
클라이언트는 보통 대상 서버에 직접 연결되었는지 중간 서버를 통해 연결 되었는지를 알 수 없다.
중간 서버는 로드 밸런싱 기능이나 공유 캐시 기능을 제공함으로써 시스템 규모의 확장성을 향상시키는데 유용하다.
클라이언트 입장에서는 REST API 서버만 호출할 수 있는 반면에, 서버는 다중 계층으로 구성될 수 있다.
순수 비즈니스 로직을 수행하는 API 서버와 그 앞단에 사용자인증(보안), 로드 밸런싱, 암호화(SSL) 계층을 추가해서 구조상의 유연성을 둘 수 있다.
그리고 Proxy, Gateway 같은 네트워크 기반의 중간매체를 사용할 수 있게 한다.
장점
HTTP 프로토콜의 표준을 최대한 활용하여 여러 추가적인 장점을 함께 가져갈 수 있게 해준다.
HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다.
REST API 메시지가 의도하는 바를 명확하게 나타내기 때문에 의도하는 바를 쉽게 파악할 수 있다.
여러 가지 서비스 디자인에서 생길 수 있는 문제를 최소화한다.
클라이언트와 서버의 역할을 명확하게 분리한다.
단점
REST는 표준이 없어서 관리가 어렵다.
HTTP 메소드 형태가 제한적이다.
웹 브라우저를 통해 테스트해야할 일이 많은 서비스라면, 쉽게 고칠 수 있는 URI보다 Header 정보의 값을 처리해야 하므로 전문성이 요구된다.
구형 브라우저에서 호환되지 않아, 익스플로어와 같은 지원이 안되는 동작이 많다.
REST API
란 REST의 아키텍쳐 스타일을 따르는 API를 의미한다.
API
란 Application Programming Interface 약자로, 다른 소프트웨어 시스템과 통신하기 위해 따라야 하는 규칙을 의미한다.[1] URI는 명사, 소문자를 사용해야 한다.
Bad Example https://devfancy.github.io/Healthy
Good Example https://devfancy.github.io/health
[2] 마지막에 슬래시(/) 포함하지 않는다.
Bad Example https://devfancy.github.io/health/
Good Example https://devfancy.github.io/health
[3] 언더바(_) 대신 가독성을 높이는 하이픈(-)을 사용한다.
Bad Example https://devfancy.github.io/health_club
Good Example https://devfancy.github.io/health-club
[4] 파일 확장자(.png, .jpg)는 URI에 포함시키지 않는다.
Bad Example https://devfancy.github.io/developer.png
Good Example https://devfancy.github.io/developer
[5] 행위를 포함하지 않는다.
Bad Example https://devfancy.github.io/delete/post/1
Good Example https://devfancy.github.io/post/1
RESTful
은 일반적으로 REST라는 아키텍쳐를 구현하는 웹 서비스를 나타내기 위해 사용하는 용어이다.
RESTful API 용어와 REST API 용어는 일반적으로 같은 의미로 사용하나, REST를 사용했다고 모두 RESTful 하다고 볼 수 없다.
REST API의 설계 규칙을 제대로 지킨 시스템을 RESTful하다고 볼 수 있다
만약 모든 CRUD 기능을 REST API 혹은 URI 규칙대로 지키지 않았다면, REST API를 사용했다고 말하지만, RESTful 하지 못한 시스템이라고 말할 수 있다.
RESTful의 목적은 이해하기 쉽고 사용하기 쉬운 REST API를 만드는 것이다.
RESTful한 API를 구현하는 근본적인 목적이 성능 향상에 있는 것이 아니라 일관적인 컨벤션을 통한 API의 이해도 및 호환성을 높여주는 것이 주 목적이다.
성능 향상이 주 목적인 상황에서는 굳이 RESTful한 API를 구현할 필요는 없다.
클라이언트가 서버에게 요청을 전송한다.
서버가 클라이언트를 인증하고 해당 요청을 수행할 수 있는 권한이 클라이언트에 있는지 확인한다.
서버가 요청을 수신하고 내부적으로 처리한다.
서버가 클라이언트에 응답을 반환한다. 응답에는 요청이 성공했는지 여부를 클라이언트에게 알려주는 정보가 포함된다. 또한 클라이언트가 요청한 모든 정보도 포함된다.
REST에 대한 개념을 공부했지만, 아직은 부족한 느낌이 든다.
REST와 REST API, RESTful API에 대한 공부를 추가적으로 더 하면서 해당 블로그를 업데이트를 하자.