블로그 내 검색

2012. 4. 18.

자바스크립트를 사용하지 않은 CSS 이미지 갤러리

자바스크립트의 도움 없이, CSS의 의사 클래스(Pseudo-classes)를 사용해서 이미지 갤러리를 구현해보았습니다.
주로 사용한 것은 :target 과 :hover. 아래 #1 ~ #4 링크를 클릭해보세요~
Firefox나 Chrome 에서 잘 보입니다.

주의 : IE8 이하는 동작하지 않고, IE9는 트랜지션 효과가 제거되어 동작합니다.

사용한 CSS.
div#slide_container {
    position: relative;
    margin: 0 auto;
    width: 480px;
    height: 320px;
}

ul {
    list-style: none;
    margin: 0px;
    margin-top: 20px;
    padding: 0px;
}

ul li {    
    height: 0px;
    overflow: hidden;
    opacity: 0;    
}

ul li img {
    margin: 0 auto;
    height: 320px;    
    box-shadow: 2px 3px 3px #666;
}

ul li:target {
    -webkit-transition: all 800ms ease-in-out;
    -moz-transition: all 800ms ease-in-out;
    -o-transition: all 800ms ease-in-out;
    transition: all 800ms ease-in-out;    
    opacity: 1;
    height: 320px;
}

  • #1
  • #2
  • #3
  • #4
  • 링크를 클릭하세요!

2012. 4. 16.

Spring in Action 3th Edition

토비의 스프링 3.0을 2번 읽은 뒤에 뭔가 부족하다 싶어 회사 주문으로 구매한 책.

토비의 스프링을 두번 읽은 효과가 있는지 책은 금방 읽혔습니다.
책에서 설명하는 내용의 깊이는 고급기술보다는 스프링의 기본 기능에 대해서 죽 설명해나가는 방식이며, 저자가 가끔 던지는 농담조차도 번역이 잘 되어 있어서 번역 수준은 아주 훌륭합니다. (부족한 부분은 역주가 달려 있습니다)

스프링의 기본인 Ioc/DI 부터 프록시, 애스펙트, @MVC, 트랜잭션 추상화 외에도 JMS, JMX, 시큐리티, RMI 등등의 다소 넓은 범위까지 설명하고 있습니다.

만일 어느정도의 자바 기본 레벨이 갖추어져 있고, 토비의 스프링같이 두꺼운 책이 부담된다면 이 책을 추천할만 합니다. 경쾌(?)한 설명으로 스프링의 기본을 학습할 수 있습니다.

그런데 이 책의 샘플 코드 구현이 spitter라는 제목의 소셜네트워크 프로그램인데...
저자의 다소 더러운(?) 센스...

2012. 4. 13.

REST

데이터는 왕
프로그래밍은 결국 데이터를 어떻게 생성하고 변형하고 지지고 볶고 나타내고 보여줄까 하는 목적의 집합체입니다.

프로그래밍의 분야에 따라, 만들려는 아웃풋의 종류에 따라 데이터의 비중이 적거나 많거나 할 수 있겠지만, 데이터가 없는 프로그램은 있을 수 있을까요.
최근에는 빅데이터라는 신조어(?)가 나돌면서 데이터 처리에 대한 관심까지 높아지고 있죠.

이렇게 소중한 데이터를 서로 나누는 기술은 오래전부터 발전해왔습니다.
맨발로 뛰는 스니커(sneaker) 통신부터 맨땅 01010101의 로우레벨 소켓, 그리고 프토토콜을 덧씌운 TCP/IP에서 좀더 상위레벨인 RPC, SOAP, REST 등등 많지요.

여기서는 REST에 대해 알아볼까 합니다.


Representational Status Transfer.

  • 표현 (Representation)
    • 데이터, 즉 리소스의 표현에 구애받지 않음.
    • 표현 형식(format)은 어떠한 것이든 전부 허용함.
  • 상태 (Status)
    • 데이터의 표현 상태에 관심이 많음. 
    • 데이터를 어떻게 해보려는 액션보다 리소스 자체의 표현되는 상태에 대해 비중을 더 둠
  • 전달 (Transfer)
    • 서로 다른 장치간에, 전달하고 전달받는 데이터.

>> 표현 + 상태 + 전달
정리하면, 어떠한 형식이든 적합한 형태의 표현 형식으로 서버 - 클라이언트간의 리소스를 전달하는 것을 말합니다.


Resource And Verb
REST는 리소스를 나타내는 형식인  URI 와, 그 리소스에 대한 액션을 나타내는 동사로 나뉩니다. 동사는 보통 HTTP의 method를 나타냅니다.

URI + method를 사용한다면 현재 서비스중인 웹서비스들은 전부 REST?

라고 생각하면 안됩니다...

REST에서는 URI을 통해 리소스를 식별합니다.(보통 URI은 좌측에서 우측으로 읽어 갈수록 식별이 명확해집니다.) 그런데 URI에는 일련의 액션이 들어가지 않습니다. 이 말인 즉, 동사가 들어가지 않는다는 겁니다.
URI이 나타내는 리소스로 무엇을 할 것인가는 URL은 전혀 관심을 가지지 않지요.

그렇다면 리소스에 대한 조작은 어떻게 하느냐.
그것은 바로 동사를 나타낼 수 있는 method 와의 조합입니다.

  • URI === 리소스
  • METHOD === 액션

method 리스트를 보면, 우리에게 친숙한 GET, POST외에도 PUT, DELETE, OPTIONS, HEAD, TRACE 등이 있는데 이들의 특성을 정확하게 알아야 합니다.

대충 정리해보죠.

  • GET
    • 데이터를 조회합니다. 단순하죠.
  • POST
    • REST 리소스를 처리하는 리스닝 서버에 특정 작업을 데이터와 함께 전송하여 요청합니다. 메소드계에서 제일 반항적이고 네거티브한 녀석입니다.
  • PUT
    • 리소스에 데이터를 둡니다(?). GET과는 정확히 반대의 액션입니다. 보통 리소스의 조작등의 상황에서 사용된다고 볼 수 있습니다
  • DELETE
    • 리소스를 삭제합니다, 심플하군요.
  • OPTIONS
    • 서버 통신을 위해 사용할 수 있는 옵션을 요청합니다. 자세히는 잘 모르겠지만 쉘의 help 액션과 비슷한 용도일 듯 싶습니다.
  • HEAD
    • GET과 같지만 응답의 헤더만을 받습니다.
  • TRACE
    • 요청한 바디를 그대로 반환합니다. 응답 바디가 아니라 요청 바디입니다.

모든 method 에는 안전과 멱등 (Safety and idempotency)이라는 개념이 있습니다.
안전은 알겠지만 멱등이라는 말은 좀 어감이 웃기지 않습니까? (저만 그런가요...)

안전은 말 그대로 안전성입니다. method + URL 의 조합이 리소스의 상태를 변경하지 않으면 안전하다고 합니다.

멱등은 첫번째 요청 이후에 같은 리소스에 대해 반복되는 동사(method)가 어떠한 부작용도 일으키지 않는다면 멱등입니다. 그렇지 않다면 멱등하지 않습니다.

그렇다면 안전과 멱등으로 method를 분리해 봅시다.
위에서 GET, OPTIONS, HEAD, TRACE만이 안전 합니다. 리소스의 상태 변경을 하지 않습니다.

다음으로 멱등을 따져 봅시다.

GET은 멱등합니다. 자료를 조회할 뿐이죠.

POST는 멱등하지 않습니다.
POST는 위에도 썼듯이, method계의 반항아입니다. 안전하지 않음은 물론 멱등하지도 않아 다룰때 조심해야 합니다.

다들 웹 서핑하면서 뒤로가기 버튼을 애용하실 겁니다.
그런데 가끔 좋은 사이트(?) 의 경우 뒤로가기를 눌렀을 때 다음과 비슷한 안내가 뜰 때가 있습니다.



이런 경우 브라우저에서 자체 검열(?)한 method 경고입니다.
"방금 수행한 method는 멱등하지 않으니, 확인바람" 이라는 뜻이죠. 대부분 POST 수행을 다시한번 수행하려고 했을 때 일어납니다.

이런 장치가 없다면 인터넷에서 큰마음 먹고 화사한 봄 자켓을 결재한뒤 실수로 뒤로가기나 새로고침을 하는 순간 다시 결재정보가 서버에 전송되고, 두번 결재되는 불상사가 일어날 수 있겠지요.

POST는 안전하지도 멱등하지도 않기에 설계 시 주의가 필요합니다.
보통의 경우에는 POST를 받은 서버는 작업을 처리 후 새로운 주소로 클라이언트를 리다이렉트(HTTP 301...Location header 등으로) 시키는 처리를 하는 경우가 많습니다

PUT은 안전하진 않습니다. 리소스를 변경하기 때문이죠. 하지만 멱등합니다. 같은 리소스에 대해 PUT을 할 경우엔 당연히 몇번이 호출되도 같은 변경사항을 덮어 쓸 뿐이겠죠.

DELETE도 PUT과 마찬가지입니다. 안전하진 않지만 같은 리소스를 몇번이고 삭제해봤자 삭제는 한번뿐입니다.

OPTION, HEAD, TRACE는 일반적인 method가 아니고 메타성이며, 전부 안전하고 멱등합니다.


리소스의 표현과 RESTful한 표현은...
리소스는 변하지 않습니다.
하지만 표현이 리소스에 덧씌워진다면 형태만은 변경될 수 있습니다.

요청이 들어왔을 때 어떠한 형식으로 반환해야 하느냐는 보통 HTTP 요청 헤더의 Accept로 구별하는게 원칙인 듯 합니다. 하지만 헤더라는게 워낙 느슨한 정의에다가, 조작이 아주 쉬운 탓에 신뢰성이 없습니다.

보통은 여러 방법으로 어떠한 방법으로 리소스를 표현할지 정합니다.

ex) 요청의 반환 구현 예
  • Extension
    • .xml 이나 .html 등등.
  • Accept 헤더 ( + Content-type)
    • application/xml, text/plain 등등.
  • format parameter
    • URI의 쿼리스트링을 이용. datatype=xml 이런식.
(스프링을 공부하신 분이면 이게 ContentNegotiatingViewResolver 의 동작과 유사하다는 걸 아실 겁니다)

이제 RESTful 한 예제를 들어보죠.
RESTful 에 대한 반대의미로 RESTless 라는 표현도 쓰는걸 봤는데 재미있는 표현같습니다.

CASE A - RESTless
GET + http://www.example.com/blog/content/get_post.html?postNo=20

POST + http://www.example.com/blog/content/delete_post.html
Payload: postNo=20

POST + http://www.example.com/blog/content/new_post.html
Payload: post params...

CASE B - RESTful
GET + http://www.example.com/blog/content/post/20

DELETE+ http://www.example.com/blog/content/post/20

POST + http://www.example.com/blog/content/post/
Payload: post params...

둘의 차이가 느껴지시나요?

CASE A 에서는 URI에 동사, 즉 액션이 나타나 있습니다.
URI의 get_post~ 라든지, delete_post~...

이것은 저 URI이 액션을 포함하고 있어 극히 고정적이며 REST의 개념인 "URI === 리소스" 가 되지 않습니다. 게다가 표현 형식은 .html로 인한 HTML 표현만이 가능할 거라고 추측됩니다.
응답형은 전부 HTML이 될 거라고 추측됩니다.
이 경우 URL에 동사가 포함되어 있는데다 데이터의 표현도 한가지로 제한됩니다.
REST와는 좀 거리가 있네요.

CASE B 는 한 리소스 URI에 동사 method를 결합하여 다양한 작업을 수행할 수 있습니다.
리소스 표현또한 구체적으로 어떠한 행동이나 표현을 강제하고 있지 않습니다.
여기서 재미있는것은 POST의 요청인데, 말 그대로 POST할 위치를 현재로서는 알 수 없으므로 리소스의 구체적인 위치를 알수 없기에 아이디에 해당하는 숫자가 URL에는 포함되지 않습니다. 포스트 결과로 응답되는 데이터에 그 아이디가 반환되겠죠.

응답의 형식은 HTTP Status와 Content-type 헤더로 구분할 수 있겠군요.
예측을 하자면 GET은 HTTP Status로 200 (OK)과 컨텐트가, DELETE는 HTTP Status 로 204(No Content) 가 응답되며 코드의 내용처럼 컨텐트 반환은 없겠죠.
POST는 동작에 따라 301(Location - Redirect), 200(OK)나 201(Created), 그리고 응답으로 컨텐트가 있을 겁니다.
REST 하군요.


마치며
누군가 REST에 대해 이런 말을 했다더군요.

"단순하게 보이지만 결코 단순하지 않다."