AWS Certification as a PHP Developer: 4 things I learned
Introduction
I would like to share my perspective on obtaining cloud service certifications such as AWS, Google Cloud, or Azure.
It’s a unique perspective because I’ll be describing what earning a certificate (in my case, AWS Certified Developer Associate) has given me from the viewpoint of a PHP developer.
So, in this article, you won’t read about the intricacies of cloud services, nor will I list hundreds of services and explain how they work. Instead, I’ll focus on what a PHP developer can take away from preparing for such an exam.
Let’s get to the point:
How the certification changed my perspective as a PHP developer
1. The application doesn't exist in a vacuum
Before a user’s request reaches the application and before the code is “executed,” it goes through a long journey. A lot happens in the areas of networking, DNS, databases, caching, logging, and monitoring. The awareness that the application is just one part of a larger puzzle broadens the perspective when designing new functionalities.
For instance, remember to log changes occurring within the application and carefully consider whether data should be fetched directly from the database or offloaded to a cache.
You’ll definitely find solutions like these useful:
- Debugbar/Profiler – popular frameworks like Laravel and Symfony have extensions such as Debugbar, which allow you to locally check things like which queries are being sent to the database.
- Blackfire, Tideways, Datadog , etc. – these are more advanced tools that not only allow you to monitor your application locally but also in production or test environments.
2. How much does a line of code cost?
Designing solutions that will be maintained in the cloud forces a particular mindset, where we think several times about whether a line of code we write might become a performance issue.
Creating a bottleneck, generating a timeout, or using a resource-intensive function are examples that can generate costs, because in models like Serverless or the general Pay-as-you-go model, we pay for how long our code runs (plus how many resources are consumed).
This type of billing model forces us to design efficient applications. It compels us to think about how what we write actually works. It also requires us to log changes, making it easier to identify problems.
Not only errors are worth logging. To track down a deeper issue, it’s important to have a history of key changes to help identify the problem.
We pay for resources, and one of those resources is memory. It’s important to monitor memory usage when developing new functionality. For local debugging, you can use this extension: github.com/BitOne/php-meminfo
Below is a simple example of how to quickly check memory usage.
I then analyze the file in the console:
Above, you can see an example from the documentation.
Additionally, timeouts are often overlooked. We think about how long it takes to send a request to an external service (I hope you do this), but we forget about what happens if that service gets stuck and our connection hangs open. When time equals money, it’s essential to ensure timeouts are properly defined.
See below. If the external service, in this case “user-service.example.com,” becomes unresponsive and our requests don’t go through, it’s better to stop the request after 5 seconds instead of 30. With a larger scale, this change can be crucial.
Moreover, if we’re using services like Redis or Elasticsearch, which are typically fast and return data in milliseconds, it’s a good idea to set a global timeout, for example, to 1 second. When such a service is unavailable, there’s no point in consuming resources and keeping the connection open for several seconds, which will ultimately fail anyway.
Moving forward, it’s important to ensure that these actions are repeatable without causing any harm or data duplication.
Thus, the mindset of counting costs by lines of code is both interesting and useful.
3. If something is repetitive – automate it!
In the cloud, nearly everything happens automatically. Pressing a single button triggers a series of operations happening under the hood of a cloud service. Deploying a new version of an application triggers CI and CD processes. Scaling an application refers to automatically changing the number of servers. Everywhere, automation!
Here, we can look at it from different perspectives.
We can use it to automate features within the application. The user can be relieved of repetitive tasks, reducing their clicking to a single process initiation. We can design solutions so that things happen automatically.
Additionally, we can automate our own work. If the same mistakes keep appearing in code reviews, we can use tools to automatically check syntax or formatting according to our standards.
If you're not yet using the tools listed below in your projects, consider giving them a try – they will bring you a lot of benefits:
PHPStan
A static code analysis tool that will, for example, show you when you try to access a property in an object that could be null:
PHP CS Fixer
A tool that will save you hundreds of hours spent on code reviews by improving various formatting issues and maintaining coding standards:
Identifying repetitive tasks is a great habit to build automation and reduce tedious work, leaving us with more time for new, more attractive things.
4. Design patterns in practice
This is my last observation. Cloud services are vast infrastructures that work reliably across many layers. When we see all of them and how they are interconnected, it demonstrates the use of design patterns on a massive scale – and that… they work!
Solutions like Event-Driven Architecture or CQRS, which operate in practice at the user level, are invaluable. It gives us perspective on how to design applications that live in harmony with each other.
Combined with High Availability, Regions, or Availability Zones, we deal with an organism that doesn’t fail. Our application physically operates across several locations scattered around the globe. With this knowledge, we approach designing things like dependencies and functionality differently. We approach debugging and client-side experience differently. We notice more places that are bottlenecks. And most importantly, we have the knowledge of how to build reliable applications.
The conclusion is that it’s worth exploring and trying out new solutions, such as design patterns, not only in code but also in the overall architecture of the entire ecosystem we’re building.
In short
- The application doesn’t exist in a vacuum – before the client reaches the application, it passes through many points,
- use logging to track changes happening within the application,
- ensure application monitoring,
- design applications that can retry failed requests,
- keep in mind that performance issues, bottlenecks, and improperly defined timeouts cost money,
- identify repetitive tasks and automate them,
- reliable and efficient applications work because they are physically located in different locations, have backups, scaling, components, and still work as a single organism.
Conclusion
I’m giving you a unique perspective, because studying for the exam and earning the certificate is not just about knowing how a service works and how many there are. It allows you to gain a perspective and way of thinking, and that is valuable.