Micropub: The Emerging API Standard for IndieWeb Apps

Open Source Bridge - June 24th, 2015

Micropub: The Emerging API Standard for IndieWeb Apps



Open Source Bridge - June 24th, 2014

aaronparecki.com

@aaronpk

Anyone can publish
on the Web

indiewebcamp.com/principles

Why not post
to your own site
from other apps?

Twitter Client Ecosystem (2012)

Twitter Client Attribution

Micropub

Micropub

Micropub Endpoint

Taproot

Micropublish

Android App

Browser Extension

Pebble

OwnYourGram

How does it
work?

IndieAuth =
OAuth 2.0 +
Web Identity

			Application
			client_id = https://quill.p3k.io/
			redirect_uri = https://quill.p3k.io/auth/callback
			
				User
				me = https://aaronparecki.com/
			
			
				User's services
				authorization_endpoint = https://indieauth.com/auth
				token_endpoint = https://tokens.indieauth.com/token
				micropub = https://aaronparecki.com/micropub
			
		

Declaring the endpoints

on aaronparecki.com

			<html lang="en">
			<head>
			    <title>Aaron Parecki</title>
			    <link rel="authorization_endpoint" href="https://indieauth.com/auth">
			    <link rel="token_endpoint" href="https://tokens.indieauth.com/token">
			    <link rel="micropub" href="/micropub">
			</head>
		

"Registering" the redirect_uri

on quill.p3k.io

			<html lang="en">
			<head>
			    <title>Quill</title>
			    <link rel="redirect_uri" href="https://quill.p3k.io/auth/callback">
			</head>
		

Sign-In Form

When submitted, the server discovers the user's authorization_endpoint, and redirects the browser there with the parameters for the request.

Send the user to their auth server


https://indieauth.com/auth?me=https://aaronparecki.com/&
   client_id=https://quill.p3k.io/&
   redirect_uri=https://quill.p3k.io/auth/callback&
   state=1234567890&
   scope=post
		

Auth server presents the request

User authenticates, IndieAuth server generates an authorization code

HTTP/1.1 302 Found
Location: https://quill.p3k.io/auth/callback?
  code=xxxxxxxx&
  state=1234567890&
  me=https://aaronparecki.com/
		

Quill obtains an access token

POST https://tokens.indieauth.com/token
me=https://aaronparecki.com/&
code=xxxxxxxx&
redirect_uri=https://indiewebcamp.com/auth/callback&
client_id=https://indiewebcamp.com&
state=1234567890&
scope=post
		

Quill obtains an access token

Response:
HTTP/1.1 200 OK
me=https://aaronparecki.com/&
access_token=XXXXXX&
scope=post

User is signed in!

Using the Access Token

indiewebcamp.com/token-endpoint

Micropub

Micropub Request

POST https://aaronparecki.com/micropub
Authorization: Bearer XXXXXXXXXXXXXXX
Content-Type: application/x-www-form-urlencoded

h=entry&
content=Hello+World
		

Micropub Response

HTTP/1.1 201 Created
Content-Type: application/x-www-form-urlencoded
Location: http://aaronparecki.com/notes/2014/06/23/1/
Link: <http://aaron.pk/n4Wj1> rel="shortlink"
		

Creating other types of posts

Post with Location

POST https://aaronparecki.com/micropub
Authorization: Bearer XXXXXXXXXXXXXXX
Content-Type: application/x-www-form-urlencoded

h=entry&
content=Hello+World
location=geo:45.525185,-122.681633
		

Micropub Photo Post

POST https://aaronparecki.com/micropub
Authorization: Bearer XXXXXXXXXXXXXXX
Content-Type: multipart/form-data; boundary=-------xxxxxx
-------xxxxxx
Content-Disposition: form-data; name="h"
entry
-------xxxxxx
Content-Disposition: form-data; name="content"
Grabbing a drink and working on my slides while waiting to 
get my hair cut! 🍸☀️✂️👍
-------xxxxxx
Content-Disposition: form-data; name="file"; filename="photo.jpg"
Content-Type: image/jpeg
[image data]

		

A "like" post

POST https://aaronparecki.com/micropub
Authorization: Bearer XXXXXXXXXXXXXXX
Content-Type: application/x-www-form-urlencoded

h=entry&
like-of=http://example.com/thing/that/is/liked
		

Even more kinds of posts

Micropub

Editing with Micropub

Editing with Micropub

Note: Still in progress

Microformats 2

<div class="h-entry">
  <p class="p-name e-content">Hello World</p>
  <a class="p-author h-card" href="http://aaronpk.com">
    Aaron Parecki
  </a>
  <a href="http://aaronpk.com/post/1" class="u-url">
    <time class="dt-published" datetime="2015-06-24">
      June 24, 2015
    </time>
  </a> 
</div>
		
{
  "items": [{
    "type": ["h-entry"],
    "properties": {
      "author": [{
        "type": ["h-card"],
        "properties": {
          "name": ["Aaron Parecki"],
          "url": ["http:\/\/aaronpk.com"]
        },
        "value": "Aaron Parecki"
      }],
      "name": ["Hello World"],
      "published": ["2015-06-24"],
      "url": ["http:\/\/aaronpk.com\/post\/1"],
      "content": ["Hello World"]
    }
  }]
}

Posting an "Edit"

Edits as their own posts

Like pull requests on GitHub

Replacing a property

{
  "edit-of": "http://example.com/post/1",
  "update": {
    "properties": {
      "content": ["hello moon"]
    }
  }
}

Adding a value to a property

{
  "edit-of": "http://example.com/post/1",
  "add": {
    "properties": {
      "category": ["indieweb","foo"]
    }
  }
}
If there are any existing values for this property, they are not changed, the new values are added. If the property does not exist already, it is created.

Removing a value from a property

{
  "edit-of": "http://example.com/post/1",
  "delete": {
    "properties": {
      "category": ["indieweb"]
    }
  }
}
This removes just the "indieweb" value from the "category" property, leaving all other values. If no values remain, the property is removed.

Removing a property completely

{
  "edit-of": "http://example.com/post/1",
  "delete": {
    "properties": ["category"]
  }
}

Deleting a post

{
  "delete-of": "http://example.com/post/1"
}

Getting Started

Thanks!

Learn more: micropub.net

IndieWebCamp Events!

indiewebcamp.com/events