You Are Not Your Code (2012)
sstephenson.us
sstephenson.us
If you replace 100 lines of my code with 500 lines of buzzword-driven development that is 50% copied off of Stackoverflow, we're going to have a discussion.
if( $_GET["foo"] == "bar" ) {
//add_action( 'wp_loaded', 'do_foo' );
//add_action( 'init', 'do_foo' );
//add_action( 'admin_init', 'do_foo' );
do_foo();
}
which allowed easy launching of do_foo() by simply httping http://wordpress.tld/?foor=barto
add_action('rest_api_init', 'Company\PluginName\setup_foo_route');
and namespace Company\PluginName;
function setup_foo_route()
{
register_rest_route(
'company/v1',
'bar',
array(
'methods' => 'GET',
'callback' => 'Company\PluginName\do_foo',
)
);
}
which can be run by httping http://wordpress.tld/?rest_route=/company/barWhich one of us would like to talk to :) ?
What I noticed is that people following the first method ends up hacking core functionalities of WP because "it just works" but in the end that makes the code unstable and harder to maintain because it relies on undocumented stuff and a coding style that is very personal. It can also messes big time with stable things expected from the CMS (mangled taxonomies, hijacked hooks in the core instead of the WP pile that make it hard to debug or to play nice with other plugins/themes).
If I'm doing anything that actually requires sane PHP primitives (like the routing in your above example, and also notably DB) I steer clear from WordPress entirely. WordPress is a good CMS and makes for a great blogging platform but I have done my best to decouple any-and-all custom application development to it's own API.
WordPress and it's core simply don't offer good tools, and it's a VERY highly targeted platform in regards to security. I would suggest Symfony or Laravel for PHP frameworks that do APIs very well; or even AltoRouter + vanilla PHP for super light-weight stuff where you want minimal dependencies. Personally I think Laravel is the easiest, and a joy to learn.
Otherwise - kudos on ripping it out and replacing it with cleaner code!
I admit I am a bit nervous in regard to opening WP with REST endpoints considering its reputation.
A lot of people will frown on my advice to pull in the primitives from WP and/or directly tie-in to the existing database. People have an "all-or-nothing" approach to WP/application development and will push you to do things 100% in one tool or another... sometimes this is a great decision, many times it is not.
The truth is, WordPress is a great CMS with backwards compatibility that is astounding... but to maintain that backwards compatibility it has to hold itself back. When I have to work on WordPress sites (way less often by choice) I find the APIs and ergonomics to be horrid and regressive, as-if I was still stuck programming for PHP 5.x.
The downside of what I'm pushing: you have one more codebase to manage/deploy/update/document/etc. For me, that's no big deal. I have an established GitLab pipeline for smooth deployments of WordPress and Laravel codebases alike.
Effectively I've designed my engineering projects/teams around "spinning off a microservice when needed"; but I also work on very large-scale applications. One more thing that keeps this manageable is hella-good documentation _IN THE REPOS_ that link to sibling codebases + describes every significant integration. (WP + Laravel via HTTP API and DB tie-in)
Same goes with the API docs - even if internal, and even if for 1-2 routes: Ensure every potential HTTP request/method/URI is documented and kept up-to-date. I rely on Postman for this so I also get actual tooling along with my docs!
Keep fighting the good fight =)
Likely[1], the intent is almost to treat Wordpress as one component (dependency) of your application. Remove all business logic that's held directly in its tables and code, and instead add layer from Symphony/Laravel/Framework-Goes-Here which "syncs/pushes/writes" to Wordpress. Wordpress becomes just a "piece" of your application instead of your application. Wordpress is just the CMS for your business logic (application), not the application itself :)
It'll reduce the surface area of attacks because you fucks with wordpress internals less. It'll make upgrades easier because you fucks with wordpress internals less, and it'll generally make life easier down the road because you need to fucks with wordpress internals less.
Just my two cents :)
[1] Because what they outlined is like spot on with what I'd be doing... I think nervous laugh -_-;
Nailed it. 100%
WordPress gets pushed WAY too far and treating it more as a component/dep of your application is a perfect way of describing how I go about my work (stealing that explanation). When I start see people jacking into the REST API and the like I feel like that's "too far". However, in OP's defense, I have done exactly what he's showing myself and 100% understand the need with the right constraints!
I often push my clients to decouple anything that can be described as "application-specific" or "business logic" ASAP for MANY reasons - security, better dev tooling, scaling, not relying on an EAV DB design under the hood, etc. Usually it's a <5 table CRUD application that can be described in 10-20 API routes... Even if you need an authentication system thrown in there Laravel eats that for breakfast. Way easier to scale, I have better control over the DB schema, I get "nice-to-haves" if I want them (ORM, input validation, DB migrations/seeds), I can trust it, etc etc.
Also - when you use something like Laravel/Symfony you can totally tie into WordPress primitives, or even just point at the same DB as WP (you kinda touch on this). Some people may really look down on that - I see it just as any other integration. When done thoughtfully and WITH DOCUMENTATION it is 100% fine to "join the worlds" like that IMO. Ultimately, you get a LOT more flexibility when you pull in a tool and decouple a bit from WordPress which is why I'm getting all preachy.
I feel responsible PHP devs should program very carefully, and/or use opinionated tools that are thoroughly vetted and well designed (like Symfony and Laravel). WordPress, it's core, it's team, and it's plugins are the antitheses of that last sentence! But for many it's a necessary evil as it still is the most popular/developed-for "host-your-own CMS" solution.
Thanks for backing me up - that comment could have really backfired with the HN audience. Cheers!
Its hard because while we do recognize that the value and difficulty is in the problem-understanding, the code is the most tangible thing we produce and so it feels like the work.
In every shop I work at, I do ask WHY someone refactored something I have done. However, I do not do so with any malice.
As you point out above, sometimes, that first writeup is a working implementation, and while important, the first iteration is often not optimal.
Thus, asking why is useful because it helps us become better developers. Talking about the changes helps share knowledge, and, yes, when questionable changes are made, it can be a lesson for the refactor-er as well.
And when I am the refactor-er... I will try to explain my changes in the PR. Usually with a polite explanation of why I refactored.
I also find this very interesting. Many codebases decline in usage by not being actively developed. Other times, changing the way things are done goes against the core and is better off leaving it alone, and developing anew. Of course this is only clearly visible in retrospect. I'm generally against adapting to trends and wonder why perfectly complete and functioning frameworks need to be actively developed. This is why--we want to know that the framework will change with the users.
The second part of the trend to prefer modular libraries, I think was transitional as there was no one framework that had the best of breed components and using individual libraries produced a better ad-hoc framework. Now we have something in-between with coherent frameworks but still having replaceable parts.
I first used it to reduced the number of calls to my server by showing/hiding sections of a form and that made my apps way easier to use and much faster for the end user.
It was a little clunky (for me) to implement but it worked with most of the web browsers at the time and that made those features available across platforms. That was huge for me. I replaced it with jQuery later on and still use jQuery.
I have to credit Sam Stephenson with showing us (or at least me) the way towards full blown client side web apps. My latest version of that same app runs entirely in the user's web browser on or offline. Prototype was the first stepping stone I stood on to get here.
If someone goes about it the right way, the wrong decision in hindsight will feel right at the moment in time. Human matters oftentimes require a delicate touch, something that not many of us deeply involved in software pay attention to :)
This applies in dealing with others but perhaps even more so in dealing with yourself. If you don't tie your self worth to the work that you do, when the tides of time make your work irrelevant, it won't be so painful.