
Data Interactivity in the Serverless Future (HYTRADBOI 2022)
hey folks i'm james i'm co-founder at a company called convex and i'm going to be talking today about data interactivity in the serverless future so i've spent a lot of my life building large-scale infrastructure but today i want to talk about a trend that's underway in how people build applications and one that i don't think is being adequately met at least historically but i think convex is doing a good job of doing so so convex is a platform for building dynamic serverless applications and i'm going to elaborate on this problem space in this talk but if you plan on tuning out just hit up convex.dev and you can try things out for yourself so i said there's a serverless trend underway and at its core this trend is just that application developers don't want to deal with infrastructure they want to build products that people use the other day one of our developers said that having to deploy a back end sucks all the joy out of building a project and this is actually great they want to create value for users and they want to spend as little time as possible on supporting infrastructure so you're seeing early signs of this trend in platforms like netlify and vasel these are platforms for rapidly deploying an app written in something like react or next.js in literally 90 seconds so you can take an app from a github repo to deploy it on a global cdn almost immediately they're really quite magical but one area where the magic starts to fade a little is we need to build a dynamic application one with changing data or interactivity because then you need to talk to a database and databases are near and dear to my heart but to most people databases are a huge pain so sure they're a lot of work to set up and maintain and there's some good services for that these days but more notably they're complex to interact with so issues around refreshing application state when back-end data changes caching results correctly in ways that don't break your consistency guarantees or queries and schemas that aren't able to be represented easily in a few lines of sql so the core need here is global state management and i think these words here are important so it's state and not data clients and application developers care about the state they're rendering to the user it doesn't matter if the data in postgres is correct if the representation of it is anomalous it's the user facing state that matters and it's management not transactions or storage those things are important but the key to getting this right is providing tools for developers to mutate and synchronize data right out to the edge right out to their users so this is the dialect of the end user developer global state management it reflects what they care about they don't want abstractions that encapsulate the shape of underlying infrastructure they want abstractions that match the shape of the problems that they're facing so let's talk about convex and how it's dissolved designed to solve these problems so behind the scenes convex is two things it's a database and it's an execution engine so the database uses multi-version optimistic concurrency control it's relational it provides full serializability it uses a timestamp oracle to serialize transactions there's a ton to talk about in here and i love talking about database implementation details but i don't think they're actually too relevant to this talk what is relevant is the features that the database supports so one of these features is how we handle schemas so the developer can treat convex as schema-less and just dump their json blobs right into the system when they're getting started but convex actually dynamically tracks the shape of all the data put into the system so here's a screenshot from our dashboard showing the inferred schema for a table right this is a messages table in a chat application and it has an author a body an id a channel etc relatively straightforward but these schemas can be more complex they represent the union type of all the data put into the table so here you can see there's a field called foo that's optional sometimes includes another nested object can have arrays with different types in them and these schemas can be codified over time and they can be used as the basis for schema migrations and there's a lot we can talk about the database itself but i also want to get to the execution the second part of the convex cloud so the queries in convex are actually javascript or typescript functions they're in the language that developers are already using and they can be used to do relatively sophisticated queries and data transformations these run server side and form the basis for the transactions that we run so here's the query in convex this one's actually written in typescript and you can talk directly to the database via this db call here so we have db.table which is looking up the messages table in the database and that's filtering based on a channel id this is a relatively simple query but it's essentially a general purpose typescript function so here's a slightly more complex query that does an application level join against the user table now there's there's no need to read this it's quite hard to read a lot of code in a talk but this is straight from our documentation the point here is that you can write relatively complex complex queries if needed we've seen people pull in thousands of lines of library code when implementing their queries and then front and center of the convex unit developer experience are the client-facing libraries for interacting with convex this is where the application developer needs are met and there's a lot we can talk about here but the thing i want to focus on now is the power of subscriptions and component binding so what do these mean every query in convex is able to be used as a subscription you can think about it as automatic pub sub publish subscribe to arbitrary functions and we implement these subscriptions quite efficiently server-side by tracking the read sets for every query so every data the query every piece of data every range the query touches and we track the right sets for every mutation we invalidate a subscription if any of these read sets and write says intersect and and refresh the subscription to the user but the interesting thing from the client perspective is that the subscriptions can be bound to an application level ui component so let's talk about this binding this here is some code for react component that renders a chat window in a in a client-side ui the first thing you see here is this use query hook and what this tells convex to do is run the query list messages we're passing in a channel id and then anytime the result of this query changes so anytime a new message shows up automatically update the messages variable and re-render the component so the actual rendering part is at the bottom of the screen it just iterates over the last 10 messages here and displays them quite simple code but i can show you how this application works you type you know chat message in one window it shows up for all clients in the chat it's a pretty basic chat example but the key here is it's extremely simple to inc to implement and extremely simple to implement correctly it's actually the second demo in our documentation so subscriptions make developing dynamic applications a lot easier by themselves but by themselves they're not completely solving the problem of global state management because we can provide abstractions with strong consistency guarantees in isolation but then if the developer has to compose these abstractions together to you know to solve their their ui problems in ways that violate this consistency then our initial guarantees have been undermined so i'll expand on that with an example of two additional features of subscriptions that help convex fulfill the promise of global state management so the first is consistent client views so let's imagine you have a chat app with a user list in one ui component and a message list in another so if a message shows up from a user in the message window before the corresponding user profile shows up in the user list the experience is going to feel off or perhaps more seriously if we have a task management app where there's tasks in one ui component which contain foreign key relationships to projects in another this will actually break the client app if the application receives a task and then tries to look up a project that hasn't been received by the ui layer yet so it doesn't matter how consistent your database is if a client doesn't benefit from it if we don't solve this problem the application developer will have to do it themselves and it's actually quite hard so instead in convex all subscriptions across all components in a browser session are updated in an order that's consistent with a snapshot of a global database state state subscriptions are aggregated on a websocket and convex tracks the dependencies between them ensuring that any state the client sees reflects a snapshot of accurate data on the back end most developers probably won't notice this but the great thing is that they don't have to it just works the second feature is optimising updates this is the need to display updates locally before the server has been fully updated there's lots more to talk about here but it's not time to squeeze into into this 10 minute talk so take a look at our docs and we cover that there so ultimately though features like these combined to provide the abstraction of global state management to the end developer who ultimately is the person we should be building infrastructure for so that's convex it's our approach to taking a lot of distributed systems ideas and applying them to the problem of application level global state management there's a lot more going on in the platform so swing on over to convex.dev give us a spin and i'd love to hear what you think
Convex is the backend platform with everything you need to build your full-stack AI project. Cloud functions, a database, file storage, scheduling, workflow, vector search, and realtime updates fit together seamlessly.