8장 프로파일

8장 프로파일 현재까지 공부한 API 설계의 규칙 프로토콜 의미 체계의 문제 해결법 내 문제에 맞는 도메인 특화표준이 있다? ⇒ 사용 애플리케이션 특화 확장은 문서화 내 문제에 맞는 컬렉션 패턴이 있다? ⇒ 사용 애플리케이션 특화 용어를 정의하고 문서화 둘 다 해당되지 않으면? ⇒ 일반적인 하이퍼미디어 유형 사용 애플리케이션을 상태 전이로 나누고 문서화 애플리케이션 의미 체계의 문제 해결법 내 문제에 맞는 마이크로데이터 아이템이나 마이크로포맷이 있다? ⇒ 사용 문서화 없으면 애플리케이션 특화 용어를 정의 문서화 결국 문서화는 필요하다. ...

2024년 11월 27일 · 4 분 · 배준수

7장 순수 하이퍼미디어 설계

7장 순수 하이퍼미디어 설계 왜 HTML인가? HTML은 세상에서 가장 인기 있는 하이퍼미디어 유형이다. HTML의 기능 텍스트 문서의 중첩 구조를 표현할 수 있다. 택스트 콘텐트와 기타 태그를 표현할 수 있다. 하이퍼미디어 컨트롤 HTML은 다음과 같은 하이퍼미디어 컨트롤을 내장하고 있다. <link>, <a>, <img>, … 플러그인 애플리케이션 의미 체계 HTML은 사람이 이해할 수 있는 문서를 다룬다. HTML은 원래의 용도 외의 목적으로 사용하기가 매우 쉽다. HTML4는 세 가지 일반 속성을 더 가진다. rel : 연결되는 리소스와 지금 리소스 사이의 관계를 정의 id : 문서 내 한 요소를 식별하는 고윳값 class : 태그의 애플리케이션 의미 체계를 전달하는 용도(속하는 클래스를 정의) 마이크로포맷 hCard같은 마이크로포맷은 HTML에 추가적인 애플리케이션 의미 체계를 더하게 해준다. hMaze 마이크로포맷 새로운 hCard같은 마이크로포맷을 정의하는 것은 쉽다. 몇개의 클래스의 의미만 정의하면된다. 마이크로데이터 마이크로데이터는 HTML 5용으로 마이크로포맷을 다듬은 것이다. 다섯 개의 새로운 속성이 있다 itemprop : 마이크로포맷이 class 속성을 사용하던 방식으로 사용 itemscope : boolean. 태그에 마이크로데이터가 있는가를 표시 itemtype : 해당 마이크로데이터의 의미를 확인할 수 있는 곳 itemid itemref 마이크로포맷을 사용할땐 class=hCard 가 붙은 태그 내부가 모두 hcard 포맷임을 알 수 있다. 마이크로데이터는 그렇지 않다. itemscope 내부는 itemtype 이 가리키는 문서로 작성되어 있다고 표현된다. 예시 1 2 3 4 5 <div itemscope itemtype="https://www.naver.com/..."> <div itemprope="cell"> ... </div> </div> 마이크로포맷은 rel로 연결 관계를 정의할 수있지만 마이크로데이터는 그렇지 않다. itemtype 문서에는 나타날 것. 리소스 상태 변경하기 스위치를 누르면 리소스의 상태와 관계가 변경된다고 해보자 이 스위치를 조작하는 요청은 하이퍼미디어로 어떻게 구현될까? 폼에 애플리케이션 의미 체계 추가하기 rel 속성은 두 리소스 사이의 관계를 나타낸다. ‘리소스 상태를 변경하라’는 의미를 가진 rel 값을 만들 수 있을까? 리소스들이 나열되고 그 리소스를 요청하는 것은 GET 요청이다. 하지만 리소스 상태 변경은 GET 요청을 쓸 수 없다. POST를 써야한다. 이때 HTML이 정의한 하이퍼미디어 폼을 사용하면 된다. 대신, rel 속성은 지원하지 않는다. 이 switch 클래스도 hMaze 마이크로포맷에 추가할 수 있겠다. 1 2 3 <form action="/switches/4" method="post"> <input class="flip" type="submit" value="Flip it!"/> </form> 하이퍼미디어의 대체재는 미디어다 요즘 API 문서들에는 많은 메서드가 개별 API 호출로 노출되고, 상세하게 문서화되어 있다. 이는 다시 말해, 사람이 읽을 문서를 하이퍼미디어 대체재로 사용하고 있다는 것이다. 사람 대신, 이 정보를 받도록 의도된 대상(소프트웨어)에 맞춰 작성해야 한다. 스위치를 나타내는 두 버전을 살펴보자 1 2 3 4 스위치를 조작하려면 다음 주소로 POST 요청을 보낸다. https://api.example.com/swithches/{id}?action=flip {id}는 스위치 ID다. 스위치가 있는 셀에 있을 때에만 스위치를 조작할 수 있다. 1 2 3 4 5 6 7 <div class="swithch"> <span class="position">down</span> <form action="/swithches/4" method="post"> <inpuit class="flip" type="submit" /> </form> </span> </div> 애초에 하이퍼미디어 컨트롤을 사용할 수 있을 때만 제시되므로, 셀에 있을때에만 조작할 수 있다는 경고문구는 제공할 필요도 없다. HTML의 제약 기술적으로 HTML은 일반 하이퍼미디어 포맷이 아니라 도메인 특화 표준이다. 여기서 발생하는 한계들이 있다 PUT, DELETE는 HTML 하이퍼미디어 컨트롤로는 표현할 수 없다. HTML 4의 폼은 두 가지 종류의 엔티티 바디만 만들 수 있다. application/x-www-form-urlencoded multipart/form-data HTML 4는 JSON과 달리 숫자와 문자열을 구분하지 않는다. HTML 4는 날짜를 표시할 방법을 정의하지 않는다. HTML5가 문제를 해결해 줄까? 보완점 날짜 문제 ⇒ time 태그로 해결 숫자 문제 ⇒ 일반적으로 동작하지 않음 몇 가지 컨트롤을 더 정의하나, 여전히 유용하지 않음 input 태그 검증을 위한 방법 정의 일부는 보완되나, 하이퍼미디어 포맷으로서의 HTML을 급격히 변화시키지는 않는다. 하이퍼텍스트 애플리케이션 언어 웹 API에 특화되어 설계된, HTML의 기본 개념인 하이퍼링크만 가져온 HAL(Hypertext Application Language)가 있다. HAL은 두 가지 방식으로 제공된다. XML(application/hal+xml) JSON(application/hal+json) HTML과 HAL의 차이 HTML에는 여러가지 경우에 따라 <a>, <img>, <form> 을 사용한다. ...

2024년 11월 20일 · 4 분 · 배준수

6장 컬렉션패턴

6장 컬렉션 패턴 Collection+JSON은 여러 도메인에 걸쳐 반복해서 나타나는 패턴(컬렉션)을 다루기 위해 만들어졌다. 컬렉션은 무엇인가? 다른 리소스들의 링크를 걸어 나열하는 리소스다. 다른 리소스들을 한 그룹으로 묶는게 존재 목적이다. 아이템에 연결하는 컬렉션 아이템(item), 엔트리(entry), 멤버(member) : 컬렉션에 포함된 개별 리소르를 부르는 동의어 아이템이라해서 그 리소스 자체가 아니다. 친구 전화번호부의 콜렉션은 내가 아니다. Collection+JSON href: 컬렉션 자체의 영속적인 링크 items: 컬렉션 멤버를 가리키는 링크와 그것들의 부분 표현 links: 컬렉션에 관계된 다른 리소스를 연결한다. queries: 컬렉션 검색을 위한 하이퍼미디어 컨트롤 template: 컬렉션에 새 항목을 추가하기 위한 하이퍼미디어 컨트롤 아이템 표현하기 각 멤버는 JSON 객체로 표현된다. href 속성 : 해당 아이템을 독립 리소스로 나타내는 영속적인 링크 links:: 그 아이템에 연관된 다린 리소스의 하이퍼미디어 링크 data: 해당 아이템의 표현의 중요한 부분을 나타내는 기타 정보 아이템의 영속적인 링크 href 속성의 URL에 GET 요청을 보내면 서버는 한 아이템에 대한 Collection+JSON 표현을 보낸다. 아이템의 데이터 아이템의 data 슬롯에 JSON 객체 배열로 들어간다. name과 value 프로퍼티가 각각 단일 키-값 묶음을 나타낸다. 선택사항인 prompt는 사람이 이해할 수 있는 설명이다. 아이템의 링크 특정 아이템 하나를 참조하고 싶을 때 클라이언트가 사용할 특별할 URL이다. links라는 목록이 포함될 경우, 여기에 관련된 리소스를 연결하는 하이퍼미디어 링크 여러 개가 포함된다. 쓰기 템플릿 새 아이템을 컬렉션에 추가하려면 쓰기 템플릿에 적혀있는 형식으로, 컬렉션의 href로 POST 요청을 보내면 된다. 쓰기 템플릿은 개념적으로 HTML 폼과 동일하다. 동일한 입력을 하면 똑같은 요청을 보낸다는 의미다. 폼으로 보내면 application/x-www-form-urlencoded, 쓰기 템플릿으로 보내면 application/vnd,collection+json 일 뿐이다. 검색 템플릿 queries 슬롯에 저장된다. (일반) 컬렉션은 어떻게 동작하는가? GET 표현을 제공한다. 표현의 미디어 유형은 그 리소스로 무엇을 할 수 있는지 말해준다. application/vnd,collection+json : Collection+JSON 표준의 규칙 적용 application/atom+xml: AtomPub 규칙이 적용 applcation/json: 맘대로 하겠다. POST로 추가하기(POST-to-Append) 새 리소스를 생성 PUT과 PATCH 몇 개의 요소를 한 번에 수정하거나 개별 요소를 제거하는 데 사용 DELETE 무언가를 삭제하기 위해 존재 페이지 나눔 링크가 많을 경우 나눠서 제공한다. <link rel=”next” href=”/collection/4iz6”/> : 다음 next, previous, first, last, prev 등이 제공될 수 있다. 검색 폼 AtomPub(Atom Publishing Protocol) Collection+JSON의 item은 어떤것이든 나타날 수 있다. 반면 AtomPub은 뉴스 기사를 게시할 목적으로 설계되었다. 또한 뉴스 기사에 필요한 필드들이 존재한다. XML을 처리하는 방식때문에 도태됨 사람들은 자신이 필요로 하는 표준이 아니라면 해당 표준을 배우려 하지 않는다. 의미 체계의 문제: 잘 대응하고 있는가? 우리는 ‘컴퓨터가 어떤 링크를 클릭하도록 결정하게 하려면 어떻게 프로그래밍을 해야 할까?’에 대해 생각 중 컬렉션 패턴은 두 가지 다른 종류의 리소스를 인식한다 ⇒ 아이템 유형 리소스 : GET, PUT, DELETE에 응답 컬렉션 유형 리소스 : GET, POST에 응답 컬렉션과 아이템의 차이점 : 의미체계에서 나온다. 컬렉션 패턴에서 어떤 행동을 하기 위해 무엇이 필요한지는 알 수 있다. 하지만 필요한 필드의 의미를 알기 위해선 여전히 설명이 필요하다.

2024년 10월 23일 · 2 분 · 배준수

5장 도메인 특화 설계

5장 도메인 특화 설계 요청을 보내고 클라이언트가 되돌려 받는 하이퍼미디어는 미로의 길을 알려줄만큼 다음 선택지에 대한 정보를 제공해야 한다. 클라이언트는 그들의 원하는 일을 한다 미로 지도라는 리소스의 표현에서 출구를 찾던, 지도를 작성하던, 요청 몇개 보내고 지도를 완성했다고 거짓말을 하던 상관이 없다. 클라이언트와 서버는 서로 주고받는 표현의 이해를 공유하고 있어야 하지만 풀어야 하는 문제가 무엇인지 함께 인식할 필요는 없다. 표준 확장하기 미로를 3차원으로 확장한다면 어떤 클라이언트는 작동에 이상없으나 어떤 클라이언트는 문제가 생긴다. ...

2024년 9월 25일 · 2 분 · 배준수

4장 하이퍼미디어

4장 하이퍼미디어 클라이언트는 어떤 요청을 해야 할지 어떻게 아는 것일까? ⇒ 하이퍼미디어 하이퍼미디어는 서버가 클라이언트에게 나중에 어떤 HTTP 요청을 보낼 수 있을지 설명하는 방식이다. 하이퍼미디어 유형으로서의 HTML <a> 태그는 HTTP GET 요청을 만들 수 있음을 브라우저에 알려주는 신호다. 더 정확히는, 특정 URL이 방문할 수 있는 리소스를 부른다는 웹 서버의 약속 사용자가 활성화할 때만 요청(클릭)이 진행된다. <img> 태그도 요청할 수 있는 HTTP GET 요청을 설명하긴 하지만, 문서 사이를 이동한다는 뜻은 담겨 있지 않다. ...

2024년 9월 18일 · 3 분 · 배준수

3장 리소스와 표현

3장 리소스와 표현 REST는 설계 제약 조건 모음이다. 무엇이든 리소스가 될 수 있다 사용자가 어떤 작업을 취하고 싶다면 그것을 리소스로 만들어야 한다. 리소스에는 딱 하나의 제약만 있다. 모든 리소스는 URL을 가져야 한다. 다시말해, 무언가에 URL을 부여하면 그건 리소스가 된다. 리소스의 기본 형태는 비트 스트림이다. 클라이언트는 URL과 리소스의 표현만 볼 뿐이다. 표현은 리소스의 상태를 설명한다 표현 : 클라이언트가 리소스에 GET 요청을 보내면 그 리소스를 유용한 방식으로 나타내는 문서를 제공해야 한다. “기계가” 읽을 수 있는 설명으로 나타낸 것 표현은 양방향으로 전송된다. 클라이언트도 POST 요청에서 리소스의 표현을 보낸다. 새 리소스가 어떻게 보여야 하는지에 대한 클라이언트의 생각이 나타난다. 서버는 그 표현을 추가하거나 변경하거나 일부 무시할 수 있다. 데이터베이스 필드에 항상 created_at 과 updated_at 을 남김 표현의 상태 전송 서버는 리소스의 상태를 나타내는 표현을 보낸다. 클라이언트는 그 리소스가 가졌을면 좋을 상태를 설명하는 표현을 보낸다. 많은 표현이 있는 리소스 하나의 리소스에 여러 표현이 있을 수 있다. 다양한 언어, 파일 형식 등 클라이언트가 원하는 표현을 지정하는 법 HTTP 헤더의 값 각 표현마다 별개의 URL 부여 HTTP의 프로토콜 의미 체계 클라이언트가 리소스에 원하는 행동에 대한 규칙이 있다. 미리 정의된 프로토콜을 따라 메시지를 보낸다. 웹 API에선 이 프로토콜이 HTTP다. GET: 리소스의 표현을 얻음 DELETE: 리소스를 제거 POST: 주어진 표현에 기반을 두고 이 리소스 아래 새 리소스를 생성 PUT: 이 리소스의 현재 상태를 주어진 표현으로 대치(전체) PATCH: 이 리소스의 일부 상태를 주어진 표현으로 변경(일부) HEAD: 이 리소스의 표현과 함께 주어질 헤더를 받음(표현은 X) OPTIONS: 이 리소스가 어떤 HTTP 메서드에 응답하는지 알아냄 LINK: 다른 리소스를 이 리소스에 연결 UNLINK: 다른 리소스와 이 리소스의 연결 관계를 제거 모든 요청은 프로토콜 의미 체계가 동일하지만, 애플리케이션 의미 체계는 다르다. GET 정보를 요청할 뿐이라 안전한 메서드여야 한다. 리소스 상태를 바꿀 것을 예상해서는 안된다. DELETE 삭제하는 메서드 멱등성(idempotence) DELETE 요청은 두 번 이상 보내도 한번 보낸것과 같은 결과가 나와야 한다. 지운걸 또 지우려는 요청을 보내도 처음 지웠을 떄와 동일하기 때문이다. 수학 0을 곱하는 것과 같은 이치 GET도 마찬가지다. 리소스가 변하지 않으므로 PUT도 마찬가지. 같은걸 계속 덮어써도 결과는 동일하므로 POST로 추가하기 새로운 리소스를 생성 PUT 덮어쓰기 PATCH 일부만 수정할 경우 멱등성이 없다. 예를 들어, 특정 값을 1 증가시키는 요청을 보내면 멱등성이 없다. PUT은 리소스 전체상태의 교체기 때문에 이러한 요청이 없다. 특히 PUT은 전체상태를 모르는 상태에서 이렇게 만들기 위해 쓰기도 한다. 반면 PATCH는 현재 상태를 알고 이를 일부 변화시키기 위한 요청 아직 HTTP 명세에 정의되지 않았다. LINK와 UNLINK 리소스 간 하이퍼미디어 링크를 관리 멱등하지만, PATCH와 마찬가지로 명세에 정의되지 않아 안전하지 않음 HEAD GET을 헤더에만 적용하는 느낌이라 안전함 GET 대신 쓰더라도 시간이 줄어들진 않지만, 대역폭 사용량은 줄어든다. OPTIONS 응답 헤더에는 HTTP Allow가 담겨, 해당 리소스가 지원하는 HTTP 메서드를 나열한다. 잘 설계된 API는 이 요청이 없어도 응답에 제공되는 하이퍼미디어 문서로 알게끔 해준다. 오버로드한 POST 사실 온갖 종류의 변화에 다 쓰이는게 POST다. ...

2024년 9월 11일 · 3 분 · 배준수

1장 웹 서핑하기 & 2장 간단한 API

1장 웹에서의 원칙 : 일반 사용자들이나, 자동화 소프트웨어 에이전트나 동일하게 작동한다. URL : 데이터 접근 경로 ⇒ 각 URL은 하나의 리소스를 식별한다. 브라우저가 리소스에 HTTP 요청을 보내면 서버는 응답으로 리소스의 표현(representation)을 반환한다. 주소 지정 가능성(addressability) 하나의 URL은 단 하나의 리소스만 식별한다. 플래시 인터페이스가 이를 어긴 대표적인 예시 이 원칙은 모든 리소스는 각각 자신의 URL을 가져야 한다는 말 짧은 세션 HTTP 세션은 하나의 요청 동안 유지된다. 요청이 발생하지 않으면 서버는 클라이언트의 존재를 모른다 ⇒ 무상태(statelessness) 자기 서술형 메시지 요청에서 받은 리소스의 표현에는 보통 다음에 해야할 것도 포함되어 있다. ...

2024년 9월 4일 · 4 분 · 배준수

파이썬 알고리즘 : 후보키

2024년 5월 24일 알고리즘 문제풀이 문제 후보키 난이도 Lv.2 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 from itertools import combinations # 최소성을 만족하는지 확인하는 함수 # 검증하는 조합 target의 부분집합이 이미 찾은 조합 answer_array에 포함되어 있는지 확인 # 포함되어 있으면 target은 최소성을 만족하지 않음 def validate(answer_array,target): for i in answer_array: if set(i).issubset(target): return False return True def solution(relation): answer = [] n = len(relation) m = len(relation[0]) arr = [ i for i in range(m)] for i in range(m): # 모든 속성 조합을 구함. idx = list(combinations(arr,i+1)) for q in idx: # 유일성을 만족하는지 확인 # 속성의 값을 이은 문자열을 set에 넣어 중복을 제거 # 중복이 없다면 유일성을 만족 check = set() for j in range(n): tmp = "" for k in q: tmp += relation[j][k] check.add(tmp) # set의 길이가 n과 같다면 중복이 없단 의미로 유일성을 만족 if len(check) == n: # 최소성을 만족하는지 확인 if validate(answer,q): answer.append(q) return len(answer)

2024년 5월 24일 · 1 분 · 배준수

파이썬 알고리즘 : Container With Most Water

2024년 5월 23일 알고리즘 문제풀이 문제 Container With Most Water 난이도 medium 코드 1차시도 시간초과(50/62) 모두 탐색했는데 시간초과가 떴다. 1 2 3 4 5 6 7 8 9 10 11 12 class Solution: def check(self,a,b,height): val = min(height[a], height[b]) return abs(b-a)*val def maxArea(self, height: List[int]) -> int: n = len(height) ans = 0 for a in range(n-1): for b in range(a+1,n): ans = max(ans, self.check(a,b,height)) return ans 2차시도 메모리초과(49/62) 인덱스 중 2개를 골라 처리하려 했는데 2개의 숫자 조합을 만들기 위한 배열이 메모리초과가 떴다. 아무래도 접근 방법 자체가 틀린것같다. ...

2024년 5월 23일 · 2 분 · 배준수

파이썬 알고리즘 : 오픈채팅방

2024년 5월 21일 알고리즘 문제풀이 문제 오픈채팅방 난이도 Lv.2 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 def solution(record): n = len(record) answer = [] # 들어오거나 나가는 행동을 저장할 배열 arr = dict() # 각 아이디의 최종 닉네임을 저장하기 위한 배열 name = dict() # 데이터를 가공하기 위한 반복문 for i in range(n): # 데이터 분리 data = list(record[i].split(" ")) tmp = dict() # 들어오고 나가는 행동이면 저장 if data[0] != "Change": tmp["message"] = data[0] tmp["id"] = data[1] arr[i] = tmp # 들어올 때 닉네임을 바꾸는 경우 추적 if data[0] == 'Enter': name[data[1]] = data[2] # 닉네임을 바꾸는 행동일땐 저장하지 않고 이름만 갱신 else: name[data[1]] = data[2] # 출력하기 위한 반복문 for i in range(n): # i번째일때 바꾸는 행동이였으면 arr에 해당 키 값은 존재하지 않음 if i not in arr: continue # 각 아이디의 최종 닉네임으로 출력 if arr[i]["message"] == "Enter": c = name[arr[i]["id"]] + "님이 들어왔습니다." elif arr[i]["message"] == "Leave": c = name[arr[i]["id"]] + "님이 나갔습니다." answer.append(c) return answer

2024년 5월 21일 · 1 분 · 배준수