The perfect environment
I started programming in the early 2000s when CMS systems like Typo3 and WordPress just made attempts to be frameworks. And while I progressed I started to understand that there is a constant tension between providing unrestricted possibilities and fast output. Over time, while attempts like Ruby in Rails showed potential but never crossed the line of being true all-purpose solutions, I saw more and more experienced developers splitting into fractions of "no framework at all" and advancing open-source systems to capture the needs of the edge cases.
This tension traverses into patterns where OOP and functional programming tell a similar story. Therefore, it has always been an ongoing Side-Project for me to work on the ideal framework. And after over a decade, neoan3 has become quite close. This is the story of utilizing an installation script to scaffold a modern setup: VueJs, Tailwind and an API wrapper (using axios) capabilities for the front-end and the neoan3 REST pattern for backend needs.
Opinionated vs. Abstraction
It's always the same battle: ease of use and rapid development or unhindered possibilities? Whenever I build something with reusability in mind, I find myself in this very 🐇 hole. And sure enough, I always end up either being boxed in or not having accounted for something.
You all know the scenario: you basically rebuild 80% of the same stuff over and over again. Yes, there is stuff you can copy and paste but you simply can't reuse that component you where so proud of because the CSS-framework simply doesn't play nice.
neoan3 and repos
Neoan3 is designed for such scenarios. You either pull in an existing component via the cli or publish a component to it's own repo. As long as we are on the backend, the out-of-the-box dependency logic is fine, but what about coupled front-end components?
Well, vast-n3 extends the functionality and enables bundling front-end components to required backend functionality, including models and database transactions.
So it has strong opinions and is highly monolithic?
Yes and no. The project bundles Vue, Tailwind, Stateless JWT and neoan3 into a performant system using a variety of simplifications like the provided axios wrapper that understands authentication and behavior of neoan3. Additionally, complete components like login are provided. BUT: nothing is written in stone. There is nothing you can't touch and the way responsibility works means you can modify even the most basic behavior. Whether it is markup and/or design, API endpoints or model-structure - everything is fair game. Won't that break everything? Let's find out!
Installation
I will assume that you have PHP and MySQL (or mariaDB) installed as well as node, npm and composer. The installation will not work without these prerequisites. Also, make sure you have set up composer to be able to make authenticated calls as we will be adding repos that aren't available in packagist (yet).
If you haven't set this up, go to https://github.com/settings/tokens and generate a token and then run
composer config -g github-oauth.github.com YOUR-TOKEN
Instead of the built-in PHP server, I prefer the good ol' Apache. Using Ubuntu, this leaves me with a web-root on "var/www/html".
NOTE: On Windows, the easiest solution is installing XAMPP, which ships with Apache, PHP, MySQL ( as well as PHPMyAdmin, Perl, etc.), normally resulting in a web-root at "C:\xampp\htdocs"
After creating a project folder and navigating into it, I can run
neoan3 new app MY-PROJECT-FOLDER
To see if this worked, I open a browser and go to localhost/MY-PROJECT-FOLDER.
You should see the neoan3 demo output.
Then, we run
neoan3 install https://neoan3.us/vast-n3/master/
This downloads and executes the installation script.
Assuming all went well, we now run
php setup.php
to let a script guide us through database setup and credentials.
We are now set up. However, in order to run our application locally, we want all migrations to be executed. So we end our setup with
neoan3 migrate models up
That's it. You should now be able to refresh your browser and and see the vast-n3 welcome page.
Now what?
The installed models, components and frame are all their own repo. The recommended way of working with existing repos is to
Create a GitHub organization for your project
Change the upstream for components you make changes to and/or
Publish new components to this organization (the cli tool will help you with the publish command)
creating new components
Running neoan3 new component testMe
will ask you to chose between type of components. Due to the templates we provided, choosing "custom element" will generate a new Vue component.
In order to use your component on a particular route (let's say "/introduction", open "/component/introduction/introduction.ctrl.php" and add "testMe" to the array "vueComponents"
You can now use your component in "/component/introduction/introduction.view.html". In order to ensure availability in a component template, add your component to the function "dependencies" of the inheriting component's PHP controller.
What are these $params there?
Since we are serving the app via PHP, we have the possibility to render variables (or anything, really) into otherwise static JS & HTML. This is particularly useful when having either dynamic requirements or if we e.g. want to pass in info we don't want to be static (like public keys for APIs) in order to be reusable. In the component files (JS & template HTMLs), we can access these parameters with double curly braces. Keep in mind that these values will be rendered to the DOM, so security has to be considered.
What about the API?
You have a globally available object "api", which you can use for calls against the backend. To do so, simply call the required method:
api.get('introduction').then(jsonResult => {
// your code
});
This will generate a GET-call to the function "getIntroduction" in "component/introduction/introduction.ctrl.php". Note: this function dies not exist, you will have to write it
On the backend, you can simply answer with an array. The conversion to json will be done by the neoan3 API. You can use the static functions of Stateless:: to control access and use the built-in RouteExeption for custom header returns and rejections.
About routes
As you might have noticed, we aren't using neoan3 as a pure API but rather serve through it. While you can implement routing via Vue, the advantage of routing server-side is to produce a very scalable basis. There is almost no limit of application size. As such, we added templates that create easy starting points when creating route components (again with neoan3 new component
).
What's next?
As you might have noticed, this project is still in its early stages and requires some knowledge to get the intended benefit out of it. However, we are inviting people to provide feedback and are hoping for contributions.
Top comments (0)