[TIL - 1011] 옵저버패턴, REST에 다가가기, mysql 데이터 타입, git 명령어 제대로 사용해보기, HTTPS

REST

  • 도대체 REST가 무엇인가? 이전까지는 그냥 아키텍쳐 스타일, API를 디자인할 때 지켜야하는 원칙들의 모음이라고만 얼핏 알고 있었음 그러니 누가 설명해달라고 했을 때 선뜻 이게 무엇이다라는 말을 하지 못하겠음 그 말은 즉슨 내가 잘 모른다는 사실 그래서 REST에 대해서 나름의 정의를 머리에 가지기 위해 여러 글들을 찾아보게 됨
    • REST 원칙들이 무엇인지는 알아도, REST가 왜 고안되었는지는 알아도 정작 REST의 REpresentational State Transfer에 대해 관심을 가져보지 않음

REST 알아보기

  • 특정 리소스의 상태 정보를 전달하는 것을 말함 : HTTP 메세지 payload에 특정 리소스의 수정될 상태를 전달하는 것도, 단순히 보여달라는 것도, 삭제해달라는 상태 정보 전달까지도 포함
    • 위의 뜻을 이해하다보니 HTTP 통한 통신을 할 때 REST API 설계를 한다면 HTTP 메세지(GET/POST/PUT/DELETE 등), 리소스 id 부여(uri) 등을 왜 하는지, 필요한지 이해하게 됨
    • 상태 정보를 전달하는 것 : 읽기/수정/삭제 요청과 응답(요청 처리한 후의 리소스 상태 정보)에 상태 정보를 담아서 줌, 여기서 말하는 리소스는 전달 매게체인 문서는 아님 - 타겟(uri)이 되는 리소스
    • 리소스에 대한 어떤 요청을 할 때 전달하는 HTTP 헤더는 representation metadata
    • 리소스 중심 아키텍쳐 설계
  • REST API 설계를 했을 때 왔다리 갔다리 하는 payload는 representationl(리소스 상태 정보) : HTTP 헤더 + HTTP 바디

참고

옵저버 패턴

  • A객체의 변화를 체크하기위해서 매번 연관된 객체가 상태 체크를 하는 것이 아니라 A객체가 연관 객체 목록을 가지고 있고 자신의 상태 변경 때 연관 객체들에게 업데이트를 알리는 패턴 : 상태 체크를 매번해서 뭔가를 하기보다 자동적으로 하도록 해서 복잡도를 줄이는 방법이라고 생각 됨
    • 역할 분담 : Observable(Publisher) / Observer
    • 옵저버 중 선택적으로 노티를 주기위해서는 조금 수정할 필요가 있어보임
public class NewsPublisher { 

    private ArrayList<Reader> readers = new ArrayList<>();

    public int addReader(Reader reader) {
        .
        .
        .
        return readers.size();
    }

    public void update() {
        .
        .
        .        
        notifyToReader();
    }

    private void notifyToReader() {
        for (Reader reader : readers) {
            .
            .            
        }
    }
}

옵저버 패턴 API

  • API 패키지 + 클래스명 : java.util.Observable, java.util.Observer
  • 두 역할에 맞게 클래스(Observable) 상속, 인터페이스(Observer) 구현하면 됨 : 명칭 상으로 Observer라서 다형성을 이용할 때 뜻 파악하기가(아니면 상위 클래스를 하나 더 만들던가 - 복잡도만 증가)

RDBMS(mysql v5.7)

기본키와 유니크키 차이

  • 언뜻 보면 같은 의미 아닐까 라는 생각에 한번 찾아보기로 함
  • 제약사항의 차이 : 기본키(primary)의 경우 유일한 값 + Not Null, 유니크키의 경우 유일한 값 + Nullable

데이터 타입

  • 데이터 타입에 따라 차지하는 공간이 다르기때문에 맞지않는 데이터 타입을 사용하는 것은 비효율적
  • 숫자
    • tiny int(1byte)
    • small int(2byte)
    • int(4byte), big int(8byte)
    • double/float
    • decimal : 10진수, 1자리 당 1byte, 소수점 자리까지 지정가능, 정확한 값 저장 - 중요한 데이터 일수록 해당 데이터타입(소수점까지 정확한 데이터를 저장하기위해서는 실수형보다 decimal로 하는 것이)
  • 문자열
    • char : 고정길이 문자열 저장 시, 최대 255 bytes 까지 선언가능, 선언된 크기만큼 데이터가 저장되지않을 시 공백으로 채움
    • varchar : 가변길이 문자열 저장 시, 최대 65,535 bytes 까지 선언가능
    • 인코딩(컴퓨터에 문자를 저장하기위한 집합/맵핑표 - 비트 세상에서, 바이트 단위)에 따른 한글 데이터 크기 : utf-8(3byte), utf-16(2byte)
  • 시간
    • date : 년월일
    • time : 시간
    • datetime : date + time 데이터 저장
    • timestamp : datetime과 같은 데이터가 저장되나 자동적으로 생성/수정을 인식하고 데이터가 변경됨
mysql> select * from user;
+----+----------+---------------------+
| id | name     | created_time        |
+----+----------+---------------------+
|  1 | jinbro   | 2018-10-10 15:33:42 |
|  2 | jinhyung | 2018-10-10 15:33:42 |
+----+----------+---------------------+

mysql> update user set name = 'gnyun' where id = 1;
Query OK, 1 row affected (0.01 sec)

mysql> select * from user;
+----+----------+---------------------+
| id | name     | created_time        |
+----+----------+---------------------+
|  1 | gnyun    | 2018-10-10 15:40:03 |
|  2 | jinhyung | 2018-10-10 15:33:42 |
+----+----------+---------------------+
  • 대용량 데이터
    • BLOB(Binary Large Object, tiny/normal/medium/long) : binary string 저장
    • text(tiny/normal/medium/long) : character string 저장(non-binary), varchar와의 차이점을 더 파악해보도록
    • 이미지의 경우 DB에 데이터를 그대로 저장하지않고, 요즘은 디스크에 파일 저장 후 파일을 식별할 수 있는 값을 DB에 저장하는 것이 추세라고 함 : 코드스쿼드에서 파일 업로드 기능 만들 때에도 그렇게 해보았음

git

  • 공부할 때 이용한 페이지(시각적으로 어떤 결과가 나올 지 보여주기도 하고 실습 환경이 갖춰져 있어서 매우 좋다고 생각됨, 더 자세하게 동작 보려고 repo를 만들어 실험해봄) - learn git branching
  • commit : 스냅샷, 전체를 기록하는게 아니라 이전 커밋과의 차이점만을 기록하고 있음
  • branch : 커밋의 참조변수(단지 커밋을 가리키는, 커밋의 고유값을 저장하고 있는 참조변수), 메모리 주소값을 직접 다루지않고 참조변수에 담아 사용하는 것처럼, 커밋의 주소를 직접적으로 다루는 것은 안좋은 행동
  • HEAD : 현재 커밋을 가리킴
  • merge : 브랜치 둘을 합침, 같은 파일에 대해 다르게 변경 후 커밋을 기록한 후 merge 할 경우 merge conflict가 발생할 수 있는데 수동으로 merge를 해줘야함(수정 후), 새로운 커밋을 만들어냄
  • rebase : 현재 선택된 브랜치의 커밋을 복사하고 대상이 되는 커밋 뒤에 이어 새로운 커밋을 만드는 작업, 말 그대로 base를 다시 잡아 commit을 하는 것, 주의할 점은 rebase할 때 base로 삼을 커밋과 같은 곳에 대해 변경을 다르게 했을 때 conflict 발생함 -> 고친 후 stage 한 후 rebase –continue를 하면 됨
> git rebase master
First, rewinding head to replay your work on top of it...
Applying: jinbro first commit
Using index info to reconstruct a base tree...
M	text.txt
Falling back to patching base and 3-way merge...
Auto-merging text.txt
CONFLICT (content): Merge conflict in text.txt

# 수동으로 conflict 수정 후
> git add test.txt
> git rebase --continue
  • reset : 브랜치가 가리키는 커밋을 이전 커밋으로 바꾸는 것(참조 변수에 저장된 주소값을 변경), reset이 위험한 점은 기존 커밋은 그대로 두고 이전 커밋으로 가기때문에 변경 전 커밋에서 브랜치를 따고 다른 사람이 작업을 했다면 위험(reset을 한 쪽에서 새로운 커밋을 만들어 나가기 시작하면 브랜치를 딴 브랜치와는 전혀 다른 커밋 줄기), 혼자서 작업을 할 때는 상관없지만 같이 작업하는 환경에서는 reset을 함부로 사용하지말 것
> git log --graph --oneline
* 86503df (HEAD -> jinbro) fifth commit
* 391a28f Revert "jinbro third commit"

> git reset --hard 
> git log --graph --oneline
* 391a28f (HEAD -> jinbro) Revert "jinbro third commit"
* b857b3b jinbro forth commit
  • revert : 대상이 되는 커밋의 내용으로 돌아가되 현재 커밋의 다음 커밋을 만듦(새로운 커밋)
> git log --graph --oneline
* b857b3b (HEAD -> jinbro) jinbro forth commit
* 03d2e96 jinbro third commit

> git revert 03d2e96
* 391a28f (HEAD -> jinbro) Revert "jinbro third commit"
* b857b3b jinbro forth commit
* 03d2e96 jinbro third commit

HTTPS

  • secure socket layer 추가 : SSL 프로토콜로 한층 더 보안에 신경 쓴 HTTP - 데이터 암호화, 인증된 서버(CA에 의한, 신뢰할 수 있는 제 3의 기관, 웹브라우저 벤더가 공인한 회사)
  • HTTPS 통신 이뤄지는 과정
    1. 인증서 응답 : 제대로된 인증서인지 판단(브라우저에 리스트 - CA 맞는지), 정상적인 서버 인증
    2. 인증서 공개키로 복호화 -> 서버 공개키 획득
    3. 획득한 서버의 공개키로 클라이언트 대칭키 암호화 : 중간에 탈취 당하더라도 서버에서 비밀키만 누출되지않았다면 대칭키 탈취 당하지않음, 서버는 클라이언트와 통신할 수 있는 대칭키를 안전하게 획득
    4. 데이터 주고 받기
    5. 세션 종료 시 대칭키 만료
  • 데이터를 암호화 할 수도 있으면서 비밀키 형식으로 데이터를 암호화 - 복호화 하지않기 때문에 컴퓨팅 파워를 아낄 수 있음