장고 orm이나 파이썬 코드를 보면 *args, **kwargs를 확인할 수 있습니다.

해당 뜻은 어떤 파라미터를 몇개를 받을지 모르는 경우 사용한다 라고 하지만 막연하기 때문에 예를 들어 설명하겠습니다.

*args 

 *args는 파라미터를 몇개를 받을지 모르는 경우 사용하고 튜플 형태로 전달됩니다.

 def test(*args):
    print(args)

test('a','b','c')


#결과 ('a', 'b', 'c')

위처럼 argument로 여러 값을 던지고 해당 함수에서 tuple을 사용할 수 있습니다.


dict타입과 같이 변수 자체를 그대로 넘기면 튜플 내에 데이터 1개로 취급됩니다.

def test(*args):
    print(args)

a = {'name': 'a', 'name2': 'b', 'name3': 'c'}
test(a)


#결과 ({'name3': 'c', 'name': 'a', 'name2': 'b'},)



아래와 같이 dict 변수에 포인터를 붙여서 사용하면 dict 변수내의 키값만 빠져 튜플형태를 이루게 됩니다.

def test(*kwargs):
    print(kwargs)

a = {'name': 'a', 'name2': 'b', 'name3': 'c'}

test(*a)
 
#결과 ('name', 'name2', 'name3')


**kwargs

- 파라미터 명을 같이 보낼 수 있고 kwargs는 딕셔너리 형태로 전달됩니다.

def test(**kwargs):
    print(kwargs)


test(name1='a', name2='b', name3='c')


#결과 {'name2': 'b', 'name3': 'c', 'name1': 'a'}


만약 이미 dict 형태인 값을 가지고 있고, 해당 함수에 변수 자체를 넘기고 싶을 경우 아래와 같이 합니다.


def test(**kwargs):
    print(kwargs)


a = {'name': 'a', 'name2': 'b', 'name3': 'c'}

test(**a)


# 결과 {'name': 'a', 'name2': 'b', 'name3': 'c'}


젠킨스를 통해 지속적인 통합 (CI: Continuous Integration)을 행할 수 있다.


형상관리(git, 서브버전 등)와의 연동

젠킨스와 같은 CI툴이 등장하기 전에는 일정시간마다 빌드를 실행하는 방식이 일반적이었다. 특히 개발자들이 당일 작성한 소스들의 커밋이 모두 끝난 심야 시간대에 이러한 빌드가 타이머에 의해 집중적으로 진행되었다. 젠킨스는 정기적인 빌드에서 더 업그레이드 해 서브버전, Git와 같은 버전관리 툴과 연동하여 소스의 커밋을 감지하면 자동적으로 자동화 테스트가 포함된 빌드가 작동되도록 설정 할 수 있다. 개발 도중의 커밋은 빈번하게 일어나기 때문에 커밋 횟수만큼 빌드를 실행하는 것이 아니라 큐잉되어 자신이 실행될 차례를 기다리게 된다. 
 코드의 변경과 함께 이뤄지는 자동화 빌드와 테스트 작업들은 다음과 같은 이점들을 가져다 준다.
  • 프로젝트 표준 컴파일 환경에서의 컴파일 오류 검출
  • 자동화 테스트 수행
  • 정적 코드 분석에 의한 코딩 규약 준수여부 체크
  • 프로파일링 툴을 이용한 소스 변경에 따른 성능변화 감시
  • 결합 테스트 환경에 대한 배포작업

이 외에도 젠킨스는 500여가지가 넘는 플러그인을 온라인으로 간단히 인스톨 할 수 있는 기능을 제공하고 있으며 파이선과 같은 스크립트를 이용해 손쉽게 자신에게 필요한 기능을 추가 할 수도 있다.

 

각종 배치 작업의 간략화

프로젝트 기간 중에 개발자들은 순수한 개발 작업 이외에 DB셋업이나 환경설정, deploy 작업과 같은 단순 작업에 시간과 노력을 소비하는 경우가 빈번하다. 데이터베이스의 구축, 어플리케이션 서버에 deploy,  라이브러리 릴리즈와 같이 이전에 커맨드 라인 인터페이스로 실행되던 작업들이 젠킨스 덕분에 미려한 웹 인터페이스로 손쉽게 가능해지게 되었다.

 

젠킨스은 거들뿐

이와같이 다양한 작업들을 손쉽게 처리해 주지만 테스트를 만들고 빌드 전략을 세우는 등의 작업은 여전히 개발자의 몫으로 남아 있다. 젠킨스가 진정으로 프로젝트에 도움이 되기 위해서는 다음과 같은 작업이 반드시 함께 이루어 져야 한다.

Build 자동화의 확립

빌드 툴의 경우 Java는 이미 Maven이 대세로 자리 잡았다. 물론 Ant도 훌륭한 기능들을 많이 갖추고 있지만 플러그인의 편리함은 Maven을 따라잡지 못한다. 이미 빌드관리 툴을 이용해 프로젝트를 진행하고 있다면 Jenkins를 사용하지 않을 이유가 하나도 없다.

 

자동화 테스트

자동화 테스트는 젠킨스를 사용해야 하는 이유 중 하나이며, 사실상 자동화 테스트가 포함되지 않은 빌드는 CI자체가 불가능하다고 봐도 무방하다. 젠킨스는 Subversion이나 Git와 같은 버전관리 시스템관 연동하여 코드변경을 감지하고 자동화 테스트를 수행해 줌 으로서 만약 개인이 미처 실시하지 못한 테스트가 있다 하여도 든든한 안전망이 되어준다. 무엇보다 중요한것은 이러한 안전망이 제공해 주는 안심감이야 말로 개발자들이 악취나는 코드를 리팩토링을 통해 적극적으로 제거 할 수 있게 해 주는 든든한 버팀목이 된다는 점이다.

 

테스트 커버리지

젠킨스는 자동화 테스트 실시와 더불어 테스트 커버리지도 리포팅을 해 준다. 

코드 표준 준수여부 검사

 자동화 테스트와 마찬가지로 개인이 미처 실시하지 못한 코드 표준 준수여부의 검사나 정적 분석을 통한 코드 품질 빌드 내부에서 수행하는 것으로서 기술적 부채의 감소에도 크게 기여한다.

 빌드 파이프라인 구성

2개 이상의 모듈로 구성되는 프로젝트의 경우 당연하게도 레이어드 아키텍처가 적용되어 있을터이고 그에 따른 빌드 파이프라인 구성이 필요하다. 예를 들자면 도메인 -> 서비스 -> UI와 같이 각 레이어의 참조관계에 따라 순차적으로 빌드를 진행하지 않으면 안된다. 이러한 파이프라인의 구성은 선형 뿐만 아니라 간단한 스크립트를 통해 매우 복잡한 제어 까지도 가능하다. 


Rest API란

REST는 HTTP/1.1 스펙과 동시에 만들어졌는데, HTTP 프로토콜을 정확히 의도에 맞게 활용하여 디자인하게 유도하고 있기 때문에 디자인 기준이 명확해지며, 의미적인 범용성을 지니므로 중간 계층의 컴포넌트들이 서비스를 최적화하는 데 도움이 된다. REST의 기본 원칙을 성실히 지킨 서비스 디자인은 “RESTful 하다.” 라고 흔히 표현.

무엇보다 이렇게 잘 디자인된 API는 서비스가 여러 플랫폼을 지원해야 할 때, 혹은 API로서 공개되어야 할 때, 설명을 간결하게 해주며 여러 가지 문제 상황을 지혜롭게 해결하기 때문에 (버전, 포맷/언어 선택과 같은) REST는 최근의 모바일, 웹 서비스 아키텍처로서 아주 중요한 역할을 하고 있다.

웹 아키텍처

  1.  클라이언트/서버 (Client/Server)
  2. 균일한 인터페이스 (Uniform Interface)
  3. 계층 시스템 (Layered System)
  4. 캐시 (Cache)
  5. 상태 없음 (Stateless)
  6. 주문형 코드 (Code-on-demand)

클라이언트/서버

균일한 인터페이스

웹을 구성하는 클라이언트, 서버, 네트워크 등의 인터페이스 (웹 컴포넌트들) 중 하나라도 표준에서 벗어나면, 웹 커뮤니케이션 체계는 붕괴된다. 웹 컴포넌트들은 다음 제약에 따라 서로 일관성 있게 상호 운영된다.

  1. 리소스 식별
  2. 표현을 통한 리소스 처리
  3. 자기-서술적 메시지 (Self-descriptive messages)
  4. 애플리케이션 상태 엔진으로서의 하이퍼미디어(HATEOAS07)

리소스 식별

리소스는 웹 상에서 서로 구별할 수 있는 URI와 같은 개념으로 볼 수 있다.

표현을 통한 리소스 처리

클라이언트는 리소스 표현을 처리한다. 같은 리소스라도 표현방식은 달라질 수 있다. 예로 문서가 웹에서 HTML로 표현되지만 타 프로그램에서는 JSON으로 표현될 수 있다. 이러한 표현이 다양하다고 해서 리소스, 식별자 자체가 변하지는 않는다.

자기-서술적 메시지

자기-서술적 메시지는 메타데이터를 포함하는데, 메타데이터에는 리소스의 상태, 표현 형식과 크기, 메세지, 자신에 대한 추가 정보등 이 포함되어 있다. HTTP 메세지는 일정한 형태로 여러 종류의 메타데이터 정보를 넣을 수 있는 헤더를 제공한다.

애플리케이션 상태 엔진으로서의 하이퍼미디어

계층 시스템

계층 시스템이라는 제약조건은 프락시 또는 게이트웨이 같은 네트워크 기반의 중간매체를 사용할 수 있게 한다. 웹의 일관된 인터페이스를 사용하면 중간매체를 클라이언트와 서버 사이에 마치 없는 것처럼 배치할 수 있다. 일반적으로 네트워크 기반의 중간매체는 특별한 목적을 위해 클라이언트와 서버간 통신을 가로챌 수 있다. 네트워크 기반의 중간매체는 보통 보안을 강화하거나,응답을 캐싱하거나, 부하를 분산하는 용도로 사용한다.

캐시

캐시는 웹 구조의 중요 제약조건 중 하나다. 캐시라는 제약조건에 의해 웹 서버가 응답 데이터마다 캐시 여부를 선언한다. 캐싱 응답 데이터는 클라이언트가 느끼는 지연을 감소시키고 애플리케이션의 전체적인 이용 가능성과 안정성을 향상시키며, 웹 서버의 부하를 제어한다. 다시 말해, 캐싱08은 웹의 전체적인 비용을 낮출 수 있는 중요한 방법이다. 캐시는 클라이언트와 서버 사이의 네트워크 경로라면 어디에라도 위치할 수 있다. 웹 서버단, 콘텐츠 전송망CDN단, 또는 클라이언트 내에도 가능하다.

상태 없음

상태 없음 제약조건은 웹 서버가 클라이언트의 상태를 관리할 필요가 없다는 의미다. 따라서 각 클라이언트는 웹 서버와 상호작용하는 관련 상황 정보를 직접 관리해야 한다. 웹 서버는 웹 애플리케이션과의 복잡한 커뮤니케이션을 위해 필요한 상태 관리를 클라이언트에 맡김으로써 더 많은 클라이언트에 서비스할 수 있다. 이러

한 트레이드오프는 웹 구조적인 스타일의 확장성에 이바지하는 주요 요소다.

주문형 코드

웹은 주문형 코드Code-On-Demand를 아주 많이 사용한다. 이 제약조건은 스크립트나 플러그인 같은 실행 가능한 프로그램을 일시적으로 클라이언트에 전송하여, 클라이언트가 실행할 수 있도록 한다. 주문형 코드는 웹 서버와 클라이언트 사이에 기술적 결합을 만들어내기도 하는데, 클라이언트는 필요할 때마다 서버에서 내려받은 실행 코드를 이해해야 하기 때문이다. 이러한 이유로 주문형 코드는 웹의 구조적 스타일에서 유일한 선택사항이다. 주문형 코드 제약사항의 예로 자바 애플릿, 자바스크립트, 플래시 같은 웹 브라우저 기반의 기술들이 있다.

URI 규칙

  • 슬래시 (/)는 계층관계를 나타내는데 사용

  • 마지막 문자로 슬래시를 포함하지 않음
  • 하이픈(-)은 URI 가독성을 높이는데 사용
  • 밑줄(_)은 URI에 사용하지 않음
  • URI 경로에는 소문자가 적합
  • 파일확장자는 URI에 포함시키지 않음
  • API에 있어 서브 도메인은 일관성 있게 사용

리소스 원형

도큐먼트 (단수명사, 명사의 조합)

도큐먼트리소스는 객체 인스턴스나 데이터베이스 레코드와 유사한 단일개념이다. 도큐먼트는 값을 가지고 있는 필드와 다른 관련 리소스와의 링크 둘 다를 가진다.

컬렉션 (복수명사)

컬렉션 리소스는 서버에서 관리하는 디렉터리 리소스이다. 클라이언트는 새로운 리소스를 제안해서 컬렉션에 포함할 수 있다. 

스토어

스토어는 클라이언트에서 관리하는 리소스 저장소이다. 스토어 리소스는 API 클라이언트가 리소스를 넣거나 지우고, 업데이트 하는 것을 말한다. 스토어는 스스로 새로운 리소스를 생성하지 못하기 때문에 새로운 URI를 만들지는 못한다.

컨트롤러(동사)

기본으로 GET, PUT, POST, DELETE 요청에 1:1매치 되는 개념인 CRUD가 존재하며 CRUD의 앞글자들을 풀어보면 Create, Read, Update, Delete가 될 텐데, 각각 POST, GET, PUT, DELETE에 대응되는 개념이다. 그런데 사실 URI를 디자인 하다 보면 이러한 방식으로 나타내기 참 어려운 경우를 많이 만나게 된다. 그 중 가장 많은 경우가 어떤 특정한 행위를 요청하는 경우이다. 많은 분이 이럴 때 동사를 쓰는데, 앞선 포스팅에서 밝혔듯이 동사를 써서 URI를 디자인하는 것은 대체로 옳지 않은 방식으로 여겨진다.

이럴 때 컨트롤러 리소스를 정의하여 이 문제를 해결할 수 있다. 컨트롤러 리소스는 URI 경로의 제일 마지막 부분에 동사의 형태로 표시되어 해당 URI를 통해 접근했을 때 일어날 행위를 생성한다. (개념적으로는 이렇게 이해하면 됨) 생성과 관련된 요청이 POST이기 때문에 컨트롤러 리소스에 접근하려면 POST 요청을 보내야 함.

http://api.college.restapi.org/students/morgan/register
리소스 morgan을 등록

http://api.ognom.restapi.org/dbs/reindex
리소스 dbs를 재색인

http://api.build.restapi.org/qa/nightly/runTestSuite
리소스 nightly에 테스트를 수행

그리고 마치 프로그램의 함수처럼 컨트롤러 리소스에는 입력값을 전달할 수 있음. 그것은 POST 요청의 엔티티 바디에 포함되어야 함. 그리고 역시 함수에서 반환값을 돌려주듯이 컨트롤러 리소스에서는 해당 입력 값에 대한 응답 값을 돌려주어야 함.

규칙

  • 도큐먼트 이름은 단수 명사로 사용
  • 컬렉션 이름은 복수명사로 사용
  • 스토어 이름은 복수명사
  • 경로 부분 중 변하는 부분은 유일한 값(고유 값)으로 대체
  • Crud기능을 나타내는 것은 URI에 사용하지 않음
  • URI 쿼리 부분으로 컬렉션이나 스토어를 필터링 할 수 있음
    • GET/users?role=admin     - 응답 메시지의 상태표현은 컬렉션에 있는 사용자 중 'role'의 값이 'admin'인 사용자의 리스트
  • URI 쿼리는 컬렉션이나 스토어의 결과를 페이지로 구분하여 나타내는데 사용

컬렉션과 도큐먼트

도큐먼트는 우리말로 문서로 이해해도 되고, 정보라고 이해해도 무관. 도큐먼트는 엘리먼트(element)라고도 불림 컬렉션은 정보(문서)들의 집합. 컬렉션과 도큐먼트는 모두 리소스라고 표현할 수 있으며 URI에 표기가 됨

http://www.remotty.com/sports/soccer
http://www.remotty.com/sports/soccer/players
http://www.remotty.com/sports/soccer/players/13/skills

http://www.remotty.com/sports는 컬렉션임. sports컬렉션에 soccer도큐먼트가 존재하고 soccer도큐먼트에 player이라는 컬렉션이 존재함. players컬렉션에 등번호가 13번인 선수가 존재한다고 가정하면 여기서 13은 도큐먼트이다. soccer 도큐먼트와 동일한 수준의 다른 도큐먼트는 baseballmarathon 등이 있다고 볼 수 있다. 그 하위의 players의 컬렉션과 동일한 수준의 컬렉션은 뭐가있을지 생각해보면  rulesleagues 등이 존재할 것이다.

HTTP Method에 맞는 역할

HTTP Method는 여러가지가 있지만 REST API에서는 4개 혹은 5개의 Method만 사용됨. POSTGETPUTDELETE 이 4가지의 Method를 가지고 CRUD를 할 수 있음. 그러나 REST API에서 사용되는 개수는 4개 혹은 5개라고 한 이유는 PATCH를 포함하면 5개가 되기 때문.

각 Method마다 올바른 역할이 존재

URI
POSTGETPUTDELETE
http://www.remotty.com/sports
12

 http://www.remotty.com/sports/soccer

345

번호를 이용하여 설명하겠습니다.

  1. 현재 리소스 보다 한단계 아래에 리소스를 생성. POST Method를 통해 해당 URI를 요청하면 sports 컬렉션에 알맞은 soccer 또는 baseball과 같은 도큐먼트 리소스를 생성.
  2. 현재 리소스를 조회. 보통 컬렉션 리소스를 조회하게되면 하위의 도큐먼트들의 목록과 아주 간단한 정보들을 가져옴.
  3. 현재 리소스를 조회. 도큐먼트 리소스를 조회하게되면 해당 도큐먼트에 대한 자세한 정보들을 가져옴.
  4. 현재 리소스를 수정. soccer에 대한 정보를 수정하게 됨.
  5. 현재 리소스를 삭제. DELETE Method를 이용하여 현재 URI를 호출하면 sports 컬렉션에서 soccer 도큐먼트가 삭제.

추가로 주목해볼 만한 Method는 PATCH인데 기존에 REST에 익숙하신분들은 수정(update)을 위한 Method는 PUT가 익숙하지만 앞으로는 PUT대신 PATCH를 자주 써야할꺼 같음.

자세한 설명은 Edge Rails: PATCH is the new primary HTTP method for updates

요청 메소드

규칙

  • GET 메서드나 POST 메서드를 사용해 다른 요청 메서드 처리를 하면 안됨
    • 터널링tunneling은 메시지의 원래 의도를 감추거나 잘못 표현하는 것, 프로토콜의 투명성을 훼손하는 것 등의 HTTP 오용을 의미한다.

  • GET 메서드는 리소스의 상태표현을 얻는 데 사용
  • 응답헤더를 가져올 때 반드시 HEAD 메서드를 사용
    • GET 메서드와 동일하지만 바디가 존재하지 않음
  • POST 메서드는 컨트롤러를 실행하는 데 사용
    • HTTP 표준에서는 POST 메서드에 의미상 제한을 두지 않음
  • PUT메서드는 리소스를 삽입하거나 저장된 리소스를 갱신하는데 사용
  • PUT 메서드는 변경 가능한 리소스를 갱신하는데 사용
  • POST 메서드는 컬렉션에 새로운 리소스를 만드는 데 사용
  • DELETE 메서드는 그 부모의 리소스를 삭제하는데 사용
  • OPTIONS 메서드는 리소스의 사용가능한 인터낵션을 기술한 메타데이터를 가져오는 데 사용
    • OPTIONS 메서드를 사용하여 Allow 헤더에 포함된 리소스 메타데이터를 가져옴. (다음처럼 사용가능한 메서드를 가져옴 : Allow: GET, PUT, DELETE

응답상태코드

응답코드

코드이름의미
200OK

성공

201Created

새로운 리소스가 추가되었음을 알리기 위해 컬렉션이나 스토어에서 보내는 상태다. 어떤 경우에는 컨트롤러에서 보낼 수도 있다 

202Accepted

비동기 액션이 시작되었음을 알리기 위해 컨트롤러에서 보낸다. 

204No Content

바디 부분이 의도적으로 비어 있는 상태임을 나타낸다. 

301Moved Permanently

클라이언트가 요청한 리소스에 새로운 영구 URI가 할당되었음을 가리 

303See Other

컨트롤러에서 옵션인 결과를 돌려줄 때 보낸다. 

304Not Modified

조건 GET에 대해 대역폭을 보호하기 위해 보낸다. 

307Temporary Redirect

클라이언트가 요청한 리소스에 새로운 임시 URI가 할당되었음을 가리 킨다. 

400Bad Request

특별한 일이 없는 클라이언트의 에러 상태를 가리키는 오류 코드다. 

401Unauthorized

클라이언트에서 유효하지 않은 자격 증명을 보내거나 자격 증명을 보내지 않은 경우 보내는 오류 코드다. 

402Forbidden

보호된 리소스의 접근을 거부할 때 보내는 오류 코드다. 

404not Found

클라이언트가 URI에 대해 상호작용하고자 하였으나, REST API에서 URI 를 특정 리소스로 대응할 수 없을 때 보내는 오류 코드다. 

405Method Not Allowed

클라이언트에서 지원하지 않는 HTTP 메서드를 사용하여 상호작용하고자 할 때 보내는 상태 코드다. 

406Not Acceptable

클라이언트에서 지원하지 않는 미디어 타입 형식의 데이터를 요청할 때 보 내는 오류 코드다. 

409Conflict

클라이언트에서 리소스 상태를 위반하는 시도를 하고 있음을 나타내는 오 류 코드다. 

412Precondition Failed

선행 조건 중 하나가 만족되지 않았음을 클라이언트에게 알리는 오류 코 드다. 

415Unsupported Media Type

지원하지 않는 미디어 타입 형식으로 클라이언트에서 데이터를 제출하였음 을 알리는 오류 코드다. 

500Internal Server Error

API가 내부에서 문제가 생겼음을 클라이언트에게 알리는 오류 코드다. 

HTTP 헤더

규칙

  • Content-Type을 사용해야함.
    • (Content-Type 헤더는 요청이나 응답 메시지 바디에 있는 데이터 타입을 나타내기때문에 메시지 바디에 있는 바이트열 처리방법을 결정할 수 있음)
  • Content-Length를 사용해야함.
    • (Content-Length 헤더는 바이트 단위로 바디의 크기를 나타냄. 클라이언트는 이 값을 사용해 바이트의 크기가 올바르게 읽혔는지 알수 있고 HEAD요청으로 데이터의 크기를 확인할 수 있음)
  • Last-Modified는 응답에 사용.
    • (이 응답 헤더의 값은 타임스탬프로 리소스의 표현 상태값이 바뀐 마지막 시간을 나타냄. 클라이언트와 캐시 중간자는 이 헤더를 사용해 갱신여부를 결정)
  • ETag는 응답에 사용. 
    • (응답 엔티티에 포함된 표현 상태의 특정버전을 나타내는 일련의 문자열)
  • 스토어는 조건부 PUT요청을 지원해야함.
    • (PUT메서드를 사용해 스토어에 리소스를 추가하거나 갱신할 수 있어서 REST API는 클라이언트의 If-Unmodified-Since와 If-Match 요청 헤더를 통해 클라이언트의 의도를 파악할 수 있음)
  • Location은 새로 생성된 리소스의 URI를 나타내는데 사용.
    • (Location 응답 헤더의 값은 클라이언트의 관심 범위에 있는 리소스를 식별하는 URI)
  • Cache-Control, Expires, Date 응답헤더는 캐시 사용을 권장하는데 사용해야 함.
    • (캐시는 클라이언트의 대기시간을 줄일 수 있고 신뢰성 향상, api 서버의 부하감소 등 장점이 있음)
  • Cache-Control, Expires, Pragma 응답헤더는 캐시 사용을 중지하는데 사용해야 함.
  • 캐시 기능은 사용해야함.
    • (no-cache 지시자는 캐시 응답이 제공되는 것을 막음. REST API는 꼭 필요한 경우가 아니면 캐시를 사용하지 않는다. no-cache 보다 값이 작은 max-age를 사용하면 클라이언트는 갱신에 관계없이 짧은 시간 내 캐시에 저장된 복사본을 가져올 수 있음)
  • 만기 캐싱 헤더는 200응답에 사용.
    • (만기 캐싱 헤더는 성공적인 GET메서드와 HEAD 메서드의 요청에 대한 응답으로 설정)
  • 만기 캐싱 헤더는 3xx와 4xx 응답에 선택적으로 사용될 수 있음
    • (200 응답코드를 보낸 성공적인 응답에 추가로 3xx와 4xx 응답에 대한 캐싱 헤더를 추가하는 것을 네거티브캐싱 이라 하는데 리다이렉트 횟수와 REST API에 오류에 따른 부하를 감소시킴

메시지 바디 포맷

규칙

  • JSON 리소스 표현을 지원해야함 
    • (JSON은 가볍고 간단한 상호 연동을 지원.)
  • JSON은 문법에 잘 맞아야 함
    • (key-value 로 구성되며 순서와 무관. JSON은 숫자를 지원하기 때문에 문자열로 처리할 필요 없고 시간과 날짜는 지원하지 않음.)
    • JSON에 이름을 붙일 때 소문자,대문자를 섞어쓰고 특수 문자는 피해야 함.
  • XML과 다른 표현 형식은 선택적으로 지원할 수 있음

오류표현

규칙

  • 오류는 일관성 있게 표현

지원적 문제

  • 서버 구현 모델과 리소스 모델 간 자연스러운 분리
  • 일관된 크로스 포맷 하이퍼미디어 구조
  • 부분적이면서 동적으로 구성되는 응답 바디
  • 클라이언트 식별과 자격 권한의 통합


'' 카테고리의 다른 글

CORS  (1) 2017.03.17
세션 클러스터링  (0) 2016.11.09
HTML5  (0) 2016.07.28
웹서버와 WAS  (0) 2016.06.28
RestFul API  (0) 2016.06.20
세션, 쿠키, 캐시  (0) 2016.05.21

세션과 쿠키, 캐시의 정의에 대해 매번 햇갈려 정리합니다. 

1. Stateless 프로토콜

기본적인 HTTP통신의 원칙은 Stateless입니다. 클라이언트의 상태를 가지지 않는 서버 처리 방식을 말합니다. 다시 말해, 클라이언트와의 첫번째 통신에서 데이터를 받았다고 해도 두번째 통신에서 이 데이터를 계승하지 않는 처리 방식입니다. 하지만 실제 서비스에서는 이와 같은 기본 원칙보다 Stateful한 방식이 필요한 경우가 많습니다. 예를 들어, 상품을 선택하고, 구입을 하는 예를 생각해 봅니다. 상품 선택의 통신이 끝난후, 상품 구입의 리퀘스트가 서버로 보내지게 될 터인데, 여기서 만약 서버가 선택한 상품의 정보(상태)를 가지고 있지 않다면 유저는 상품을 구입 할 수가 없습니다. 따라서 웹 어플리케이션 개발자는 이런 HTTP의 stateless 특성 위에 stateful과 같은 시스템을 개발 할 필요가 생기게 됩니다. 

Stateful을 가능하게 만든 방법으로 쿠키와 세션이 있습니다. 두개의 큰 차이는 상태정보를 어디에 저장하는지 입니다. 쿠키는 브라우저에 의해 클라이언트 측에 저장되고 세션은 서버 측에 저장됩니다.

만약 세션을 사용하면 특정 클라이언트가 무엇을 요청하는지 저장되어 있어 요청에 대한 응답을 실행하지만 쿠키의 경우 서버는 특정 클라이언트가 무엇을 주문했는지 기억하지 않고 클라이언트가 저장되어 있는 이전 데이터를 불러와 반복적으로 서버에게 요청합니다.

쿠키

쿠키는 브라우저에 보존되고, 통신시에 HTTP 헤더에 저장되어지는 텍스트 파일입니다. 쿠키를 이용한 실제의 stateful 통신의 흐름은 다음과 같습니다.

  1. 최초 통신에서는 클라이언트가 서버의 쿠키를 가지고 있지 않은 상태에서 request한다.
  2. 서버는 request의 헤더에 쿠키가 포함되어 있지 않은것을 판단하고, 통신의 상태(유저ID, 패스워드, 조작상태, 방문횟수 등)을 저장한 쿠키를 response한다.
  3. 클라이언트의 브라우저가 받은 쿠키를 보존한다.
  4. 두 번째 연결에서 HTTP헤더에 쿠키를 싣어서 서버에 request한다.
  5. 서버는 받은 쿠키로부터 클라이언트를 판별한다.

쿠키에는 다음과 같은 제약조건이 존재합니다.

  • 클라이언트는 총 300개의 쿠키를 저장할 수 있음
  • 하나의 도메인 당 20개의 쿠키를 가질 수 있음
  • 하나의 쿠키는 4096byte까지 저장 가능

하나의 도메인에서 설정한 20개의 쿠키의 갯수가 20개가 넘으면 가장 적게 사용되는 쿠키부터 삭제됩니다.

이러한 쿠키는 텍스트 형식으로 저장되며 쿠키가 사라지는 시점은 쿠키를 저장할 때 설정할 수 있고 만약 설정하지 않으면 해당 브라우저 종료시 삭제됩니다.

또한 쿠키에는 단점이 존재하는데 사용자의 데이터가 컴퓨터에 저장된다는 보안적인 문제가 존재합니다. 또한 악성유저들은 이러한 정보를 악용하는 경우도 있습니다.


세션

세션은 클라이언트와 서버의 통신 상태를 가집니다. 세션을 이용한 다수의 HTTP통신을 하나의 묶음으로 “세션관리”라고 말합니다. 세션관리에서는 세션ID라는 것과 세션을 하나의 짝으로 취급하는데, 이때 세션ID만이 클라이언트에 보내집니다. 클라이언트에 세션ID를 전해주는 방법은 여러가지가 있으니 일반적으로 쿠키를 이용하는 경우가 많습니다. 클라이언트로부터 세션 ID를 받아 실제로 서버의 세션에 저장된 중요한 정보들과 관련을 짓기때문에 쿠키만을 이용한 방식보다 보안적인 측면에서 좋습니다.



다수의 서버를 이용하는 경우에는 로그인한 시점에서 사용이 끝날때까지 한가지 서버만을 이용하게 하던지, 혹은 서버에 저장되는 세션정보를 전부 다 동기화를 해야합니다. 

캐시

Cache란 웹페이지 Resource 파일들 (오디오, 비디오, 이미지 등)의 임시 저장소로 다음에 같은 웹페이지 (또는 웹사이트) 접속 시 페이지 로딩 속도를 개선해주는 역할을 합니다. 

'' 카테고리의 다른 글

CORS  (1) 2017.03.17
세션 클러스터링  (0) 2016.11.09
HTML5  (0) 2016.07.28
웹서버와 WAS  (0) 2016.06.28
RestFul API  (0) 2016.06.20
세션, 쿠키, 캐시  (0) 2016.05.21

모바일의 앱스토어 처럼 구글에도 웹스토어가 존재합니다. 이에 어떻게 크롬 확장프로그램을 개발할지와 이를 이용해 ajax를 호출하는 확장프로그램 개발을 설명하겠습니다.

개발

확장프로그램을 개발하기 위해서는 html과 자바스크립트를 사용할 수 있어야 합니다.

 https://developer.chrome.com/extensions 해당 url에서 익힐 수 있지만 여기서는 테스트 api에 ajax 호출을 하는 프로그램을 개발할 수 있도록 진행하겠습니다.

manifest.json

매니페스트에 정의된 것으로 크롬이 해당 확장프로그램을 인식하고 어떻게 동작할 지 확인합니다. 자세하게 확장 프로그램의 이름, 설명, 어떠한 파일이 먼저 실행될 지, 사용하는데에 필요한 퍼미션은 무엇인지 등을 기술합니다.

아래의 예는 사무실 문을 여는 확장프로그램의 manifest입니다.

{ "manifest_version": 2, "name": "테스트", "description": "테스트입니다.", "version": "1.0", "background": { "scripts": ["door.js"] }, "browser_action": { "default_icon": "open.png", "default_popup":"door.html" }, "permissions": [ "tabs", "contextMenus", "<all_urls>" ] } 

manifest_version : 해당 매니페스트의 버전을 표시합니다.

name : 확장 프로그램에서 확인할 수 있는 이름입니다. (chrome://extensions/ 에서 확인)

description : 확장 프로그램에서 해당 프로그램의 상세 설명입니다. (chrome://extensions/ 에서 확인)

version : 확장프로그램의 현재 버전을 나타냅니다.

background : 해당 프로그램이 실행될 때 백그라운드로 실행될 파일을 정의합니다.

browser_action : 해당 프로그램이 크롬에 등록될 시, 주소창 우측에 아이콘이 생깁니다. 이때 어느 아이콘으로 할지, 기본 아이콘과 해당 아이콘을 클릭 시, 어느 .html로 이동할지 기본값을 정합니다.

여기서 작성하는 이름은 실제 파일명과 동일해야 합니다.

permissions : 해당 프로그램에서 사용할 퍼미션들을 나열합니다. 위에서는 tabs와 contextMenus, <all_urls> 3개를 사용했습니다.

  • tabs: 클릭 시, 새로운 탭이 오픈되도록 하는 권한입니다.
  • contextMenus : 마우스 오른쪽을 눌렀을 때 동작하도록 하는 권한입니다.
  • <all_urls>: 모든 url에서 해당 프로그램을 사용할 수 있도록 하는 권한입니다.


위와 같이 굵은 글씨로 정리된 내용을 제외하고 크롬에서 제공하는 더 많은 API를 알고 싶거나 해당 API에 대해 더 자세히 알고 싶다면 https://developer.chrome.com/extensions/api_index 에서 확인할 수 있습니다.

js

위의 json파일에서 background로 door.js파일 호출하도록 만들었습니다. 

var req; function openURL(){ var msg = { body: { 필요한 부분 기재 }, header: { 필요한 부분 기재 } }; req = new XMLHttpRequest(); req.onreadystatechange = handleStateChange; req.open("POST",ip주소 및 url,false); req.setRequestHeader("content-Type","application/json;charset=utf-8"); req.send(JSON.stringify(msg)); } function handleStateChange(){ if(req.readyState == 4){ if(req.status == 200){ //alert("성공: "+req.responseText); }else{ //alert("실패: "+req.status); } } } //마우스 오른쪽을 눌렀을 때, 반응하는 부분 chrome.contextMenus.create({"title":"테스트입니다.", "contexts":["all"], "onclick":openURL}); //window.onload = test;


마우스 오른쪽을 클릭하면 해당 프로그램이 실행되면서 위에 정의한 chrome.contextMenus.create 해당부분이 실행됩니다. 

chrome.contextMenus.create
  • title : 오른쪽 클릭 시 메뉴에서 보이는 제목입니다.
  • contexts : 오른쪽 클릭에도 여러 상황이 있습니다. 가령 빈 페이지에서 오른쪽 클릭을 할 경우, 이미지에 오른쪽 클릭을 할 경우 등등 많은 상황이 있는데 이러한 상황들을 체크해주는 옵션입니다. 위에서는 all로 정의해서 어떠한 상황에서도 동작합니다. 
  • onclick : 메뉴에서 해당 프로그램을 클릭했을 시 호출할 함수

create에 대한 더 많은 함수 및 함수 정의는 https://developer.chrome.com/extensions/contextMenus#method-create 에서 확인할 수 있습니다.


위에서는 크롬에서 제공하는 API중 contextMenus의 create 함수에 대해서만 설명을 했지만 https://developer.chrome.com/extensions/samples#search 에서 사용할 퍼미션에 대해 검색하고 정보를 찾을 수 있습니다.

다른 블로그들을 확인하면 jquery를 사용해 동작한다고 나와있는데 직접 해본결과 jquery를 사용한 ajax호출이 되지 않은 것으로 확인했습니다.

html

매니페스트 파일에서 기본 html 파일을 아래의 door.html로 정의했습니다.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            BODY {width : 200px; min-height:30px;}
        </style>
    </head>
    <body>
        <p>마우스 오른쪽으로 써주세요.</p>
    </body>
</html>

크롬 확장프로그램을 설치 후 활성화를 시키면 주소창 오른쪽에 아이콘이 생기면서 클릭을 할 수 있습니다. 여기서는 해당 아이콘을 클릭하면 정의한 문구가 나오도록 설정했습니다.

등록하기

위에서 정의한 매니페스트 파일, html, js, 아이콘 파일을 door라는 하나의 폴더에 이동시킵니다.

다음 구글 확장프로그램으로 이동해 우측에 있는 개발자 모드의 체크박스를 활성화 시킵니다.


체크박스 활성화 시, 압축해제된 확장프로그램 로드... 버튼이 생기는데 해당버튼을 클릭한 후, door 폴더를 선택해 줍니다.

새로고침을 하면 활성화가 된 것을 확인할 수 있습니다.


'Chrome' 카테고리의 다른 글

크롬 확장프로그램 (Chrome Extension)  (0) 2016.05.21

bower는 트위터에서 만든 프론트앤드용 패키지 매니저 입니다. bower는 node.js로 만들어진 도구이므로 npm을 이용해서 설치하고 커맨드라인 명령어로 사용합니다. npm과 pypi와 마찬가지로 지금부터 private하게 구축하는 방법을 설명하겠습니다.

private-bower 설치


아래 명령어로 bower 이미지를 다운받습니다.

 $ docker pull tandrup/private-bower

빠른 시작

$  docker run -e ADDRESS=ip주소 -i -t -d -v /home/bower:/data -p 5678:5678 -p 6789:6789 -p 7891:7891 --name bower tandrup/private-bower


모든 데이터는 /home/bower에 저장되며 컨테이너 내의 /data 공유합니다.

5678 포트는 bower registry를 나타내고 6789는 git cache, 7891은 svn cache 포트를 나타냅니다.

private-bower에 패키지 업로드


url에 http://위에서 지정한 주소:5678로 들어가면 다음과 같은 화면을 볼 수 있습니다.


+를 눌러 url에서 패키지를 업로드할 수 있습니다.


private bower는 pypi와 다르게 서버에 직접 패키지를 관리하는 것이 아닌 저장소는 git에서 따로 관리하고 git 주소를 관리하는 툴입니다. (public bower도 동일)


여기서 private-bower 자체 문제가 있어 불안정 합니다.


package url은 http://나 git:// 또는 https://로 입력해야 다음과 같은 화면을 볼 수 있습니다.



POST를 사용해 등록을 할 수 있다고 나와 있지만 (https://github.com/Hacklone/private-bower/blob/master/README.md) POST로 url을 입력해도 url이 들어가지 않아 에러가 나며, 명령어로 실행하는 방법이 존재하지 않습니다.

'저장소 > BOWER' 카테고리의 다른 글

BOWER  (0) 2016.05.21

+ Random Posts