Tools for a GraphQL application

Over the past few months, I’ve had the luxury of playing with and developing an app using a whole slew of technology. Nothing makes me happier than doing research to find a bunch of solutions and then writing some real life code to test the specific solutions I want to build my app on. It is a bit overwhelming, but each layer has an interesting mix of latest, sometimes bleeding edge tech. At the same time, it is also functional and stable, so the focus is on features and not fixing bugs.

I knew I needed a webapp, mobile (android and ios) and backend. Zero devops. I wanted to try GraphQL over REST (ended up with a bit of both anyway). I know I need aggregations, so it is postgres over a document store. I need login and authentication and firebase provides that… for free. The entire stack can be worked on by anyone involved, no specialized future hires, which limits the hiring pool.

webapp

Typescript - Javascript with a compiler and types!

React / Hooks / Context - Latest React philosophy is quite nice.

Jest + React Testing Library - Most important things!

Material-UI - Not just Material, it is a great platform for building component based apps.

React Final Form - Best form management tool I’ve found… because it is performant.

MUI-RFF - Form components that I wrote!

Navi Router - Great alternative to the standard fare.

Apollo React Client - A bit difficult to use, but works well enough

mobile

Flutter / Dart - Fascinating take on language and mobile compatibility

Provider State Pattern - Common state management pattern, done well.

flutter_test - Easy enough testing of components

backend

Typescript - Again, simply because it means I can use the same developers.

Firebase - Excellent platform with near zero costs and great documentation.

Firebase Auth - Security is hard, let someone else do it.

Firebase Cloud Functions with Node JS - Zero devops for the win.

Mikro-ORM (v3 is shaping up nicely) - Finally hibernate for JS/TS

Cloud Postgres SQL - $7/month to start and scales with growth

Apollo GraphQL Server - Experiment in GraphQL isn’t bad, but I’m not entirely convinced yet.

Type-GraphQL - Really makes using Apollo so much simpler.

GraphQL code generator - Let type safety work for you.

Thoughts, comments?


Jon Stevens picture

Thanks for the comments and feedback. I had a huge amount of churn (aka: changing tech and throwing away code) with this project because I was intentionally writing code to prove if it would work for me. There is also quite a few dependencies that I left out. Maybe I can publish my package.json next. =)

Let's start at the beginning. Apologies if this gets too long. I have had great success with AppEngine over the years and I've always wanted to use Firebase. In order to get a 'server' using Firebase, you are stuck with NodeJS and Cloud Functions, which dictates Typescript. Bare Javascript is a non-starter for me... I love a compiler and typesafety. I went with express for simplicity and also because I'm not going to be focused on the REST side since Apollo will do all the heavy api / routing lifting for me. Apollo has a very nice Cloud Functions integration.

I originally started out building the mobile app as a webapp and got very far along before I started testing on the device. Stupid me. That's when everything blew up. My app needs to use the camera as a qr code scanner and it turns out that on iOS only Safari can use the camera and it asks for permission every single time you use the camera. So, I decided to go native app, but since I wanted to run on Android and iOS, only cross platform choices...

I looked into React Native and quickly nixed it for a few reasons. While it is popular among all the kids, I have to admit that it has always felt like a kludge to me. It is trying too hard to bring the web to the phone and they are just two separate points. Having just been burned with a webapp, I kind of felt like there had to be another solution. I also wanted something with a great mobile component library already setup and ready to go. Then I remembered Flutter.

While I do have a good sense for design, I want to spend my time writing features and not components. Material gets me there the fastest and it is well supported in Flutter. I had always wanted to try Dart and this was a perfect entry point for it. Turns out that Dart is quite nice, well documented and super easy to pick up. Intellij support for it is excellent. I even submitted a few bug reports and got some nice improvements to the IDE. Flutter as a framework is easy to learn and get started with. Hot reload on the device is a killer feature as well. Use my provider pro-tip mentioned above for the best experience.

GraphQL is an experiment. I love the ability of putting the queries on the client side. It is complicated to get setup though. The tooling is getting better all the time, but it definitely isn't 100% yet.

The trick to making GraphQL really work is the code generation + typegraphql. I started off without using either of these and as soon as the code turned to spaghetti, I rewrote it using those tools. Makes all the difference in the world and now I'm quite happy. The entire schema is generated from typescript decorators and my model objects are both annotated with Mikro+TypeGraphql. Everything, including my queries, run through a parser / compiler, so I know that I'm not at risk of randomly breaking anything when I make changes. This removes the need for a lot of testing and makes passing data around super easy. The code generation also creates hooks for me.... so that is what I reference in my code. I looked into Relay, but I fear being at the whim of Facebook making changes or even just abandoning the project. It seemed over complicated for what I wanted to do. I did model my pagination on theirs.

I could probably write a whole book here...

Soumyajit Pathak picture

You could shape this comment itself into a follow up post in my opinion. Thanks for responding back with these much details so quickly.

I agree with the points you made about React Native. I shifted to Flutter for more or less the same reasons. Amazing Amazing Official Widgets Collection. Clear-cut options for state management and routing which still is a community effort in React Native (especially routing). Hot reloading works like a charm which is often not the case in React land. And Dart is a fine language.

One thing I would like to ask is what other ORMs did you try before settling on Mikro. I have tried others like Sequelize, TypeORM and Knex (a query builder) but not Mikro yet. Would love to hear if you have also tried the other options and your opinions about why you think Mikro is the one for you.

By the way, I encourage you to write the whole book in may be a series sort of way when you can. It can be a great community resource.

Thanks again for sharing.

Jon Stevens picture

You are probably right about another post. =)

I think that I tried them all! Or at least all of the top ones. Sequelize, TypeORM, Knex, Bookshelf and Objection.js.

I found Mikro out of a last bit of desperation because coming from Java/Hibernate land, all of the other ones just do not work as I would expect an ORM to work.

I cannot speak highly enough about Mikro, but I will say... you have to use the (stable) @next version 3. I have been working quite a bit with the developer to really make v3 awesome. He is super patient, excellent dev and wonderful to work with.

Mikro does something that none of the other (node) solutions do... it is based on Unit of Work. This allows Mikro to properly do ORM relations in a way that feels natural in the code.

Additionally, the TypeScript support is a first class citizen.

The next closest project is TypeORM, but it just falls over on edge cases that Mikro gets right the first time. Both TypeORM and Objection also have some serious bugs and huge long lists of stale stuff in their githubs. Sequelize is out of date. Mikro is based on top of Knex, but honestly... Knex has some major issues too. Bookshelf, is well, outdated.

I'm hoping that Mikro really blows up in popularity over time because it is definitely heads above the rest. Give it a try and let me know what you think.

Soumyajit Pathak picture

Great post detailing your preferred tech choices.

I have worked with most of the base technologies you mentioned (TS/JS, Dart with and without Flutter, GraphQL, etc.) and find the tech choices you have made quite interesting. Would love to see you expand on the "why" on a lot of those choices when you can.

One choice I really found interesting is why you chose Flutter and Dart for mobile and did not stick a solution from JS/TS ecosystem. Dart may be an easy language to pick up but it's still a difference ecosystem altogether.

I hope to read more about this from you.

Rhett Trickett picture

Nice! TypeScript is a good bet. No shortage of JS devs out there and there is something to be said for using the same language across the frontend and backend.

Any web frameworks like Express to handle routing logic etc? What are you planning to build with this?

I did an interview with the Co-founder of Mixcloud where he raved about GraphQL over REST, especially when used with Relay. Might be of interest.

Jon Stevens picture

Over a year later and I'm still using this setup. It has been mostly great.

My only realization is that I probably won't go with GraphQL again. The complexity doesn't outweigh the benefits. At the end of the day, REST is simpler and easier for this app. At some point, I'll migrate everything off of GraphQL.