This all began after reading this article which questions the usage of single-page applications (SPAs) and APIs for the modern web:
Second-guessing the modern web
The emerging norm for web development is to build a React single-page application, with server rendering. The two key…
Read that 👆🏾 (and a popular response), if you want.
As I read, I realized that writing APIs for SPAs isn’t very fun. Like when I need five or more API endpoints on the backend with all their associated actions and mutations for state management on the frontend—all for just one page!
Is there a simpler way? This the problem I’d like to solve…
My Thought Process
In its most basic form, a website only has two parts: 1) something to store/retrieve data (server-side) and 2) the interface to interact with/view that data (client-side).
It would be nice if…
1. the view always had the data it needed and we didn’t need to think about fetching that data—it was just always there, ready to use
2. there was only one place to do all our routing (as opposed to writing the API routing on the server and all the SPA routing on the client).
3. [and my personal preference] I could use Laravel for the backend and VueJS (more specifically, a vue-cli project) on the frontend.
But why not just Laravel?
Firstly—and maybe I’m in the minority—but I personally prefer vue-cli over Laravel Mix (a lot). The biggest reason is that because you’re loading from a server on each page load/refresh with Laravel Mix, it just feels too slow to me for local development. (First-world problems, right?)
Secondly, I want to build a SPA.
But what about Livewire?
Using livewire would still not be a SPA, and for the more complicated interactions, you’ll still need to bring in some advanced JS anyways.
I’d rather have all the frontend in VueJS and all the backend in Laravel (and without REST API) — which is really the whole point of this post… let me just get to it already!
Introducing the “Soppy App”
A “Soppy App” keeps your view hydrated with all the data it needs—without all the hassle of managing server-side APIs and client-side states.
Disclaimer: I’d like to think that this type of setup is best for mid-range websites or Progressive Web-Apps (PWAs)—maybe not the best for simple sites that don’t use a server much. And it’s definitely more for those who want to work with Laravel and VueJS. AND this is more of beta testing stage than full-blown production-ready. Proceed at your own risk—or opportunity… whichever way you see it ;)
How It Works
- Every route is written in Laravel but also generates a
routes.jsonfile (with an artisan command) for the Vue app to use.
- Every route returns its data in the app’s view or in a JSON depending on the request (see the code). This way, when you load the page initially, it has all the data, but also, when you navigate to the page in a SPA, it gets all its data via JSON—both through the same URL. Just send the data you need.
- The vue-soppy package works with vue-router and vuex to get (and even preload) each page’s data behind the scenes. You may want to write some getters, but you won’t need to write any actions or mutations—just use the data you need.
- You get a SPA with all the vue-cli project benefits.
- You get all the bootstrapping backend power with Laravel.
- You write your routing once in one place.
- You send just the data you need for each page.
- You get all the data you need on the frontend without having to write an action, AJAX request, and mutation for every model.
- I’m not 100% sure, but I doubt this approach would work well for an app where ALL the interaction of the app takes place on one page.
- … I’m sure there are more maybe. I just haven’t discovered them, yet.
Let me know what you think!