This is the tale of how we, at Balsamiq, rolled out our new web-app, from greenfield to production. A real-world application with real-time collaboration, built using Relay, Redux, React-rendered html emails, node.js, Redis, etc., running on AWS using Convox. Even at small/medium scale, if you're serious about building a good product you will eventually have to build a complex stack. I will share the details of the services we use, how we make them fit together and what we learned in the process.
2. GraphQL
• Alternative to REST
• Space efficient in the network
• Nice way to describe the UI data requirements
• Nice way to organize code on the server
17. An operation
export default function ({db, siteId, name, logger, notificationCentral,
subscriptionsManager, loggedUser, cache, whenFinished}) {
logger.info('performing operation: changeSiteName');
return db.withTransaction(async function () {
let userInSite = await db.queryUserInSiteById(siteId, loggedUser);
if (!userInSite) {
throw new ErrorWithInfo('User does not belong to site', {
detail: `User ${loggedUser.id} not in site ${siteId}`,
code: 'RENAME_SITE_USER_NOT_IN_SITE'
});
}
if (!userInSite.isSiteOwner()) {
throw new ErrorWithInfo('User is not site owner', {
detail: `User ${loggedUser.id} is not owner of site ${siteId}`,
code: 'RENAME_SITE_USER_NOT_SITE_OWNER'
});
}
let site = await db.changeSiteName(siteId, name);
...
await cache.storeSite(site);
await db.addHistoryLine(changeSiteName(siteId, name, loggedUser));
whenFinished(() => {
notificationCentral.notifySiteNameChanged(siteId, name, logger);
});
return {siteId};
});
}
18. Error management
1. A simple text for the user
• Indicate the next step
2. A detailed text for the server logs
• To help debug the issue
3. A unique error code
• To pinpoint the snippet of code
throw new ErrorWithInfo('User does not belong to site', {
detail: `User ${loggedUser.id} not in site ${siteId}`,
code: 'RENAME_SITE_USER_NOT_IN_SITE'
});
28. Reactivity
• Relay Classic: no solution out of the box
• Pub-Sub + forceFetch: a solution but inefficient
• Relay Modern and Apollo: GraphQL Subscriptions
• Live queries: promising, but still open discussion
inherent complexity, deal with it