Last active
September 26, 2019 19:15
-
-
Save cdeutsch/744b08b3609c5eb0d60dc59cbeec56df to your computer and use it in GitHub Desktop.
Isomorphic Async Proposal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// UserStore.ts | |
// | |
// This is the code you write and is executed on the Node.js server side. | |
// The decorators can be used to automatically turn it into Express routes. | |
// | |
// Pretty much already exists using `routing-controllers` NPM | |
@Route('/api/users') | |
export class UserStore { | |
@Get('/') | |
public static async getAll() { | |
return db.users.find(); | |
} | |
@Post('/') | |
public static async add(user) { | |
const newUser = db.users.add(user); | |
return newUser; | |
} | |
@Get('/anything') | |
public static async doAnything() { | |
// Do some random async task to sync user data. | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// UserStore.ts | |
// | |
// A transformer like TypeScript, Babel, or Webpack will transform the "real" UserStore.ts into: | |
export class UserStore { | |
public static async getAll() { | |
return await axios.get('/api/users'); | |
} | |
public static async add(user) { | |
return await axios.post('/api/users', user); | |
} | |
public static async doAnything() { | |
return await axios.get('/api/anything'); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Isomorphic React Component that can be re-used server and browser side: | |
export class UsersPage extends React.Component { | |
// Executed server side by next.js to populate initial data: | |
// https://nextjs.org/docs#fetching-data-and-component-lifecycle | |
static async getInitialProps({ req }) { | |
const users = await UserStore.getAll(); | |
return { users: users }; | |
} | |
constructor(props: any) { | |
super(props); | |
this.state = { | |
users: props.users | |
}; | |
} | |
render() { | |
return ( | |
<div> | |
<ul> | |
{this.state.users.map((user) => ( | |
<li key={user.id}>{user.name}</li> | |
))} | |
</ul> | |
<button onClick={this.onClick}>Add random user</button> | |
</div> | |
); | |
} | |
onClick = async () => { | |
// calls the frontend version of | |
await UserStore.add({ | |
name: randomNamePicker() | |
}); | |
this.setState({ | |
users: [...users, user] | |
}) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Server.ts | |
// Inspired by `routing-controllers` | |
// https://github.com/typestack/routing-controllers#example-of-usage | |
import { useExpressServer } from 'isomorphic-async'; | |
import { UserStore } from './UserStore'; | |
const app = express(); | |
useExpressServer(app, { | |
routes: [UserStore], | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment