Important: this article is of older date. The frameworks and libraries might be outdated, but the process is applicable to any scenario.
Are you:
- a new customer curious about our approach to web application development?
- a webdesign agency looking for reliable php development outsourcing?
- a web developer in search for a perfect job?
This article is right for you.
First, you will learn how we got there. Our history is not a perfect straight line from A to B. It's more about trying different approaches and choosing the best of them. We'll address the primary question:
What are the key components of a good application development strategy?
Following that, you can obtain detailed insights about components and technologies we use today. In short: Let's talk about the Why, the How and the What.
Check out our web applications services!
How We Got There
We started our journey with a lot of enthusiasm and energy. There was, however, a lack of developer discipline and know-how. At first, everything was just fine and we delivered results. But right from the start, concerns started to emerge. Our applications were cumbersome, generating a great load of work on any modifications required later in the development, performing poorly in terms of scalability. This brought about a lot of man-days wasted by inefficient tuning, rewriting and experimenting.
Originally, we approached our apps the way we were used to, i.e. as an integral part of our CMS built in PHP. We had already created successful website development strategy with custom CMS for rapid web development, called 3OS, and it worked like magic for most of the web-related scenarios we found ourselves in. Having a CMS that gets a website live in little or no time is a great advantage. But how does this apply to web application development? Is the "rapid" and "simple" a solid development strategy?
As it turned out, it was not. 3OS simply could not cope. Web development strategy differed vastly to any app development strategy we've seen deployed over the time. It could not react to a growing number of demands, requests for modifications, and it could not deliver the level of security and efficiency we were hoping for. Sure, you could develop a simple intranet solution as an add-on to your CMS in no time, as we still do today. But since you focus on making a web application from the start, you'll soon realize that the CMS part is quite irrelevant in your project. It's the parts that are missing that make all the difference.
We first touched pro-level a year later, when we agreed with the client to go with the Zend framework. The tools of the trade changed. The first major change was a very strict use of repository (namely Git) in the workflow with the Git Flow scheme, having multiple developers working cooperatively. We learned a lot about deployment and testing. The client was a development company with a long tradition, and thanks to this fact we have adapted a lot of practices and tips from their experience.
The front-end development was a huge problem. As Zend is primarily a back-end solution, we had a wide-open space in dynamic scripting on the client side, leading to many bad choices such as a very wild development of many components, jQuery plugins, methods and functions. Lacking the required JavaScript professionalism, this created a lot of troubling issues with accessibility, code maintenance and management of modifications. But the Zend way changed us for the better dramatically.
Somewhere in the middle of this particular project, a need emerged to develop a very distinct application targeted at the specific task of energy consumption measurements and analysis. We chose a totally different path with Ruby on Rails. It was a first non-PHP project at Kurzor and it was a wild one, indeed. On one hand, Ruby on Rails had a very profound way of solving common web application development tasks. The approach could be described as "you can do it any way you want, but this is the right one". It had two major characteristics:
- As a beginner, you are forced to proceed properly to avoid stupid mistakes that are going to cost you in the long run. A big advantage indeed.
- Complex problems were much more difficult to resolve, and problem areas such as poor performance were very hard to address. The application was delivered later than expected, but with proper tests, a relatively good code maintainability, and the more than welcome adaptability to modifications. It still shows today in a situation where a diverse team of people works on it to extend and improve various areas. An obvious disadvantage.
The big question is: Would I recommend trying Ruby on Rails today? The answer is simply no. It has a lot of advantages, but clearly one big disadvantage: it is much harder to find a pro RoR developer than an experienced PHP one, and he or she will cost you a great deal of extra money. What I would recommend to any web developer, however, is to try RoR development at least once in your life. It clearly shows you the proper ways to develop a web application. In other words, once you experience the benefits of well defined procedures, you will never want to do things differently and, most importantly, worse.
On our path to perfect strategy, we made one last mis-step and tried to implement our workflow based on CakePHP. I liked the similarity with Ruby on Rails, the fact that it's in PHP and it's easy to grasp and well documented. But our search for a motivated and experienced CakePHP programmer came to no avail. Also, it became clear to us in 2013 that we needed to address how the world was evolving - heavy AJAX-based applications and REST APIs. It is very helpful from the user experience perspective if the app is as dynamic and responsive as possible. And simple interfaces like REST make the back-end serve the same content for multiple endpoints.
So clearly, sometime in that period, it became clear we needed to focus on a set of approaches, rather than a specific server-based framework. It became clear we needed a strategy.
Strategy: The Necessary Elements
Most importantly, a clear thought process needs to be in place at the start of every step:
- Knowing why each feature is important to the client, and the rationale behind it.
- Being able to analyse the thing as a whole and come up with a solution employing the best of the system setup we have, or introducing new ones at a reasonable cost.
Analysis is the single most important step in any application development and it is more than required in web apps. If you feel that something might not work, don't keep it to yourself. Communicate with the client, come up with solutions.
Security – a huge potential issue not only for PHP development. There are thousands of ways even a teenage hacker can bring your business to its knees: hacking, stealing information or identity, manipulating data... These are often solution- and platform-independent. It should be the number one priority for any development team to think securely, to imagine the worst, to beef up the system with a bunch of features that do not visibly screw up user experience, but put a clear stop to any kind of external threat. Example: using of blowfish hash to securely store passwords is practically making a "brute force" password attack impossible, yet the typical user does not notice.
Performance – most importantly, web application should respond immediately, not after looooong page reloads. But there is more... Ever had thousands of entries to work with? Any solution should be scalable and allow a simple future optimization for this kind of data increase. It all starts on the back-end with the chosen storage, and more importantly with giving enough thought to the model in advance. Also, time-consuming tasks on the server, such as document generation or mass e-mail sending, should be queued and processed in parallel if possible, without many inter-dependencies.
Efficiency – any web application should have a rich set of tools that allows alterations in many ways. It should be relatively simple to introduce any kind of modification, small or big. Nobody knows what the app will look like at the beginning, so deal with it. Live with agile planning. Tests should not be taken as a cool thing we do if we have the time, they should be integral part of our effort, and TDD (test-driven-development) should be used wherever possible.
Web Apps Redefined: The Back-end
The core question should be: Which framework? We give a simple response: A slim one! Precisely, Slim Framework. Built in PHP with very good standards in place, this is a minimalist venture with only a fraction of responsibilities of a typical framework of today. Dependency Injection principles and Service Locator pattern easily allow to fit in foreign components, such as authentication (ACL) borrowed from Zend Framework. It's perfect for our goal, making an impressively fast and reliable REST JSON-based engine.
Why REST is obvious - we need the simplest possible way of managing our back-end communication. The one with the fewest questions, which in turn will be the most standardized one today. Perfect for AJAX-based apps. And a quick way of adding future different endpoints to our REST API. Do you plan a mobile app? Let's connect it. Are your customers looking for a way to fetch information from your app to their website? Give it to them.
Let's go under the hood: How do we deal with data? Storage engine is MySQL-based and operated by Doctrine. We feel that today, as application data are represented by sets of entities, typing our queries by hand is neither effective nor required in most cases. We start by Doctrine models and go even further, fully exploiting Doctrine Repositories for advanced data retrieval. Doctrine is one of the most advanced database layers for PHP today, and after extending it with custom data types, what we have is a rock-solid application foundation. The engine also allows speed optimization on critical parts.
As for server-based workload, we have a custom-built queue with plenty of advantages, allowing tasks to be performed whenever the server is ready. Example of tasks we tried are: E-mails with HTML templates based on phpmailer class implementation. Or PDF document generation using wkhtmltopdf ideal for invoices of any kind.
The back-end would be incomplete without tools. Automated testing is number one. This one is always a tricky one in PHP, as it requires customizing the PHPUnit and making custom classes as a base for application-relevant components. But once all that has been implemented, it just works! PHPUnit can be integrated in a number of advanced IDE's, such as PHPStorm. This helps make tests simple and accessible, the first rule of thumb if we need to test frequently and anywhere. The excellent mailtrap.io service is used to review sent e-mails in depth.
Final tools are all about component management and deployment. For components, the Composer is a must without much explaining. For deployment, we use Phing with targets. A lot of effort was put into adding new tasks simply. Therefore a new app should be prepared to be plugged in online to a number of target domains in a consistent and reliable way, and to run a number of tasks such as database restoring or updating.
The final mix of ingredients proves to be a secure, performance-wise and extensible set of technologies. Perfectly suitable for our web application development strategy.
Let's Go Live: The Front-end
A front-end question always begins with the letter J: How do we deal with JavaScript? A miraculous language with a lot of expressivity, JavaScript got a fitting nickname: the world's most misunderstood language. It can be used simply, in a profoundly stupid way, and dangerously, yet it's most performing when it exploits its philosophy to the core. And in our strategy, we do not want JavaScript to be a cosmetic add-on, we want the whole thing to be built by it.
That's the reason we decided to switch to AngularJS. As powerful as our back-end seems, it would be nothing without a well-fitting client-side environment. A super heroic one, to be exact. AngularJS inspired us through many factors:
- well-thought basic ideas,
- openness and communication of the development team,
- quite a good readability
- emphasis on proper JavaScript usage patterns.
Also, having Google on your side feels good for the future development. Hence, our apps are divided into single-page segments completely powered by AngularJS engine for routes, templating, dynamic actions, and back-end communication.
When it comes to the looks, we use LESS syntax instead of plain CSS to provide algorithmic support into the styles. We've used LESS since 2010 as an integral part of our combined efforts, so it was easy to continue with it. We've had great experience with Twitter's Bootstrap framework and practically adopted and easily modified it for our purposes and client demands.
We noticed that the gap between bleeding edge technologies and technologies actually used in production greatly shrinks if approached correctly. You can, therefore, expect a lot of live behaviour from our apps, manifested by CSS animations, responsiveness of tools like form validation, and using new UI patterns to solve old problems. Since it's much less of a pain to setup a, say, dropdown menu with autocomplete and server-results, we can use them much more often.
The ease of testing is one of the most important aspects of developing an application with AngularJS. Any written component can be isolated and tested easily, just like when an engineer tests automotive parts in the lab. It's all done in the browser, it's done really quickly, and the results can be dumped to a console using node.js. In the past, very few development teams cared to do any JavaScript testing at all, arguing about the difficulty and consistency of such a task. This could be a real deal breaker if we relate the complexity of a single-page JavaScript-powered component and the ease of writing automated tests for it. It's also easier to develop using TDD, that is, writing tests first and then programming to meet the specs.
Last but not least, JavaScript offers many tools to help with development. Since node.js can run just about any JavaScript from command line fast, there are tools which mimic the Composer or Phing on the server-side for JavaScript. Notably, grunt.js and bower, coexisting in a single tool called yeoman.
A Solution to Everything?
No, not really. This strategy is aimed at medium- to large-sized projects. Those which can really benefit from the advantages of the approach described above, and where the client can pay for all this effort. We are still adapting it today, and we slowly harvest the fruits it delivers. This way, we can define pretty precisely the scenarios where it won't fit:
- Simple content websites - any CMS will do the job much faster and less expensively for the client. If you want a simple blog, go with WordPress. If you want a company website combined with our analytical tools and design, you will be better off using our 3OS CMS.
- Heavy SEO-based portals - as AngularJS is dynamic, it is directly opposed to projects being built specifically for SEO - in such projects, it is important to serve static content really fast. The Angular way of doing this generally means something else is presented to the search engine than to the user. This simply means extra work and such an approach is only acceptable if a better UI experience to the user is an important factor.
After all, a solid strategy is not only about what to do, it has to be about what NOT to do. We're sure there are many other possible application development strategies and as we grow, we're going to keep perfecting our approach to current technologies and standards.