This is my first post in the Elixir forum and I’m excited to have started learning Elixir/Phoenix to date.
My question is related to an application I’m planning to build and what others thoughts would be regarding the stack I’m trying to incorporate.
Frontend - React
Mobile - React Native
API - GraphQL
Backend - Phoenix
Database - PostgreSQL
I’ve seen through the forum people discussion ReasonML, ReactReason, Live View and various other suggestions. Would love to hear peoples opinion why current stack wouldn’t be a good idea, why include other ones etc. I know with a MVP it doesn’t matter too much in a stack but I would live to consider different options as I’m learning and building.
A little about the application:
I was considering making an application similar to Instagram if I were to give an existing example. It’ll be accessible not only through Mobile but also on the Web.
A little about myself:
I’ve started on this journey of programming after taking a boot camp which taught React/Rails almost 2 years ago. I officially got my first job about 4 months ago as a Full-stack developer in React/PHP but would like to build a personal project in my free time. After looking around and considering between NodeJS/Phoenix, I’ve decided to go with Pheonix and have been reading Programming Phoenix book (close to finishing the newer version).
SPA: In 99,5% of projects, a Single Page Application is not needed. Server rendered HTML with drop-in JS components (Vue/React/Angular) for interactive parts is much more user friendly and less complicated. One of our clients has rebuilt their web UI as a VueJs SPA and 90% of their content is static (fetched from API and shown in a table). That project has the maximum possible complexity.
Remember: You have to redo quite some things that also needs to be done on the Server/API side, e.g. routing, state management, authentication, permissions, etc.
Mobile App: I’ve worked with ReactNative in the past and now I am working on a Cordova app with VueJS. I just don’t like it. The apps don’t look like they belong to the platform (style guide, etc.), they don’t feel like native apps and quite some things are much harder to build and some are almost impossible. For our current project, I will probably rebuild the whole App in Kotlin for Android as soon as the client gives the permission to do so. For an Instagram like app, it might work, but lets be honest, the original Instagram app is one of the worst I’ve ever seen. I doubt it’s a native one, but if it is, they screwed it up.
Just my two cents and some personal experience. If you can, avoid the SPA for the web UI. And if you feel comfortable with ReactNative and the platform (React) isn’t in your way or causes you trouble, go with it and try it out.
Thank you for replying and sharing your experience/opinion regarding the flow I’m considering of taking with this application.
I do have to agree with the mobile portion. My original thought was to implement the application in Swift (IOS) but the depth of catch up I’ll need to do in order to start implementing made me reconsider it. That is a reason why React Native came into play for the initial application creation since its similar to React causing less of a learning curve although it does have a lot of limitation from what I’ve heard.
I’ll be considering your advice as I finalize how I’ll approach this application for the web UI.
I think these are all reasonable choices. You didn’t tell us anything about what you plan to build or who your users are. Personally I’d try really hard to deliver a mobile experience through the web with a responsive framework and only go native if absolutely required. If you want a mobile app for marketing reasons there is always Cordova.
Aside from games and similar specialized experiences Flutter is going to be a huge step back for web development for several years yet. Since it totally disregards the DOM, you get none of the features of the browser which means accessibility, copy paste, drag-drop etc do not work. Think of it more like a flash replacement for now.
My team has used similar stack for almost 2 years. Recently, we are thinking of removing with GraphQL. The reasons are:
The biggest benefit that GraphQL gave for the frontend is React Apollo where state management is handled by Apollo store. This means we do not have to use Redux for state management. However, with React hooks and context, we think this benefit might not be as great as hooks/context is a good alternative to Redux.
For doing something that is very simple (such as adding one column), we have to maintain Ecto model, GraphQL schema, React queries. Given that we are all full stack, it become rather tiring and repetitive after some time.
One benefit of GraphQL is giving the frontend the control of what data to request. This benefit make sense when you are designing open API, for e.g. Github. But our team maintain both frontend and backend, so this benefit is non-existent.
Not really a strong reason, but one of the feedback given by our juniors is this tech stack is very difficult to pick up. These juniors often are only familiar with Ruby on Rails with jQuery. They have to pick up Elixir/Phoenix, React, and GraphQL in order to be productive. This can be pretty demoralizing for them. Personally, I join the team when we are using Rails, GraphQL and React. So still not so bad as I have Rails background.
My personal opinion is until we feel that we need GraphQL, we should first implement RESTful API for backend. In fact, I am also thinking of going back to standard Phoenix with eex instead of using SPA as the complexity is not worth the effort.
We have not made the final decision yet. But I would like to ask how’s the experience of everyone implementing this tech stack, and any comments on the above points?
GraphQL over rest has better network traffic handling, fewer requests, more efficient queries, etc… etc… You can even use it ‘as’ a REST style endpoint but still better all around. I’d never opt for REST over GraphQL. Even when not designing for an open API it still lets you make backwards compatible changes far far easier than REST so those changes don’t infect and require changes to ever call that access it elsewhere as well.
Your stack is fine. I personally went with Vue.js instead of react, because of the single-file component stuff and not wanting to learn JSX on top of everything. That’s not even a very strong reason, but it’s working for me. Note that in my case, an SPA is fully justified. Others will point out reasons not to use an SPA, which is also a fine decision for many projects.
On my current project we decided near the inception, not to use GraphQL and we used REST endpoints for everything to reduce the number of new things we were juggling. In retrospect I think we should have used GraphQL queries for reading data. We keep making mistakes like loading the same data twice in the client, which is sometimes very hard to avoid when the composition of components may change from page to page. We use Vue.js instead of React but its the exact same issues either way. We also keep writing these awkward rest endpoints with variable query params, and I feel like we are creating some ad-hoc query endpoint language. Or we have endpoint names that are basically just resolvers to ‘run the query in def get_all_these_things_joined_with_those_things_with_these_collections_loaded and get me all the results’. I admit I have not used GraphQL in anger but I think it offers a better way to solve for this kind of thing and at some point we’re going to be using it anyway.
As far as SPA vs EEX app I think this depends on what you are building. For a modern full function application that people use all day long to do their job, I think they will be more productive and happier in an SPA app. My current project was started by a consultancy as a Phoenix HTML app and we converted to Vue.js SPA after a few months as we just were not happy with the user expeirence we were delivering, and we had all kinds of ad-hoc state management happening in callbacks scattered throughout the DOM. Its more work to develop an SPA but I think its actually more straight-forward and easy to reason about than the alternatives if you need an interactive client experience.
You might consider moving away from REST dogma and using task-specific endpoints that only take the parameters that are actually relevant. REST was designed as, and is great for, an API base that provides complete access for clients. But note the word base; there’s no good reason IMO to not move past it for your own client, while of course implementing it (if needed) for external access API.
It is not REST dogma that is painful as we don’t subscribe to that. It is rather that our choices are a separate endpoint for every query, or ever growing params provided to each endpoint. GraphQL solves the issue in a more structured/general way, and it also solves the issue of multiple consumers requesting the same data.
Sorry, from your tone, if I’m reading it right, you thought I was criticizing your project. That was not my intent. My comment was about how a particular good idea has been misapplied and over-emphasized until it’s as destructive as it is helpful, and meant as a suggestion to be sure you’re not misled by that–which it seems you are not.
As for GraphQL, I look at it this way: with it you have to build a lot of different queries. If control of both front and back end are with the same small number of people, it offers very little advantage over just giving each query an endpoint and implementing the query on the backend. When you have a larger group where front and back end are worked on by different people, then allowing the front end a degree of independence from back end support for each query, can be a really big advantage. And of course, this applies even more strongly when you want to support front ends developed outside your organization.