I started working on this many years ago at this point trying to build the backend with Java/event sourcing[0] and the frontend as an SPA React app. I took the unfortunate/fortunate approach of building a webpage first[1]. I learned a lot from this experience and the result was something that worked okay but was terribly inflexible and difficult to work with. (The other problem was that it was an email service, but that's a whole other matter).
I realized that if I wanted people to use this, I needed to have mobile apps and I needed to have a server-rendered frontend, at least the public facing pages. So for my second attempt (which is what you see here, a standalone messaging platform), I did the right thing and transitioned to Postgres/Hasura for the backend (with a NodeJS-based API that fills it out). On the front-end, for the web, I transitioned to NextJS which is wonderful. Eventually I transitioned entirely to TypeScript, and my stack if entirely typed from DB schema to UI. It's just great. I was able to do something like transition serial int identifiers to UUIDs in two hours without introducing a single bug anywhere in the stack.
Since I had started with a webapp, I was able to build the mobile apps out of the same frontend codebase by wrapping the core of the webapp in an SPA that is delivered with Capacitor, which is also pretty excellent. Building a nice mobile experience with web technologies proved very difficult, but I think I did a pretty good job with it. But it is really, really nice having one, single codebase for the web and mobile.
In addition to the tools I've already mentioned, I'd like to make a couple shoutouts to these indispensable libraries and the people behind them:
- ProseMirror — a rich text editor. Thank you Marijn!
- Framer Motion — an animation library for React. Thank you Matt!
- Apollo Client — a JavaScript GraphQL client. Not as robust as Relay in some ways, but actually better in my opinion (having spent a lot of time with Relay). Thank you Ben and the entire team!
(You can get a complete list of frontend libraries by clicking "Credits" in the footer on the homepage or in the menu inside the app.)
Edit:
I almost forgot: the backend is running on GKE. Kubernetes hosted by other people is a wonderful thing! This morning I woke up, ran:
gcloud container clusters resize cluster1 --node-pool default-pool --num-nodes 3
Tweaked some resource requirements in my a couple YAML files, ran helm upgrade prod .
And here we are! There was a post on here the other day about how the hermit developer is dead but that post was very wrong, and I am living proof :). One person can do so much in 2021 with all the tools we have. (That said, I would love to work with other people on this.)This is probably a dumb question because I don't have much experience with GraphQL, but how important is GraphQL to your project?
For example, if your client makes the same dozen or so queries day-after-day, would it ever make sense to use that knowledge to write a more static API? There seems to be a lot of text parsing and object serialization and deserialization with GraphQL and it makes me wonder if something more RESTy would be more efficient?
Is computer time and space too inexpensive to worry about these things?
I like GraphQL because it aligns with how I think about frontend queries and data. I had spent a bunch of time with technologies like HATEOS that standardize sorta-similar REST-based approaches, but as soon as I saw GraphQL, in my mind it was immediately like: "THIS! This is it." There's just something about it for me. I can't say that that GraphQL is _important_ technologically, I'm sure I could have done it some other way, but it definitely is what has felt the most right of all other things I've tried, and I think that's really important. The front-end clients for GraphQL are also awesome. I've tried Relay and Apollo, and both are excellent. They normalize everything and provide reactive updates when something changes.
> For example, if your client makes the same dozen or so queries day-after-day, would it ever make sense to use that knowledge to write a more static API?
Hasura lets you turn GraphQL queries in REST endpoints! It's pretty amazing. But GraphQL also has this thing called "persisted queries" where instead of sending the queries every time that needs to be parsed, you send a hash for the queries, and the server already knows what the query is and has its representation stored in memory so it can satisfying it w/ the parse step. I can only hope to have to optimize like this :).
> Is computer time and space too inexpensive to worry about these things?
I don't think so... I've just been trying to ship without prematurely optimizing. It's been somewhat of a journey as it is :).
And by the way, in 2021, I wouldn't write a GraphQL backend by hand. I think a tool like Hasura/Postgraphile is the way to go. They put up excellent scaffolds that you can augment. In addition Hasura (I don't know about other tools) provides an access control layer that is really nice as well.
That says authorization should not be in the resolver but putting it elsewhere often resulted in much more complicated code. It makes sense if GraphQL is coexisting with REST or other end points because they could all share the same authentication code, but for pure GraphQL projects it seems arbitrary.