New approaches to hypertext and REST in a mobile-first world
-
Upload
israel-shirk -
Category
Self Improvement
-
view
76 -
download
1
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