개요

Micropub 프로토콜은 타사 클라이언트를 사용하여 본인의 도메인에 게시물을 생성, 수정, 삭제하는 데 사용됩니다. 웹 앱 및 네이티브 앱(예: 아이폰, 안드로이드)은 Micropub을 이용하여 본인 웹사이트에 기사, 짧은 노트, 댓글, 좋아요, 사진, 이벤트 또는 기타 종류의 게시물을 작성 및 수정할 수 있습니다.

저자 노트

이 절은 비규범적입니다.

이 명세는 W3CIndieWeb 커뮤니티로부터 기여되었습니다. Micropub의 더 많은 역사와 발전 과정은 IndieWeb 위키에서 확인하실 수 있습니다.

이 문서의 상태

이 절은 이 문서가 발행된 시점의 상태를 설명합니다. 다른 문서가 이 문서를 대체할 수 있습니다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 개정판은 W3C 기술 보고서 인덱스에서 확인하실 수 있습니다: https://www.w3.org/TR/.

이 문서는 Social Web 워킹 그룹에 의해 권고안으로 발행되었습니다. 본 문서에 대한 의견을 환영합니다. 의견은 public-socialweb@w3.org (구독, 아카이브)으로 보내주시기 바랍니다.

워킹 그룹의 구현 보고서를 참고하시기 바랍니다.

이 문서는 W3C 회원, 소프트웨어 개발자 및 기타 W3C 그룹과 이해관계자들의 검토를 거쳤으며, 디렉터에 의해 W3C 권고안으로 승인되었습니다. 본 문서는 안정적인 문서로, 참조 자료나 타 문서에서 인용 자료로 사용할 수 있습니다. W3C의 권고안 제공 역할은 명세에 주목하고 그 광범위한 배포를 촉진하는 것입니다. 이는 웹의 기능성과 상호운용성을 향상시킵니다.

이 문서는 2004년 2월 5일 W3C 특허 정책에 따라 운영되는 그룹에 의해 작성되었습니다. W3C는 해당 그룹의 산출물과 관련하여 공개된 공개 특허 공개 목록을 유지하고 있습니다. 해당 페이지에는 특허 공개 지침도 포함되어 있습니다. 특정 특허에 대해 실제로 알고 있고, 그 특허가 Essential Claim(s)를 포함한다고 믿는 경우, W3C 특허 정책 6장에 따라 정보를 공개해야 합니다.

이 문서는 2017년 3월 1일 W3C 프로세스 문서에 의해 관리됩니다.

1. 소개

이 절은 비규범적입니다.

Micropub은 웹 또는 네이티브 앱 클라이언트를 사용하여 서버에 게시물을 생성, 수정 및 삭제하는 명세입니다. Micropub은 주로 웹사이트에 "게시물"(블로그 글, 사진, 짧은 노트, 댓글 등과 같은 개별 콘텐츠)을 생성하는 데 중점을 두고 있지만, 다른 종류의 콘텐츠에도 사용할 수 있습니다. Micropub 명세는 콘텐츠를 생성하는 간단한 메커니즘과, 더욱 포괄적인 수정 및 삭제 메커니즘을 정의합니다.

1.1 Social Web 워킹 그룹

Micropub은 Social Web 워킹 그룹에서 제작하는 여러 관련 명세 중 하나입니다. 대체 방법이나 보완적인 프로토콜에 관심이 있는 구현자는 ActivityPub과 개요 문서 [social-web-protocols]도 참고하시기 바랍니다.

1.2 배경

Micropub 명세는 AtomPub 및 MetaWeblog API의 단순화된 버전으로 시작되었습니다. AtomPub이 Atom 피드에 항목을 생성하는 API라면, Micropub은 [Microformats2] 피드에 항목을 생성하는 API입니다.

AtomPub 및 MetaWeblog와는 다른 어휘를 사용할 뿐 아니라, Micropub은 여러 가지 방식에서 이 두 API를 단순화하고 개선합니다. Micropub은 인증에 기존의 안전하지 않은 아이디/비밀번호 방식 대신 OAuth 2.0 Bearer Token을 사용합니다. Micropub은 또한 전통적인 form 게시 방식과 JSON 게시 방식을 모두 지원하여, XMLRPC 방식보다 더 간단하고 안전합니다.

Micropub 어휘는 [Microformats2] 어휘에서 직접 파생되었습니다. Micropub은 HTTP POST로 제출할 수 있는 Microformats의 직렬화 형식으로 설계되었습니다. 새로운 Micropub 어휘를 개발하는 방법은 Microformats 표현을 살펴보고 역방향으로 적용하는 것입니다.

2. 적합성

이 문서에서 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", " SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 그리고 "OPTIONAL"은 [RFC2119]에 설명된 대로 해석해야 합니다.

2.1 적합성 클래스

이 절에서는 Micropub 클라이언트와 서버의 적합성 기준을 설명합니다. 모든 구현체는 MUST UTF-8 인코딩을 지원해야 합니다.

2.1.1 게시 클라이언트

게시물을 생성하는 적합한 Micropub 클라이언트:

  • MUST x-www-form-urlencoded 요청 전송을 지원해야 합니다
  • MUST [h-entry] 어휘를 지원해야 합니다
  • 클라이언트가 파일 첨부를 업로드하여 게시물을 생성하는 경우, MUST 미디어 엔드포인트가 있는지 확인하고, 있다면 파일은 Micropub 엔드포인트가 아닌 미디어 엔드포인트로 전송해야 합니다
  • SHOULD 서버 오류 메시지를 사용자에게 안내 메시지로 전달하는 등 친절하게 처리해야 합니다
  • SHOULD 엔드포인트 탐색을 지원해야 합니다

2.1.2 편집 클라이언트

게시물을 편집하는 적합한 Micropub 클라이언트:

  • MUST JSON 인코딩 요청 전송을 지원해야 합니다
  • MUST [h-entry] 어휘를 지원해야 합니다

2.1.3 서버

적합한 Micropub 서버:

  • MUST 인증의 헤더와 폼 파라미터 방식 모두를 지원해야 합니다
  • MUST [h-entry] 어휘를 사용하여 게시물 생성을 지원해야 합니다
  • MUST x-www-form-urlencoded 구문을 사용한 게시물 생성을 지원해야 합니다
  • SHOULD 게시물 수정삭제를 지원해야 합니다
  • 게시물 수정을 지원하는 서버는 MUST JSON 구문source content query를 지원해야 합니다
  • 미디어 엔드포인트를 지정하지 않은 서버는 MUST 게시물 생성을 위한 multipart/form-data 요청을 지원해야 합니다
  • 미디어 엔드포인트를 지정한 서버는 MUST configuration query를 지원해야 하며, 그 외 서버도 SHOULD configuration query를 지원해야 합니다

2.2 권고 후보 종료 기준

이 명세는 각 기능별로 둘 이상의 독립적이며 상호운용이 가능한 구현체가 있음으로써 CR을 종료했습니다. 각 기능은 서로 다른 제품에 의해 구현될 수 있으며, 모든 기능이 하나의 제품에 구현될 필요는 없습니다. 이를 위한 용어 정의는 아래와 같습니다:

2.2.1 클라이언트

Micropub 클라이언트는 게시물 생성을 비롯한 Micropub 요청을 전송하는 구현체입니다. 적합성 기준은 위의 적합성 클래스에 설명되어 있습니다.

2.2.2 서버

Micropub 서버는 Micropub 요청을 받아 게시물을 생성하고, 선택적으로 수정 및 삭제를 지원하는 구현체입니다. Micropub 서버는 미디어 업로드를 위한 미디어 엔드포인트를 별도로 지원할 수 있습니다. 적합성 기준은 위의 적합성 클래스에 설명되어 있습니다.

2.2.3 독립적

각 구현체는 서로 다른 당사자가 개발해야 하며, 자격을 갖춘 다른 구현체의 코드 재사용, 파생, 공유가 불가능합니다. 이 명세 구현과 무관한 코드 부분은 예외로 인정됩니다.

2.2.4 상호운용 가능

특정 기능에 대해, 서버가 클라이언트의 요청에 정의된 작업을 실행하고, 클라이언트가 해당 기능에 따라 서버의 예상 응답을 받으며, 서버 역시 클라이언트에 예상된 응답을 제공할 때, 클라이언트와 서버 구현은 상호운용이 가능한 것으로 간주합니다.

2.2.5 구현

구현(Implementation)은 다음 모든 기준을 충족하는 Micropub 클라이언트 또는 서버입니다:

  • 명세의 해당 적합성 클래스를 구현함
  • 일반 대중에게 다운로드 가능 소프트웨어 또는 호스팅 서비스 형태로 제공됨
  • 실험적이지 않으며(즉, 넓은 사용자층을 대상으로 하며 일상적으로 사용될 수 있음)
  • 웹사이트에서 주요하게 사용할 수 있을 만큼 적합함

2.2.6 기능

종료 기준 평가를 위해 다음 각 항목을 하나의 기능(Feature)로 간주합니다:

  • 사용자 프로필 URL을 기반으로 Micropub 엔드포인트를 찾기
  • HTTP Authorization 헤더에 액세스 토큰을 포함하여 요청 인증
  • x-www-form-urlencoded 요청의 본문에 액세스 토큰을 포함하여 요청 인증
  • 액세스 토큰에 하나 이상의 OAuth 2.0 scope 값이 있어야 게시물 생성이 가능함
  • x-www-form-urlencoded 구문 및 하나 이상의 속성으로 게시물 생성
  • JSON 구문과 하나 이상의 속성으로 게시물 생성
  • 동일한 속성명이 여러 값으로 x-www-form-urlencoded 구문으로 게시물 생성
  • 동일한 속성명이 여러 값으로 JSON 구문으로 게시물 생성
  • 중첩된 Microformats2 객체를 포함하는 JSON 구문으로 게시물 생성
  • 지정된 미디어 엔드포인트에 파일 업로드
  • Micropub 엔드포인트에 multipart/form-data로 요청을 전송해 파일이 포함된 게시물 생성
  • URL로 참조된 사진이 포함된 게시물 생성
  • 이미지 대체 텍스트가 포함된 URL 참조 사진으로 게시물 생성
  • 서버가 인식하지 못하는 속성이 포함된 요청으로 게시물 생성
  • 게시물 생성 시 HTTP 201 CreatedLocation 헤더 반환
  • 게시물 생성 시 HTTP 202 CreatedLocation 헤더 반환
  • 게시물 수정 및 속성 값 모두 교체
  • 게시물 수정 및 속성에 값 추가
  • 게시물 수정 및 속성에서 값 제거
  • 게시물 수정 및 속성 삭제
  • 게시물 수정 시 HTTP 200 OK 반환
  • 수정으로 게시물 URL이 변경될 경우 HTTP 201 Created 반환
  • 게시물 수정 시 HTTP 204 No Content 반환
  • x-www-form-urlencoded 구문으로 게시물 삭제
  • JSON 구문으로 게시물 삭제
  • x-www-form-urlencoded 구문으로 게시물 복원
  • JSON 구문으로 게시물 복원
  • 미디어 엔드포인트로 사진 업로드 후, 그 URL로 게시물 생성
  • q=config로 Micropub 엔드포인트를 쿼리하여, 미디어 엔드포인트와 syndication 대상 조회
  • q=syndicate-to로 Micropub 엔드포인트를 쿼리하여 syndication 대상 목록 조회
  • 특정 속성 없이 게시물의 원본 콘텐츠를 Micropub 엔드포인트에서 조회
  • 특정 속성만을 조회하며 게시물의 원본 콘텐츠를 Micropub 엔드포인트에서 조회

2.3 테스트 스위트 및 보고

구현 보고서를 https://micropub.net/implementation-reports/로 제출해 주세요. 자세한 안내는 위 URL에서 확인하실 수 있습니다. 구현 보고서 템플릿은 micropub.rocks에 제공되는 테스트를 참조합니다.

micropub.rocks는 직접 구현을 테스트할 수 있는 다양한 테스트 케이스를 제공합니다. 또한 Micropub 구현을 개발할 때 실제 오류 상황에 대한 자세한 피드백을 제공하는 유용한 도구입니다.

3. 구문

[microformats2-parsing]이 HTML 문서를 데이터 구조로 파싱하는 규칙이 비교적 단순한 것처럼, Micropub도 HTTP POST 및 GET 요청을 Micropub 명령으로 해석하기 위한 소규모 규칙 집합만 정의합니다. [microformats2-parsing]이 [h-entry]와 같은 객체의 새로운 속성을 도입할 때 파싱 규칙 변경을 요구하지 않는 것처럼, Micropub 역시 비디오 포스팅과 "좋아요"와 같은 다양한 게시물 유형에 해당하는 요청을 해석할 때 파싱 규칙 변경을 필요로 하지 않습니다.

Micropub 구문은 HTTP POST 및 GET 요청을 유용한 서버 동작으로 해석하는 방법을 설명합니다.

3.1 개요

게시물을 생성하는 모든 Micropub 요청은 UTF-8 인코딩된 x-www-form-urlencoded, multipart/form-data [HTML5] 또는 [JSON] 방식의 HTTP 요청으로 전송됩니다. 응답은 일반적으로 본문 없이 HTTP 헤더(예: 생성된 게시물의 URL)에 필요한 정보를 포함합니다. 응답 본문이 필요한 경우, SHOULD [JSON] 인코딩 객체로 반환해야 합니다.

3.1.1 Form-Encoded 및 Multipart 요청

x-www-form-urlencodedmultipart/form-data 요청의 경우, Micropub은 명시적으로 다중 값 속성을 표시하기 위한 URL 인코딩 확장 형태를 지원합니다. 즉, 하나의 속성에 여러 값을 보낼 경우 속성명에 대괄호 []를 붙여야 함을 의미합니다.

예를 들어 "category" 속성에 여러 값을 지정하려면, category[]=foo&category[]=bar와 같이 요청에 포함시킵니다.

서버 측에서는 이를 내부적으로 배열 형태로 변환하는 것이 기대됩니다. 예를 들면, 동등한 JSON 표현은 다음과 같습니다:

{
  "category": [
    "foo",
    "bar"
  ]
}

이 방식은 multipart 요청에서도 동일하게 동작하며, 각 값이 요청의 별도 "part"에 포함되고 "name"은 Content-Disposition: form-data; name="category[]"와 같이 표시됩니다.

x-www-form-urlencoded 확장의 범위는 배열을 표시하는 대괄호 추가에만 해당함을 참고하세요. foo[0] 또는 foo[bar] 같은 구문은 지원되지 않으므로, 더 복잡한 객체를 전송할 때는 JSON 구문을 이용해야 합니다.

3.2 예약된 속성

x-www-form-urlencoded 또는 multipart/form-data로 요청을 보낼 때 일부 POST 본문의 속성명은 예약되어 있습니다.

x-www-form-urlencoded 또는 multipart/form-data로 게시물을 생성할 때, "mp-"로 시작하지 않는 모든 속성은 생성되는 객체의 속성으로 간주합니다.

서버는 access_token 속성을 게시물에 저장하면 MUST NOT 안 됩니다.

mp-로 시작하는 속성은 클라이언트가 서버에 명령을 전달하는 메커니즘으로 예약되어 있습니다. 일반적으로 게시물의 속성은 사용자에게 표시되지만, 서버 명령은 사용자에게 보이지 않으므로 게시물의 속성으로 설정하는 것은 적절하지 않습니다. 새로운 mp- 명령을 실험하고자 하는 클라이언트와 서버는 indieweb.org/Micropub-extensions에서 논의하고 구현을 문서화하는 것이 권장됩니다.

JSON 구문으로 게시물을 생성할 때도 mp-로 시작하는 속성은 위와 같이 예약처리됩니다.

3.3 생성

게시물을 생성하려면, 생성할 게시물 유형과 속성을 포함하여 Micropub 엔드포인트로 HTTP POST 요청을 전송해야 합니다. 유형이 지정되지 않은 경우, 기본 유형 [h-entry]를 SHOULD 사용해야 합니다. 클라이언트와 서버는 MUST x-www-form-urlencoded 구문으로 게시물 생성을 지원해야 하며, JSON 구문 또한 MAY 지원할 수 있습니다.

h={Microformats object type}

예시: h=entry

"mp-"로 시작하지 않는 모든 파라미터는 생성되는 객체의 속성입니다.

예시: content=hello+world

여러 값이 가능한 속성(예: h-entry의 여러 카테고리)을 지정하려면, 속성명에 대괄호를 붙입니다.

예시: category[]=foo&category[]=bar

여러 값을 허용하는 속성은 대괄호 유무에 상관없이 단일 값 역시 MUST 허용해야 합니다. 아래는 form-encoded 요청의 전체 예시입니다.

Example 1
h=entry&content=hello+world&category[]=foo&category[]=bar

3.3.1 파일 업로드

파일을 업로드할 때, 클라이언트는 MUST 미디어 엔드포인트가 존재하는지 확인해야 합니다. 미디어 엔드포인트가 없다면, Micropub 엔드포인트가 직접 파일을 받는다고 가정하고 요청을 바로 보낼 수 있습니다. Micropub 엔드포인트에 파일을 업로드하려면 전체 요청을 multipart/form-data 형식으로 작성하고 파일을 일반 속성으로 전송합니다.

예를 들어, 캡션이 포함된 사진을 업로드하려면 h, content, photo 세 부분으로 구성된 요청을 보냅니다.

Example 2
multipart/form-data; boundary=553d9cee2030456a81931fb708ece92c

--553d9cee2030456a81931fb708ece92c
Content-Disposition: form-data; name="h"

entry
--553d9cee2030456a81931fb708ece92c
Content-Disposition: form-data; name="content"

Hello World!
--553d9cee2030456a81931fb708ece92c
Content-Disposition: form-data; name="photo"; filename="aaronpk.png"
Content-Type: image/png
Content-Transfer-Encoding: binary

... (binary data) ...
--553d9cee2030456a81931fb708ece92c--

파일 업로드를 허용하는 속성(예: photo 또는 video)에 대해, Micropub 엔드포인트는 MUST URL 값도 허용해야 하며, 직접 업로드된 파일처럼 취급해야 합니다. 엔드포인트는 MAY URL에서 파일을 다운로드하여 직접 업로드된 파일과 동일하게 저장할 수 있습니다. 예시:

Example 3
h=entry&content=hello+world&photo=https%3A%2F%2Fphotos.example.com%2F592829482876343254.jpg

이 방식은 미디어 엔드포인트나 기타 외부 이미지를 참조하여 파일 업로드를 지원하기 위함입니다. 자세한 정보는 미디어 엔드포인트 절을 참고하세요.

3.3.2 JSON 구문

속성의 더 복잡한 값을 지원하려면, 파싱된 Microformats 2 JSON 형식으로 엔트리를 전송하여 게시물을 생성할 수 있습니다.

이 경우 파일 업로드는 불가능하며, 위에 설명한 대로 URL로만 파일을 참조할 수 있습니다.

JSON 형식으로 게시물을 생성할 때, 모든 값은 MUST 배열로 지정해야 합니다. 값이 하나만 있어도 마찬가지이며, 이는 Microformats 2 JSON 형식과 동일합니다. 이 요청은 application/json 컨텐트 타입으로 전송합니다.

mp-로 시작하는 속성은 예약된 속성과 같이 예약되어 동작함에 유의하세요.

Example 4
POST /micropub HTTP/1.1
Host: aaronpk.example
Content-type: application/json

{
  "type": ["h-entry"],
  "properties": {
    "content": ["hello world"],
    "category": ["foo","bar"],
    "photo": ["https://photos.example.com/592829482876343254.jpg"]
  }
}

alt 텍스트가 포함된 사진 업로드

이미지에 alt 텍스트를 함께 업로드하려면 Microformats 2 구문을 사용하여 photo 속성에 이미지 URL과 alt 텍스트를 모두 지정할 수 있습니다. 단순한 URL 대신, 두 개의 속성(value: URL, alt: 텍스트)을 가지는 객체 형태로 값을 지정합니다. photo 값이 객체가 되어야 하므로, form-encoded나 multipart 요청에서는 사용할 수 없습니다. 대신 먼저 미디어 엔드포인트로 이미지를 업로드한 뒤, 아래와 같이 JSON 요청에서 URL을 참조해야 합니다.

Example 5
POST /micropub HTTP/1.1
Host: aaronpk.example
Content-type: application/json

{
  "type": ["h-entry"],
  "properties": {
    "content": ["hello world"],
    "category": ["foo","bar"],
    "photo": [
      {
        "value": "https://photos.example.com/globe.gif",
        "alt": "Spinning globe animation"
      }
    ]
  }
}

경고

여기 설명된 alt 텍스트 지정 방식은 Microformats 2에서 이미지 alt 텍스트 표현에 관한 제안(issue 2)이 반영될 것이라는 가정을 전제로 추가되었습니다. 만약 다른 결과로 해당 이슈가 정리된다면, Micropub 명세 역시 이에 따라 조정되어야 합니다.

3.3.3 중첩 Microformats 객체

가능하다면 중첩 Microformats 객체는 피하는 것이 좋으며, 객체를 URL로 참조하는 대안을 권장합니다. 가장 일반적인 예는 장소에 체크인하거나 사진에 인물 또는 장소를 태깅하는 등 venue용 h-card를 포함하는 경우입니다. 이런 경우, 필요하다면 먼저 객체를 생성한 뒤 URL로 참조하는 것이 더 낫습니다.

이 기법의 장점은, 생성된 각 객체가 자체 URL(각 데이터 조각마다 링크)을 갖도록 보장하며, 서버가 각 엔티티를 별도로 처리할 기회를 가집니다. 예를 들어 이미 존재하는 venue의 중복 생성을 피하고, 기존 venue 링크를 돌려주거나 새로운 데이터를 병합할 수 있습니다.

어떤 경우에는 중첩 객체에 URL이 없어도 괜찮습니다. 예를 들어 h-measure 값을 게시할 때, 그 자체로 URL이 필요하지 않으므로 중첩 Microformats 객체 구문을 사용해도 무방합니다.

중첩 객체는 요청이 JSON 형식으로 전송되어야 하며, form-encoding 구문으로는 일관되게 지원하지 않습니다.

아래 예시는 "weight" 측정 게시글을 새로운 h-entry로 생성하면서, h-measure 객체로 체중과 체지방 값을 기술합니다.

Example 6
{
  "type": ["h-entry"],
  "properties": {
    "summary": [
      "Weighed 70.64 kg"
    ],
    "weight": [
      {
        "type": ["h-measure"],
        "properties": {
          "num": ["70.64"],
          "unit": ["kg"]
        }
      }
    ],
    "bodyfat": [
      {
        "type": ["h-measure"],
        "properties": {
          "num": ["19.83"],
          "unit": ["%"]
        }
      }
    ]
  }
}

3.3.4 양방향 텍스트

Micropub 요청의 자연어 값에는 MAY 양방향 텍스트가 포함될 수 있습니다. Micropub 텍스트 값의 기본 방향은 좌→우 (left-to-right)입니다. 각 자연어 값의 기본 방향은 아래와 같이 변경할 수 MAY 있습니다.

자연어 값의 양방향 텍스트를 지정할 때, 텍스트의 첫 강한 방향 문자를 통해 기본 방향이 올바르게 감지될 수 없는 경우 ([BIDI]), 게시 클라이언트는 적절한 유니코드 양방향 제어문자를 값 앞에 삽입하거나 HTML 값의 경우 HTML 방향 마크업을 사용해 기본 방향을 명시적으로 지정하는 것이 SHOULD 합니다.

Micropub 서버가 양방향 텍스트가 포함된 자연어 값을 받을 경우, 각 자연어 값의 기본 방향을 파악하기 위해 평문 값은 첫 강한 방향 문자를 검색하고, HTML 값은 가능하다면 방향 마크업을 사용하거나 그렇지 않으면 마크업 태그 밖의 첫 강한 방향 문자를 탐색해야 SHOULD 합니다. 이러한 자연어 값을 표시할 때 서버는 [BIDI] 알고리즘에 따라 콘텐츠 표시 방식이 결정되어야 하며, 표시 전 문자열에 추가 제어문자 또는 마크업을 감쌀 수 MUST 있습니다.

3.3.5 인식되지 않는 속성

요청에 서버가 인식하지 못하는 속성이 포함된 경우, 서버는 MUST 이를 무시하고, 인식되는 값만으로 게시물을 생성해야 합니다.

이렇게 하면 클라이언트는 해당 내용을 지원하는 서버엔 풍부한 콘텐츠를, 그렇지 않은 경우엔 대체 콘텐츠만 전송할 수 있습니다.

예를 들어, 클라이언트가 weight 속성에 h-measure 값을, summary에는 평문 요약을 넣어 게시물을 생성하면, 이 속성을 지원하지 않는 서버는 weight를 무시하고 summary만 사용하게 됩니다.

3.3.6 응답

게시물이 생성되면, Micropub 엔드포인트는 MUST HTTP 201 Created 또는 HTTP 202 Accepted 상태 코드를 반환해야 하며, Location 헤더에 생성된 게시물의 URL을 포함해야 합니다. [RFC2616]

Example 7
HTTP/1.1 201 Created
Location: https://aaronpk.example/post/1000

엔드포인트가 요청을 즉시 처리하지 않고 비동기로 처리하기로 선택했다면, MUST HTTP 202 Accepted 상태 및 Location 헤더를 반환해야 하며, 오류 점검 및 유효성 검사는 HTTP 202 반환 전에 동기적으로 수행되어야 합니다. 클라이언트는 HTTP 202 응답을 받으면 지정된 URL에 객체가 곧 존재할 것이라 기대합니다.

타겟이 단축 URL을 제공하거나, 게시물이 다른 위치에 신디케이션된 경우, Micropub 엔드포인트는 HTTP Link 헤더와 적절한 "rel" 값을 사용하여 추가 URL을 MAY 반환할 수 있습니다. 예를 들면 게시물의 단축 URL은 다음과 같이 응답할 수 있습니다:

Link: <http://aaron.pk/xxxxx>; rel="shortlink"
또는 신디케이션된 게시물의 위치를 포함할 수 있습니다:
Link: <https://myfavoritesocialnetwork.example/aaronpk/xxxxxx>; rel="syndication"

오류 응답

오류 발생 시 응답 방식에 대한 내용은 아래 "오류 응답" 절을 참고하세요.

3.4 수정

Micropub 서버는 게시물의 개별 속성 추가/제거/수정을 포함하여, 이 절에 기술된 대로 게시물 수정 기능을 SHOULD 지원해야 합니다.

수정은 변경사항을 기술하는 JSON POST 방식으로 처리합니다.

엔트리를 수정하려면 "action": "update"를 전송하고, "url" 속성에 수정 대상 엔트리의 URL을 지정하세요. 요청에는 replace, add, delete 속성(또는 이들의 조합) 중 하나 이상이 반드시 MUST 포함되어야 합니다.

replace, add, delete 각각의 내부 속성값은 값이 하나여도 반드시 배열로 지정 MUST 합니다.

add/delete 연산을 동시에 요청할 수 있지만, 동일한 속성-값 조합에 적용하는 것은 추천하지 않습니다. 하나의 업데이트 요청에서 동일 속성-값 조합의 여러 연산을 보내면 서버 동작은 미정입니다.

3.4.1 교체

지정한 속성의 모든 값을 교체합니다. 속성이 없으면 새로 생성됩니다.

Example 8
{
  "action": "update",
  "url": "https://aaronpk.example/post/100",
  "replace": {
    "content": ["hello moon"]
  }
}

이렇게 하면 게시물의 내용이 새 텍스트로 완전히 교체되며, 다른 기존 속성에는 영향이 없습니다.

3.4.2 추가

해당 속성에 기존 값이 있다면 그대로 두고, 새 값만 추가됩니다. 속성이 없다면 새로 생성됩니다.

신디케이션 URL 추가

사용 사례: 게시물이 발행된 후, 신디케이션 링크를 추가하는 경우. 예를 들어, 먼저 게시 후 MyFavoriteSocialNetwork 또는 Wikimedia로 신디케이션할 때, 사이트 측에서는 신디케이션 URL을 원본 게시물에 추가할 수 있어야 합니다.

신디케이션 URL 추가는 업데이트 요청에 하나 이상의 URL을 포함해 전송하면 됩니다.

Example 9
{
  "action": "update",
  "url": "https://aaronpk.example/2014/06/01/9/indieweb",
  "add": {
    "syndication": ["http://web.archive.org/web/20040104110725/https://aaronpk.example/2014/06/01/9/indieweb"]
  }
}

태그 추가

사용 사례: 게시물 생성 후 태그를 추가하는 경우

category와 같이 여러 값을 가지는 속성의 경우, 추가할 값을 배열로 제공합니다.

Example 10
{
  "action": "update",
  "url": "https://aaronpk.example/2014/06/01/9/indieweb",
  "add": {
    "category": ["micropub","indieweb"]
  }
}

3.4.3 삭제

해당 속성이 존재하면 삭제합니다. 지정한 속성을 완전히 삭제하게 됩니다.

Example 11
{
  "action": "update",
  "url": "https://aaronpk.example/2014/06/01/9/indieweb",
  "delete": ["category"]
}

category와 같이 다중 값을 지닌 속성은, 각각의 값을 개별적으로 제거할 수 있습니다. 값이 남지 않으면 속성도 삭제됩니다.

Example 12
{
  "action": "update",
  "url": "https://aaronpk.example/2014/06/01/9/indieweb",
  "delete": {
    "category": ["indieweb"]
  }
}

3.4.4 응답

서버는 업데이트 성공 시 HTTP 200, 201 또는 204로 응답해야 MUST 합니다. 업데이트로 게시물의 URL이 변경된 경우, 서버는 HTTP 201로 새 URL을 Location 헤더에 포함하여 반환해야 MUST 하며, 그 외에는 응답 본문 유무에 따라 200 또는 204로 응답합니다. 응답 본문은 필수가 아니지만, MAY 어떤 변경이 있었는지 설명하는 JSON 객체를 포함할 수 있습니다.

3.5 삭제

Micropub 서버는 SHOULD 게시물 삭제를 지원해야 하며, MAY 게시물 복구(undelete)도 지원할 수 있습니다.

특정 URL의 전체 엔트리를 삭제하려면, action=delete와 삭제할 항목의 url 속성을 포함한 POST 요청을 보내면 됩니다.

Example 13
action=delete
&url=https://aaronpk.example/2014/06/01/9/indieweb

Example 14
{
  "action": "delete",
  "url": "https://aaronpk.example/2014/06/01/9/indieweb"
}

게시물을 복구(undelete)하려면, action에 "undelete"를 사용하세요.

Example 15
action=undelete
&url=https://aaronpk.example/2014/06/01/9/indieweb

Example 16
{
  "action": "undelete",
  "url": "https://aaronpk.example/2014/06/01/9/indieweb"
}

3.5.1 응답

서버는 삭제 또는 복구가 성공하면 HTTP 200, 201 또는 204로 응답해야 MUST 합니다. 복구 작업으로 게시물의 URL이 변경된 경우 반드시 HTTP 201로 새 URL을 Location 헤더에 포함하여 반환해야 하며, 그렇지 않으면 응답 본문 유무에 따라 200 또는 204로 응답해야 합니다. 응답 본문은 필수가 아니지만, MAY 변경된 내용을 설명하는 JSON 객체를 포함할 수 있습니다.

3.6 미디어 엔드포인트

Micropub 애플리케이션의 사용자 경험 향상과 JSON 구문으로 파일 업로드가 불가능한 한계를 극복하기 위해, Micropub 서버는 MAY "미디어 엔드포인트(Media Endpoint)"를 지원할 수 있습니다. 미디어 엔드포인트의 역할은 파일 업로드를 전담하고, 이후 Micropub 요청에서 사용할 수 있는 URL을 반환하는 것입니다.

Micropub 서버가 미디어 엔드포인트를 지원하는 경우, 클라이언트는 사용자가 게시물의 다른 부분을 작성하는 동안 사진이나 기타 미디어를 바로 업로드할 수 있습니다. 아래 다이어그램은 사진 업로드와 게시물 작성이 비동기로 일어나는 사용자 인터페이스 예시를 보여줍니다.

어플리케이션의 메인 화면, 업로드할 사진 선택, 사용자가 텍스트를 입력하는 동안 미디어 엔드포인트로 사진을 업로드, 게시물 내용과 사진 URL을 Micropub 엔드포인트로 전송하는 4단 다이어그램.

위의 사용자 흐름은 데스크톱 앱뿐만 아니라 모바일 앱에도 동일하게 적용됩니다. 일반적으로, 더 많은 작업을 비동기로 처리하면 사용자 경험이 대폭 향상되며, 사용자가 시스템 처리가 끝나기를 기다리지 않고 계속 작업할 수 있습니다.

3.6.1 탐색

Micropub 엔드포인트가 미디어 엔드포인트를 지원함을 알리기 위해, 서버는 MUST Micropub configuration query 응답에 media-endpoint라는 키에 미디어 엔드포인트의 전체 URL을 포함해야 합니다. 클라이언트는 미디어 엔드포인트가 반드시 Micropub 엔드포인트와 동일 도메인에 있음을 MUST NOT 가정해서는 안 됩니다.

Example 17
GET /micropub?q=config
Authorization: Bearer xxxxxxxxx

{
  "media-endpoint": "https://media.example.com/micropub"
}

3.6.2 인증

미디어 엔드포인트는 Micropub 엔드포인트와 동일한 액세스 토큰을 MUST 허용해야 합니다.

3.6.3 요청

클라이언트가 미디어 엔드포인트에 파일을 업로드하려면, file이라는 이름의 파트 하나를 포함하는 multipart/form-data 요청을 전송해야 합니다. 미디어 엔드포인트는 MAY 클라이언트가 전송하는 파일명을 무시할 수 있습니다.

Example 18
multipart/form-data; boundary=553d9cee2030456a81931fb708ece92c

--553d9cee2030456a81931fb708ece92c
Content-Disposition: form-data; name="file"; filename="sunset.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: binary

... (binary data) ...
--553d9cee2030456a81931fb708ece92c--

참고

이미지가 포함된 게시물을 생성할 때 접근성 관련 정보(예: 이미지의 alt 텍스트)를 추가하려면, alt 텍스트는 미디어 파일이 아니라 게시물에 연결됩니다. 이는 HTML img 태그에서 src 속성이 미디어 파일을 가리키고 alt 속성이 대체 텍스트인 방식과 유사합니다. 자세한 내용은 alt 텍스트가 포함된 사진 업로드 항목을 참고하세요.

3.6.4 응답

미디어 엔드포인트는 파일 업로드를 처리하여 원하는 백엔드에 저장하고, 파일에 대한 URL을 생성합니다. 이 URL은 UUID를 경로나 파일 이름에 사용하여 추측할 수 없는 값으로 하는 것이 SHOULD 합니다. 요청이 성공하면, 엔드포인트는 생성된 파일의 URL을 HTTP Location 헤더에 포함하고 HTTP 201 Created로 응답해야 MUST 하며, 응답 본문은 별도로 정의되지 않습니다.

Example 19
HTTP/1.1 201 Created
Location: https://media.example.com/file/ff176c461dd111e6b6ba3e1d05defe78.jpg

Micropub 클라이언트는 이 URL을 예를 들어 Micropub 요청의 "photo" 속성 값으로 사용할 수 있습니다.

미디어 엔드포인트는 특정 시간 내에 Micropub 요청에서 사용되지 않은 업로드 파일을 주기적으로 삭제할 수 MAY 있습니다.

3.6.4.1 미디어 엔드포인트 오류 응답

미디어 엔드포인트는 오류 응답에 기술된 것과 같은 오류 응답 방식을 SHOULD 따라야 합니다.

3.7 쿼리

Micropub 클라이언트는 사용자가 볼 수 있는 신디케이션 대상 목록 조회, 업데이트 인터페이스에 표시할 게시물 소스 가져오기 등 Micropub 엔드포인트 기능을 확인하기 위해 쿼리가 필요할 수 있습니다.

쿼리를 위해, Micropub 엔드포인트에 GET 요청을 사용하고 q 파라미터에 쿼리할 내용을 지정하세요.

참고

Micropub 엔드포인트 URL에 ?micropub=endpoint와 같은 쿼리스트링이 포함될 수 있으므로, 이 경우 Micropub 클라이언트는 MUST 기존 쿼리스트링을 대체하지 말고 q 파라미터를 추가로 붙여야 합니다.

3.7.1 구성

사용자가 Micropub 클라이언트에 처음 로그인하면, 클라이언트는 사용자의 엔드포인트에 대한 몇 가지 초기 정보를 확인하고자 합니다. 클라이언트는 q=config 쿼리를 사용하여 초기 구성 정보를 요청하는 것이 SHOULD 합니다.

서버는 구성 응답에 다음 정보를 SHOULD 포함해야 합니다.

  • 지원하는 신디케이션 엔드포인트 목록은 syndicate-to라는 속성에 포함(신디케이션 대상 구조 참고)
  • 지원하는 경우 media-endpoint라는 속성에 미디어 엔드포인트 포함

Example 20
GET /micropub?q=config
Authorization: Bearer xxxxxxxxx
Accept: application/json

HTTP/1.1 200 OK
Content-type: application/json

{
  "media-endpoint": "https://media.example.com/micropub",
  "syndicate-to": [
    {
      "uid": "https://myfavoritesocialnetwork.example/aaronpk",
      "name": "aaronpk on myfavoritesocialnetwork",
      "service": {
        "name": "My Favorite Social Network",
        "url": "https://myfavoritesocialnetwork.example/",
        "photo": "https://myfavoritesocialnetwork.example/img/icon.png"
      },
      "user": {
        "name": "aaronpk",
        "url": "https://myfavoritesocialnetwork.example/aaronpk",
        "photo": "https://myfavoritesocialnetwork.example/aaronpk/photo.jpg"
      }
    }
  ]
}

서버는 SHOULD 구성 쿼리를 지원하며, 서버와 관련된 모든 속성을 반환해야 합니다. 해당 속성이 없으면 응답은 빈 JSON 객체 {} 여야 합니다.

클라이언트는 예기치 않은 응답을 빈 응답과 마찬가지로 처리해야 SHOULD 하며, 이를 통해 해당 쿼리를 지원하지 않는 서버로부터 예기치 않은 응답(예: HTTP 400)도 대응할 수 있습니다.

3.7.2 원본 콘텐츠

Micropub 클라이언트는 엔드포인트에 특정 게시물의 일부 속성만 반환하도록 쿼리할 수 있습니다. 이렇게 하면 원하는 속성만 요청하여, 예를 들어 게시물에 태그 추가와 같은 인터페이스를 구현할 수 있습니다.

게시물 수정 기능을 지원하는 서버는 MUST source content 쿼리를 지원해야 합니다.

쿼리하려면, Micropub 엔드포인트에 GET 요청을 보내고 q 파라미터에 source를, url 파라미터에 게시물 URL을 지정합니다. properties 키에 원하는 속성명을 하나 이상 포함할 수 있으며, 둘 이상일 경우 [HTML5] URL 인코딩 방식에 따라 배열 대괄호 표기법을 사용합니다.

엔드포인트는 [microformats2-parsing] [JSON] 형식으로, 요청된 속성명이 키, 값은 배열로 이루어진 properties 객체로 응답해야 MUST 합니다. 속성이 지정되지 않으면, 모든 속성과 게시물 어휘를 나타내는 type 속성도 반드시 포함해야 합니다.

Example 21
GET /micropub?q=source&properties[]=published&properties[]=category&url=https://aaronpk.example/post/1000
Authorization: Bearer xxxxxxxxx
Accept: application/json

HTTP/1.1 200 OK
Content-type: application/json

{
  "properties": {
    "published": ["2016-02-21T12:50:53-08:00"],
    "category": [
      "foo", 
      "bar"
    ]
  }
}

Example 22
GET /micropub?q=source&url=https://aaronpk.example/post/1000
Authorization: Bearer xxxxxxxxx
Accept: application/json

HTTP/1.1 200 OK
Content-type: application/json

{
  "type": ["h-entry"],
  "properties": {
    "published": ["2016-02-21T12:50:53-08:00"],
    "content": ["Hello World"],
    "category": [
      "foo", 
      "bar"
    ]
  }
}

HTML 콘텐츠

게시물 원본이 HTML로 작성된 경우, 엔드포인트는 content 속성을 html 속성을 포함하는 객체로 반환해야 MUST 합니다. 그 외의 경우 값은 단순 문자열이어야 하며, 클라이언트는 이를 일반 텍스트로 처리합니다. 이는 [microformats2-parsing]의 속성값 처리와 동일합니다.

아래는 HTML로 작성된 게시물 내용을 쿼리하는 예시입니다.

Example 23
GET /micropub?q=source&properties=content&url=https://aaronpk.example/post/1000
Authorization: Bearer xxxxxxxxx
Accept: application/json

HTTP/1.1 200 OK
Content-type: application/json

{
  "properties": {
    "content": [
      {
        "html": "<b>Hello</b> <i>World</i>"
      }
    ]
  }
}

3.7.3 신디케이션 대상

지원하는 신디케이션 대상 목록을 반환하려면, q 파라미터에 syndicate-to를 지정하면 됩니다.

GET /micropub?q=syndicate-to

엔드포인트는 응답을 [JSON] 형식으로 해야 하며, syndicate-to라는 키 아래 지원 대상 설명 객체들을 배열로 반환해야 MUST 합니다. 대상이 없다면, syndicate-to 값은 빈 배열 []이어야 SHOULD 합니다.

최소한 각 신디케이션 대상에는 MUST uid와 사람이 읽을 수 있는 name 속성이 포함되어야 합니다. uid는 Micropub 엔드포인트별로 유일한 식별자이며, 사용자에게 표시되는 값은 아닙니다. name은 게시 인터페이스에서 사용자에게 표시되는 설명용 값이어야 합니다.

신디케이션 대상은 MAY 서비스 또는 대상 사용자 계정에 대한 세부 정보를 serviceuser 속성에 추가로 포함할 수 있습니다. 두 객체 모두 사용자에게 표시할 name 속성이 필수이며, MAY urlphoto도 가질 수 있습니다. 클라이언트는 이들 이름, 사진을 UI에서 활용할 수 있습니다.

Example 24
GET /micropub?q=syndicate-to
Authorization: Bearer xxxxxxxxx
Accept: application/json

HTTP/1.1 200 OK
Content-type: application/json

{
  "syndicate-to": [
    {
      "uid": "https://archive.org/",
      "name": "archive.org"
    },
    {
      "uid": "https://wikimedia.org/",
      "name": "WikiMedia"
    },
    {
      "uid": "https://myfavoritesocialnetwork.example/aaronpk",
      "name": "aaronpk on myfavoritesocialnetwork",
      "service": {
        "name": "My Favorite Social Network",
        "url": "https://myfavoritesocialnetwork.example/",
        "photo": "https://myfavoritesocialnetwork.example/img/icon.png"
      },
      "user": {
        "name": "aaronpk",
        "url": "https://myfavoritesocialnetwork.example/aaronpk",
        "photo": "https://myfavoritesocialnetwork.example/aaronpk/photo.jpg"
      }
    }
  ]
}

최소한 각 신디케이션 대상에는 MUST uidname 속성이 있어야 합니다. uid는 클라이언트에 불투명하며, Micropub 요청에서 신디케이션 대상을 지정할 때 이 값을 사용합니다. name은 사용자가 볼 수 있도록 표시해야 하며, 예를 들면 같은 서비스에 대상이 둘 이상일 때 혼동이 없도록 반드시 구별되어야 합니다.

Micropub 서버는 MAY 신디케이션 서비스와 사용자 계정에 관한 추가 정보도 포함할 수 있으며, 추가 속성 serviceusername(사람이 읽을 수 있는 이름), urlphoto(URL 형태) 속성을 모두 가질 수 있습니다.

클라이언트는 서비스/사용자 속성을 활용하여 신디케이션 UI에 사진이나 이름을 표시할 수 있습니다.

신디케이션 기능 지원 서버는 syndicate-to 쿼리도 SHOULD 지원해야 합니다.

3.7.4 쿼리 확장

쿼리 기능을 확장하려는 클라이언트와 서버는 indieweb.org/Micropub-extensions에서 아이디어 토론 및 구현 예시를 문서화하는 것이 권장됩니다.

3.8 오류 응답

요청에 오류가 있을 경우, 엔드포인트는 반드시( MUST) 적절한 HTTP 상태 코드(일반적으로 400, 401 또는 403)를 반환해야 하며, MAY 오류 설명을 함께 포함할 수 있습니다. 오류 본문이 있는 경우, 응답 본문은 반드시( MUST) [JSON] 객체로 인코딩되어야 하며, error라는 이름의 속성이 최소 한 개 있어야 합니다. 아래 오류 코드가 정의되어 있습니다:

클라이언트는 알 수 없는 오류 문자열도 일반적인 오류로 처리해야 하며(SHOULD), 응답 본문에는 error_description 속성이 포함되어 오류 설명(사람이 읽을 수 있는 메시지, 주로 개발자 참고용)도 함께 반환할 수 있습니다(MAY). 이는 최종 사용자에게 보여지기 위한 것이 아닙니다.

오류 응답 반환 방식에 대한 더 자세한 내용은 OAuth 2 Bearer Token [RFC6750] 명세를 참고하세요.

Example 25
GET /micropub?q=source&url=https://aaronpk.example/post/404
Authorization: Bearer xxxxxxxx

HTTP/1.1 400 Bad Request
Content-type: application/json

{
  "error": "invalid_request",
  "error_description": "The post with the requested URL was not found"
}

4. 어휘

Micropub 요청에서 사용되는 어휘는 SHOULD [Microformats2]에서 정의된 어휘를 사용하는 것이 권장됩니다. Microformats2 어휘가 사용되는 경우, 클라이언트와 서버는 MUST 적어도 [h-entry] 어휘를 지원해야 합니다. 널리 사용되는 다른 어휘로는 [h-event]와 [h-card]가 포함됩니다. 객체를 생성할 때, 해당 객체의 어휘는 h 파라미터(또는 JSON 구문에서는 type)에 명시합니다. 타입이 제공되지 않으면 서버는 기본값 entrySHOULD 가정해야 합니다.

4.1 객체 생성 예시

이 절은 비규범적입니다.

생성할 객체를 지정하려면, h라는 속성(이 속성명은 Microformats 객체의 속성명으로는 사용되지 않음)에 Microformats 객체의 이름을 사용합니다. 예시:

다음 속성들은 [h-entry] 생성을 위한 요청에 포함될 수 있습니다:

4.1.1 새 노트

태그가 포함된 새 노트를 myfavoritesocialnetwork에 신디케이션하며 게시:

  • content
  • category
  • published (선택 사항, 없으면 기본값은 "now"입니다. 오프라인 작성 및 후속 동기화에 유용합니다.)
  • mp-syndicate-to

Example 26
POST /micropub HTTP/1.1
Host: aaronpk.example
Authorization: Bearer XXXXXXXXXXX
Content-type: application/x-www-form-urlencoded; charset=utf-8

h=entry
&content=My+favorite+of+the+%23quantifiedself+trackers%2C+finally+released+their+official+API
&category[]=quantifiedself&category[]=api
&mp-syndicate-to=https://myfavoritesocialnetwork.example/aaronpk

최소 예시

Example 27
POST /micropub HTTP/1.1
Host: aaronpk.example
Content-type: application/x-www-form-urlencoded; charset=utf-8
Authorization: Bearer XXXXXXX

h=entry
&content=Hello+World

Example 28
curl https://aaronpk.example/micropub -d h=entry -d "content=Hello World" -H "Authorization: Bearer XXXXXXX"

4.1.2 새 답글

태그가 포함된 새 노트를 myfavoritesocialnetwork에 신디케이션하며 게시:

  • content
  • in-reply-to
  • published
  • mp-syndicate-to

Example 29
POST /micropub HTTP/1.1
Host: aaronpk.example
Authorization: Bearer XXXXXXXXXXX
Content-type: application/x-www-form-urlencoded; charset=utf-8

h=entry
&content=%40BarnabyWalters+My+favorite+for+that+use+case+is+Redis.
&in-reply-to=https://waterpigs.example/notes/4S0LMw/
&mp-syndicate-to=https://myfavoritesocialnetwork.example/aaronpk

4.1.3 HTML을 포함하는 새 기사

HTML 콘텐츠가 포함된 새 기사를 게시합니다. 이 경우 content 속성은 html 키를 포함하는 객체로 전송됩니다. 이것은 Microformats 2 구문에서 파싱된 값이 HTML임을 나타내는 방법과 일치합니다. content가 객체이기 때문에, 이 요청은 JSON 포맷으로 전송해야 합니다.

Example 30
POST /micropub HTTP/1.1
Host: aaronpk.example
Content-type: application/json

{
  "type": ["h-entry"],
  "properties": {
    "name": ["Itching: h-event to iCal converter"],
    "content": [
      {"html": "Now that I've been <a href=\"https://aaronparecki.com/events\">creating a list of events</a> on my site using <a href=\"https://p3k.io\">p3k</a>, it would be great if I could get a more calendar-like view of that list..."}
    ],
    "category": [
      "indieweb", "p3k"
    ]
  }
}

4.1.4 이미지가 포함된 새 기사

이미지가 삽입된 기사를 생성하려면, 해당 HTML 내에 미디어 엔드포인트에 업로드한 후 반환받은 이미지의 URL로 <img> 태그를 추가해야 합니다.

미디어 엔드포인트로 이미지 업로드

우선, 하나 이상의 이미지를 미디어 엔드포인트에 업로드합니다. 일반적으로 이는 기사가 게시되기 전에, 예를 들어 시각적 에디터에서 사용자가 이미지를 추가하는 순간 이루어집니다. 에디터는 이미지를 인터페이스에 드래그하는 즉시 미디어 엔드포인트에 업로드하고, 반환된 URL을 통해 이미지를 본문에 삽입할 수 있습니다. 이 요청의 예시는 미디어 엔드포인트로 업로드를 참고하세요.

미디어 엔드포인트에 파일을 업로드한 뒤 응답으로 반환되는 값은, 클라이언트가 기사 작성시 사용할 수 있는 URL이 됩니다.

Example 31
HTTP/1.1 201 Created
Location: https://media.example.com/file/ff176c461dd111e6b6ba3e1d05defe78.jpg

클라이언트는 이 URL을 이용해 이미지를 기사에 삽입할 수 있습니다.

Example 32
POST /micropub HTTP/1.1
Host: aaronpk.example
Content-type: application/json

{
  "type": ["h-entry"],
  "properties": {
    "content": [
      {"html":"<p>Hello World</p><p><img src=\"https://media.example.com/file/ff176c461dd111e6b6ba3e1d05defe78.jpg\"></p>"}
    ]
  }
}

4.1.5 파일 게시

Micropub 요청에 파일이 포함된 경우, 전체 요청은 multipart/form-data 인코딩으로 전송되며, 파일명은 어휘에 따라 audio, video 또는 photo 중 하나로 지정됩니다. 요청에는 이 중 하나 이상의 파일이 MAY 포함될 수 있습니다.

예를 들어, 서비스에서 video 속성에는 영상을, photo 속성에는 영상 프레임의 미리보기 이미지를 게시할 수 있습니다.

PHP의 경우, 이 파일들은 $_FILES 배열로 접근할 수 있습니다:

$_FILES['video']
$_FILES['photo']
$_FILES['audio']

요청 본문이 JSON 인코딩일 경우 파일 업로드는 불가능합니다. 대신 우선 사진을 미디어 엔드포인트에 보내고, 이후 반환받은 URL을 JSON 포스트에 사용해야 합니다.

Micropub 엔드포인트는 파일을 직접 저장하거나, Amazon S3 등 외부 스토리지 백엔드에 업로드할 수 있습니다.

5. 인증 및 인가

5.1 인증

Micropub 요청은 MUST OAuth Bearer Token RFC [RFC6750]에 명시된 대로 HTTP 헤더 또는 form-encoded 본문 파라미터에 Bearer Token을 포함하여 인증되어야 합니다. Micropub 서버는 이 두 방식 모두로 토큰을 받는 것을 MUST 지원해야 합니다.

HTTP 헤더

Authorization: Bearer XXXXXXXXX

Form-Encoded 본문 파라미터

access_token=XXXXXXXXX

5.2 인가

앱이 사용자의 Micropub 엔드포인트에 게시하려면, 액세스 토큰을 받기 위해 사용자의 인가를 받아야 합니다. 인가는 OAuth 2.0 [RFC6749] 프로토콜을 통해 SHOULD 처리해야 합니다. 응용 프로그램은 엔드포인트 탐색을 지원하는 [IndieAuth] 확장도 MAY 사용할 수 있습니다. 자세한 내용은 액세스 토큰 획득 문서를 참조하세요.

5.3 엔드포인트 발견

Micropub에서는 micropub 링크 관계값을 정의하여, 사용자 프로필 페이지에서 해당 웹사이트의 Micropub 엔드포인트를 연결하도록 합니다.

Micropub 클라이언트는 이 링크 관계를 통해 사용자의 Micropub 엔드포인트를 발견할 수 있어야 SHOULD 합니다.

클라이언트는 인증에 사용된 URL의 HTML 헤드에서 <link rel="micropub"> 태그를 검색하거나, rel 값이 micropubHTTP Link 헤더를 찾습니다.

Link: <https://aaronpk.example/micropub>; rel="micropub"

<link rel="micropub" href="https://aaronpk.example/micropub">

5.4 스코프

Micropub 서버는 임의의 토큰으로 게시물이 생성되지 않도록, Bearer 토큰에 하나 이상의 scope 값이 반드시 포함되도록 MUST 요구해야 합니다.

클라이언트는 인가 요청 시 하나 이상의 scope를 요청할 수 있습니다. 표준 OAuth 2.0 [RFC6749] 방식(인가 요청에 scope 이름을 공백으로 구분해 전달)에 따릅니다. 자세한 내용은 RFC6749 Section 3.3 참조.

인가 서버는 인가 요청에 포함된 scope가 어떤 것이든 사용자에게 모두 표시해야 MUST 하며, scope를 인가 서버가 인식하지 않더라도 마찬가지입니다. 인가 서버는 클라이언트가 요청한 scope를 추가/제거할 수 있도록 MAY 허용할 수도 있습니다.

대다수 Micropub 서버는 게시물을 생성하기 위해 클라이언트가 "create" scope를 얻도록 요구합니다. 일부 서버는 MAY "delete", "update", "create:video" 등 더 세분화된 scope를 요구할 수도 있습니다. 자세한 내용 및 현재 사용되는 모든 scope 값을 확인하려면 스코프(Scope)를 참고하세요.

6. 보안 고려사항

6.1 외부 콘텐츠

사진이나 기타 미디어를 허용하는 Micropub 엔드포인트는 클라이언트가 해당 파일 업로드를 자체적으로 제공할 때처럼, Micropub 엔드포인트 또는 미디어 엔드포인트가 아닌 도메인의 파일 URL이 포함된 요청을 받을 수 있습니다. URL 값을 허용하는 보안적 방법 중 하나는 신뢰할 수 있는 도메인(예: Micropub 서버의 도메인 및 해당 미디어 엔드포인트) 목록으로부터의 미디어만 다운로드 및 저장하고, 그 외에는 파일의 URL만 저장하는 것입니다.

6.2 보안 및 프라이버시 검토

아래 질문들은 Self-Review Questionnaire: Security and Privacy([security-privacy-questionnaire]) 가이드에 따라 이 명세의 보안 및 프라이버시 고려사항을 개괄합니다.

이 명세는 개인 식별 가능한 정보를 다루나요?
Micropub은 사용자가 게시물을 생성·수정할 수 있게 하므로, 사용자가 콘텐츠를 작성할 때 개인 식별 정보를 입력할 수 있습니다. Micropub 클라이언트는 자신이 게시물을 관리하는 Micropub 엔드포인트의 URL을 인지하며, 이 URL이 개인 식별이 가능하거나 또는 공유 도메인일 수 있습니다.
이 명세는 고가치(high-value) 데이터를 다루나요?
이 명세는 OAuth 2.0 Bearer Token을 사용하며, Security and Privacy Questionnaire에 따라 “고가치”로 간주됩니다. 추가 정보는 OAuth 2.0 Bearer Token (RFC6750) 보안 고려사항 섹션을 참고하세요.
이 명세는 브라우징 세션 간 지속되는 새로운 상태를 원본(origin)에 도입하나요?
아니요, Micropub은 브라우저 세션 간에 데이터를 지속시키는 어떤 메커니즘도 제공하지 않습니다.
이 명세는 웹에 지속적이고 크로스 오리진 상태를 노출하나요?
이 명세는 클라이언트가 게시물을 생성하게 하며, 서버는 새 URL을 공개로 만들 수도 있습니다.
이 명세는 현재 접근할 수 없는 다른 데이터를 원본에 노출하나요?
아니요
이 명세는 새로운 스크립트 실행/로딩 메커니즘을 제공하나요?
아니요
이 명세는 원본이 사용자의 위치 정보에 접근할 수 있게 허용하나요?
아니요
이 명세는 원본이 사용자의 기기의 센서에 접근할 수 있게 허용하나요?
아니요
이 명세는 원본이 사용자의 로컬 컴퓨팅 환경 일부에 접근할 수 있도록 허용하나요?
아니요
이 명세는 원본이 다른 기기에 접근할 수 있도록 허용하나요?
아니요
이 명세는 원본이 사용자 에이전트의 기본 UI 일부를 제어할 수 있게 허용하나요?
아니요
이 명세는 웹에 임시 식별자를 노출하나요?
아니요
이 명세는 1st-party와 3rd-party 맥락에서 동작이 달라지나요?
아니요
이 명세는 사용자 에이전트의 “시크릿 모드”에서 어떻게 동작해야 하나요?
사용자 에이전트가 Micropub 클라이언트인 경우, “시크릿 모드”에서는 사용자 접근 토큰과 Micropub 엔드포인트 등 세션과 연관된 정보를 “잊어야” 합니다.
이 명세는 사용자의 로컬 디바이스에 데이터를 저장하나요?
Micropub 클라이언트는 사용자의 Micropub 엔드포인트와 액세스 토큰을 저장해야 합니다. 사용자가 브라우저 데이터를 지우면, 클라이언트는 저장된 자격증명과 미디어 엔드포인트에서 캐싱된 URL도 삭제해야 합니다.
이 명세는 기본 보안 특성을 다운그레이드하는 것을 허용하나요?
아니요

7. IANA 고려사항

아래 링크 관계 유형이 [RFC5988] 6.2.1절에 따라 IANA에 등록되어 있습니다:

관계 이름(Relation Name):
micropub
설명(Description):
Micropub 프로토콜에 따라 게시물을 생성할 수 있는 Micropub 엔드포인트를 검색하는 데 사용됩니다.
Reference:
W3C Micropub 명세 (https://www.w3.org/TR/micropub/)

A. 참고 자료

이 절은 비규범적입니다.

A.1 구현 사례

이 절은 비규범적입니다.

Micropub.net에서 Micropub 구현 목록을 확인할 수 있습니다.

B. 감사의 글

에디터는 IndieWeb 커뮤니티와 다양한 구현자들의 지원, 격려, 열정에 감사를 표합니다. 특히, 에디터는 다음 분들께 특별히 감사합니다: Amy Guy, Barry Frost, Benjamin Roberts, Chris Webber, Christian Weiske, David Shanske, Emma Kuo, Kyle Mahan, Jeena Paradies, Malcolm Blaney, Martijn van der Ven, Marty McGuire, Mike Taylor, Pelle Wessman, Ryan Barrett, Sandro Hawke, Sven Knebel, 그리고 Tantek Çelik.

C. 변경 이력

이 절은 비규범적입니다.

C.1 2017년 4월 13일 PR에서 이 버전까지의 변경사항

이 절은 2017년 4월 13일 PR에서 이 버전까지의 변경사항을 나열합니다.

비규범적 변경사항

C.2 2016년 10월 18일 CR에서 2017년 4월 13일 PR까지의 변경사항

이 절은 2016년 10월 18일 CR에서 2017년 4월 13일 PR까지의 변경사항을 나열합니다.

비규범적 변경사항

C.3 2016년 8월 16일 CR에서 2016년 10월 18일 CR까지의 변경사항

이 절은 2016년 8월 16일 CR에서 2016년 10월 18일 CR까지의 변경사항을 나열합니다.

규범적 변경사항

비규범적 변경사항

C.4 2016년 7월 13일 WD에서 2016년 8월 16일 CR까지의 변경사항

이 절은 2016년 7월 13일 WD에서 2016년 8월 16일 CR까지의 변경사항을 나열합니다.

C.5 2016년 6월 21일 WD에서 2016년 7월 13일 WD까지의 변경사항

이 절은 2016년 6월 21일 WD에서 2016년 7월 13일 WD까지의 변경사항을 나열합니다.

C.6 2016년 5월 4일 WD에서 2016년 6월 21일 WD까지의 변경사항

이 절은 2016년 5월 4일 WD에서 2016년 6월 21일 WD까지의 변경사항을 나열합니다.

C.7 2016년 3월 1일 WD에서 2016년 5월 4일 WD까지의 변경사항

이 절은 2016년 3월 1일 WD에서 2016년 5월 4일 WD까지의 변경사항을 나열합니다.

C.8 2016년 1월 28일 FPWD에서 2016년 3월 1일 WD까지의 변경사항

이 절은 2016년 1월 28일 FPWD에서 2016년 3월 1일 WD까지의 변경사항을 나열합니다.

D. 참고문헌

D.1 규범적 참고문헌

[BIDI]
Unicode Bidirectional Algorithm. Mark Davis; Aharon Lanin; Andrew Glass. Unicode Consortium. 2016년 5월 18일. Unicode Standard Annex #9. URL: http://www.unicode.org/reports/tr9/tr9-35.html
[Fetch]
Fetch Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML5]
HTML5. Ian Hickson; Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Theresa O'Connor; Silvia Pfeiffer. W3C. 2014년 10월 28일. W3C 권고안. URL: https://www.w3.org/TR/html5/
[JSON]
The application/json Media Type for JavaScript Object Notation (JSON). D. Crockford. IETF. 2006년 7월. 정보성 문서. URL: https://tools.ietf.org/html/rfc4627
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. 1997년 3월. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC2616]
Hypertext Transfer Protocol -- HTTP/1.1. R. Fielding; J. Gettys; J. Mogul; H. Frystyk; L. Masinter; P. Leach; T. Berners-Lee. IETF. 1999년 6월. Draft Standard. URL: https://tools.ietf.org/html/rfc2616
[RFC5988]
Web Linking. M. Nottingham. IETF. 2010년 10월. Proposed Standard. URL: https://tools.ietf.org/html/rfc5988
[RFC6749]
The OAuth 2.0 Authorization Framework. D. Hardt, Ed.. IETF. 2012년 10월. Proposed Standard. URL: https://tools.ietf.org/html/rfc6749
[RFC6750]
The OAuth 2.0 Authorization Framework: Bearer Token Usage. M. Jones; D. Hardt. IETF. 2012년 10월. Proposed Standard. URL: https://tools.ietf.org/html/rfc6750
[h-entry]
h-entry. Tantek Çelik. microformats.org. Living Specification. URL: http://microformats.org/wiki/h-entry
[microformats2-parsing]
Microformats2 Parsing. Tantek Çelik. microformats.org. Living Specification. URL: http://microformats.org/wiki/microformats2-parsing

D.2 비규범적 참고문헌

[IndieAuth]
IndieAuth. Aaron Parecki. indieweb.org. Living Specification. URL: https://indieweb.org/IndieAuth-spec
[Microformats2]
Microformats 2. Tantek Çelik. microformats.org. Living Specification. URL: http://microformats.org/wiki/microformats2
[RFC5870]
A Uniform Resource Identifier for Geographic Locations ('geo' URI). A. Mayrhofer; C. Spanring. IETF. 2010년 6월. Proposed Standard. URL: https://tools.ietf.org/html/rfc5870
[h-adr]
h-adr. Tantek Çelik. microformats.org. Living Specification. URL: http://microformats.org/wiki/h-adr
[h-card]
h-card. Tantek Çelik. microformats.org. Living Specification. URL: http://microformats.org/wiki/h-card
[h-event]
h-event. Tantek Çelik. microformats.org. Living Specification. URL: http://microformats.org/wiki/h-event
[security-privacy-questionnaire]
Self-Review Questionnaire: Security and Privacy. Mike West. W3C. 2015년 12월 10일. W3C Note. URL: https://www.w3.org/TR/security-privacy-questionnaire/
[social-web-protocols]
Social Web Protocols. Amy Guy. W3C. 2017년 5월 4일. W3C Working Draft. URL: https://www.w3.org/TR/social-web-protocols/