New approaches to hypertext and REST in a mobile-first world

Post on 07-Feb-2017

76 views 1 download

Transcript of New approaches to hypertext and REST in a mobile-first world

Israel ShirkRight now: Mad scientist, Ultra Runner,

Backcountry Skier, Performance Architect @ Scentsy (starting Monday), CTO @ Zerrtech, and a

bunch of other stuff

Ok, it’s really “New approaches to hypertext and REST in a mobile-first world

Old internet: Homogeneity (except you-know-who)

New internet: Shimmable homogeneity on the browser

Tablets!Phones!

Desktop Applications!Web Applications!

Embedded Devices!

Background:What is “hypertext”?

Background:What is “hypertext”?

Google:“A software system that links topics on the screen to related information and graphics, which are typically

accessed by a point-and-click method”

Background:What is “REST”?

Background:What is “REST”?

Martin Fowler:Level 0 to Level 4

Credit: https://martinfowler.com/articles/richardsonMaturityModel.html

POX: Plain Old Xml (or JSON)

(Yeah, I’m saying your REST API ain’t REST)

Skip a few: Rest Level 3Hypermedia Controls

Skip a few: Rest Level 3Hypermedia Controls

(HATEOAS)

HATEOAS:I hate operating

systems?

HATEOAS:Hypertext As The Engine Of Application

State

Great example: HTML w/o JS.

New world order:HTML does not always translate across

devicesthe way we want it to!

(dangit)

Solutions?REST L4 in other forms,interpreted on device

(like… a compat layer in-browser,NativeScript, Electron, React Native,

…)

Solution I’m using right now?JSON Hyperschema (with nonstandard

extensions)

Alternatives?VND is most popular, others are out there but

rarer

Why JSON Hyperschema?

It’s made for this problem: self-describing APIs

and objects.

Example:

{"$schema":

“http://json-schema.org/schema#",“type”: “person”,“X-name”: “Israel”,“links”: [{“rel”: “profile”,“href”: “

https://www.facebook.com/israelshirk"},{“rel”: “hubgit”“href": “https://github.com/israelshirk"

}]

}

Declare as JSON schema:{"$schema":

“http://json-schema.org/schema#",“type”: “person”,“X-name”: “Israel”,“links”: [{“rel”: “profile”,“href”: “

https://www.facebook.com/israelshirk"},{“rel”: “hubgit”“href": “https://github.com/israelshirk"

}]

}

Define type of object(technically the RFC doesn’t allow this but…

Open source to the rescue!){"$schema":

“http://json-schema.org/schema#",“type”: “person”,“X-name”: “Israel”,“links”: [{“rel”: “profile”,“href”: “

https://www.facebook.com/israelshirk"},{“rel”: “hubgit”“href": “https://github.com/israelshirk"

}]

}

Custom extensions start with X- to be mostly in-line with standards

{"$schema": “http://json-schema.org/schema#",“type”: “person”,“X-name”: “Israel”,“links”: [{“rel”: “profile”,“href”: “https://www.facebook.com/israelshirk"

},{“rel”: “hubgit”“href": “https://github.com/israelshirk"

}]

}

Links to indicate paths that can be followed{"$schema":

“http://json-schema.org/schema#",“type”: “person”,“X-name”: “Israel”,“links”: [{“rel”: “profile”,“href”: “

https://www.facebook.com/israelshirk"},{“rel”: “hubgit”“href": “https://github.com/israelshirk"

}]

}http://json-schema.org/latest/json-schema-hypermedia.html#rfc.section.5

We can then start doing really fancy stuff:

{"$schema": “http://json-schema.org/schema#",“type”: “person”,“X-name”: “Israel”,“X-profile-name”: “israelshirk”,“X-Friends”: { “$ref”: “/{profile}/friendlist” },“links”: [

{“rel”: “profile”,“href”: “https://www.facebook.com/{profile}"

},{

“rel”: “hubgit”,“href": “https://github.com/{profile}"

},{

“rel”: “save”,“href”: “/{profile}”

}]

}

Critical factors:

Easy-to-use interpreters.

Check out:Mozilla’s React-Jsonschema-Form (I’m a rabble-rouser there)Angular-Schema-Form (schemaform.io - just a bug fixer here)

tv4 - great little JS lib for JSON hyper schema validation. I have a fork…. Somewhere. Email me.

Then: Custom components for your object types!Webcomponents are essential here.

For example, creating your own type in React-Jsonschema-Form: https://github.com/mozilla-services/react-jsonschema-form#advanced-customization

function PageLayout(props) { const {children, schema} = props; return ( <div class=“root”>

<!— This is the root page element. Children of the schema go into children below! —> {children} </div> );}

render(( <Form schema={schema} fields={ { “page-layout”: PageLayout } } />,), document.getElementById("app"));

For example, creating your own type in React-Jsonschema-Form: https://github.com/mozilla-services/react-jsonschema-form#advanced-customization

function PageLayout(props) { const {children, schema} = props; return ( <div class=“root”>

<!— This is the root page element. Children of the schema go into children below! —> <div className=“col-xs-12”> <Form schema={schema[‘X-header’]} fields={fields} >

</div> );}

let fields = { PageLayout: PageLayout }

render(( <Form schema={schema} fields={ fields } />,), document.getElementById("app"));

Pretty quickly though you can do things like this, and each client will have an appropriate representation of the object,

laid out differently by device type - but all from the same backend:{

“type”: “page-layout”,“properties”: {

“header”: {“type”: “array”,“items”: [

{ “type”: “header-item”, “title”: “Click me!”, “links”: [{ “link”: “/clickme” }]

}],

},“body”: {

“type”: “person”,…

}}

}

End result? Data-centric wonderfulness server-side,

render-centric focus client-side!

Next steps?Integration into nginx+lua+memcache for ref

resolution,like Varnish/Akamai for ESI

Add more gif (spoken as spelled)Public code samples