api design for ISOMORPHIC age
WHOAMI
HOW API DESIGN TREND CHANGED
Text
- Old age: Define multiple endpoints per action
- GET /all_users.json
- GET /user.json
- POST /create_user.json
- POST /delete_user.json (Note: this is *not* DELETE)
HOW API DESIGN TREND CHANGED
Text
- Old age: Define multiple endpoints per action
- REST got those into more declarative (and resource-based) way:
- GET /users # All users
- GET /users/:id # Single user
- POST /users # Create a single user
- DELETE /users/:id # Delete a single user
HOW API DESIGN TREND CHANGED
Text
- Old age: Define multiple endpoints per action
- REST got those into more declarative (and resource-based) way
- Single-endpoint based framework (GraphQL/Relay)
- Large application needs less requests to scale. e.g. Facebook
GRAPHQL:
WHAT DID IT
CHANGE?
NO RESOURCE
ONE ENDPOINT
THERE IS A REACT WRAPPER FOR GRAPHQL NAMED RELAY.
DESIGNED FOR DOING ALL OPERATIONS IN ONE SINGLE ENDPOINT
GRAPHQL ITSELF DOESN'T DEPEND ON ANY SPECIFIC LANGUAGE.
CONCEPT
https://medium.com/chute-engineering/graphql-in-the-age-of-rest-apis-b10f2bf09bba#.m3xh3gubu
LEARNING GRAPHQL
JUST {SUCKS}
query Hero($episode: Episode, $withFriends: Boolean!) {
hero(episode: $episode) {
name
friends @include(if: $withFriends) {
name
}
}
}
THIS IS ACTUALLY A [LANGUAGE] WITH UGLY SYNTAX AND TOO MUCH FEATURES.
IT HAS A HUGE LEARNING CURVE.
SO WHAT
I MADE F*CKIN
NEW FRAMEWORK
universal
SINGLE-ENDPOINT
WEBSOCKET- compatible
universal
SINGLE-ENDPOINT
WEBSOCKET- compatible
UNIVERSAL
- Using same codebase in both.
- Each endpoint calls looks like normal function calls.
- Strong TypeScript support.
APPLICATION
import { op, load } from "xhip"
const request = load("request")
export class App {
@op showAppName() {
return {
appName: "xhip example"
}
}
@op showAppVersion() {
return {
appVersion: 1
}
}
@op getServerIP() {
return new Promise((resolve, reject) =>
request.get('https://api.ipify.org?format=json', (error, response, body) => {
if (error) reject(error)
resolve({ ip: JSON.parse(body).ip })
})
).catch(err => {
console.log(err)
})
}
@op echo(say) {
return { say }
}
}
export const app = new App()
Xhip provides its own loader function for isomorphism between server and frontend
Server-side
import { Server } from "xhip-server"
import { app } from "./app.js"
new xhip.Server(app, {
cors: {
origin: 'http://localhost:21000', // for CORS support
credentials: true,
}
}).listen(8080)
FRONTEND
import { Client } from "xhip-client"
const client = new xhip.Client("http://localhost:8080/", { ssl: false })
client.exec([
app.showAppName(),
app.showAppVersion(),
app.echo("hi"),
app.getServerIP()
])).then(...)
{
appName: "xhip example",
appVersion: 1,
say: "hi",
ip: ***.***.***.***
}
STRONG TYPINGS
for frontend :)
universal
SINGLE-ENDPOINT
WEBSOCKET- compatible
SINGLE-ENDPOINT
- Have no separated endpoint like RESTful API.
- All operations will be merged to single JSON/msgpack.
- Accomplishes same thing with fewer requests.
universal
SINGLE-ENDPOINT
WEBSOCKET- compatible
Websocket-Compatible
- Any operations can be treated as API and as WebSocket.
- I am not kidding.
SUBSCRIption model
LET'S TYPE:
http://xhip-example.heroku.com/
ARE YOU READY TO embrace THE FUTURE?
hope you like Xhip :p
Thanks for listening
API Design for Isomorphic Age
By minamorl
API Design for Isomorphic Age
- 4,788