<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ramil Aminov</title>
    <description>The latest articles on DEV Community by Ramil Aminov (@ramilaminov).</description>
    <link>https://dev.to/ramilaminov</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F833951%2F4c38a3aa-f78c-4c42-b53e-a1d0940da92e.jpeg</url>
      <title>DEV Community: Ramil Aminov</title>
      <link>https://dev.to/ramilaminov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ramilaminov"/>
    <language>en</language>
    <item>
      <title>Shifting Frontend to the Server</title>
      <dc:creator>Ramil Aminov</dc:creator>
      <pubDate>Mon, 18 Sep 2023 13:44:39 +0000</pubDate>
      <link>https://dev.to/smarthead/shifting-frontend-to-the-server-3lf9</link>
      <guid>https://dev.to/smarthead/shifting-frontend-to-the-server-3lf9</guid>
      <description>&lt;p&gt;In the past, web applications used to be backend-centric, where HTML pages were generated on the server, and templates were used to add dynamic data.&lt;/p&gt;

&lt;p&gt;As time passed, the demand for interactivity on web pages grew, leading to active advancements in frontend technologies, notably through the adoption of the Single Page Application (SPA) approach. Frameworks evolved to the point where the frontend became a separate application, designed and developed independently by separate teams and hosted separately as well.&lt;/p&gt;

&lt;p&gt;This separation, while having its advantages, leads to several problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The code sent to the browser becomes heavy and grows as the application's functionality increases.&lt;/li&gt;
&lt;li&gt;Much of the logic is moved to the client-side. For example, routing is implemented from scratch and bypasses browser mechanisms.&lt;/li&gt;
&lt;li&gt;Much of the logic is duplicated on the frontend and backend. For example, validation and access control.&lt;/li&gt;
&lt;li&gt;It's necessary to design and develop an API, an additional layer to synchronize frontend and backend, even where the backend only serves the interface.&lt;/li&gt;
&lt;li&gt;The division of specialists into frontend and backend developers in teams creates overhead costs, dilutes the understanding of the final task, and responsibilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, the principles of how networks and browsers work have not changed: from the user's perspective, web services still appear as complete applications. Frameworks like &lt;a href="https://nextjs.org"&gt;Next.js&lt;/a&gt; are well-suited for such "holistic" development. Their capabilities were significantly limited until recently, but the latest versions of Next.js and React are changing the game.&lt;/p&gt;

&lt;p&gt;React &lt;a href="https://legacy.reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html"&gt;introduced server components&lt;/a&gt;, and Next.js implemented them along with a new approach to routing called &lt;a href="https://nextjs.org/docs/app"&gt;App Router&lt;/a&gt;. Essentially, now some React components run on the client, while others run on the server, together forming a single web page. Server components can interact directly with the database, and the API layer becomes optional, replaced by Next.js routing mechanisms. It's now possible to create a full-fledged web application without a backend in the traditional sense. Nevertheless, of course, this does not mean that the backend is not needed at all times. On the contrary, the backend can now focus on its more backend-specific tasks without mixing them with presentation logic.&lt;/p&gt;

&lt;p&gt;By shifting some of the frontend processing and rendering logic to the server-side, we can attain the following benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accelerated initial page loading times, as the server can pre-render content before delivering it to the client.&lt;/li&gt;
&lt;li&gt;Enhanced search engine optimization (SEO).&lt;/li&gt;
&lt;li&gt;Mitigation of security risks associated with client-side code, as sensitive logic can be safeguarded on the server.&lt;/li&gt;
&lt;li&gt;Increased code reusability between frontend and backend components, streamlining the development process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Interestingly, for instance, Ruby On Rails, primarily a backend framework, also pushes the boundary of separation, but in a slightly different way. Its authors propose &lt;a href="https://hotwired.dev"&gt;Hotwire&lt;/a&gt; as an alternative to SPA, which involves decomposing and streaming individual parts of HTML.&lt;/p&gt;

&lt;p&gt;Both approaches converge on one point: a significant portion of frontend logic is executed on the server, and we don't lose the benefits of SPA. Thus, the division between the client-side and server-side is not equivalent to the division between frontend and backend. Frontend is a part of the application responsible for interacting with the user and servicing that interaction, including on the server.&lt;/p&gt;

&lt;p&gt;History is progressing in a spiral. More code is executed on the server again, but now we can build client applications of any complexity and beauty with less effort and fewer side effects.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>nextjs</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Decomposition can be excessive</title>
      <dc:creator>Ramil Aminov</dc:creator>
      <pubDate>Fri, 24 Mar 2023 15:37:11 +0000</pubDate>
      <link>https://dev.to/smarthead/decomposition-can-be-excessive-4n8c</link>
      <guid>https://dev.to/smarthead/decomposition-can-be-excessive-4n8c</guid>
      <description>&lt;p&gt;It is commonly believed that decomposition is a good thing. It is indeed useful: it allows us to eliminate uncertainty by breaking down a large, unclear problem into smaller, manageable parts. During the decomposition process, we can better understand the scope of work and even design along the way.&lt;/p&gt;

&lt;p&gt;However, excessive decomposition can be dangerous. It creates the illusion that a feature consists solely of the technical tasks we have broken it down into.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Decomposition incurs overhead costs, not only for creating and working on individual tasks but also for maintaining separate lifecycles and implementing and rolling out each task separately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The requirement for decomposition can lead to premature design and planning. In order to decompose, design decisions are made without all the necessary information. And when new information appears, it may not be corrected. We may feel compelled to implement the previously decomposed plan.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decomposition creates an illusion of control. Doing half of the subtasks means you’ve completed half of the feature. Completing all the subtasks means you’ve completed the entire feature. This is not the case. To complete a feature, it is not enough to complete all of its subtasks. The feature is usually more than just the sum of its parts. There is emergent behavior, a value that is given by the combination of the results of the subtasks and which is not present in the simple sum of these results. To complete the feature, this value must also be implemented.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Often, decomposition simply doesn’t make sense. For example, if a feature is simple enough and can be completed in one go.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Feature decomposition is relevant when we break it down by delivery: into pieces that are themselves the end result in terms of product or a use case.&lt;br&gt;
There is no need to decompose a feature into works (for example, “develop a frontend”, “develop a backend”, or “write a migration”). It is better to decompose it into separate “pieces of value”.&lt;/p&gt;

&lt;p&gt;Decomposition should not be a substitute for documentation or a task description. The description should make it clear what should be the result and what should not be forgotten. But not necessarily each of these items should be a separate subtask.&lt;/p&gt;

&lt;p&gt;Another case is when the task is formulated not in terms of value, but in terms of work to be done. In this case, it may be appropriate to decompose it into independent sub-works.&lt;/p&gt;

&lt;p&gt;With the seemingly obvious benefits of decomposition, it can easily become a “fifth wheel”. Like any other management tool, it should be used consciously.&lt;/p&gt;

</description>
      <category>management</category>
      <category>planning</category>
      <category>projects</category>
      <category>task</category>
    </item>
    <item>
      <title>Quality instead of Quality Control</title>
      <dc:creator>Ramil Aminov</dc:creator>
      <pubDate>Thu, 18 Aug 2022 06:46:00 +0000</pubDate>
      <link>https://dev.to/smarthead/quality-instead-of-quality-control-57eo</link>
      <guid>https://dev.to/smarthead/quality-instead-of-quality-control-57eo</guid>
      <description>&lt;p&gt;When discussing quality, complying with a particular set of requirements usually comes to mind. A client, analyst, or someone else sets tasks and people often take those as the requirements. The worst case scenario is that these requirements are taken as non-negotiable, and lead to the wrong results if followed to the letter. This often happens with outsourced development, and it can have a negative impact on the end user’s experience.&lt;/p&gt;

&lt;p&gt;At SmartHead, we believe that there is more to quality than just meeting client demands. It’s not purely complying with requirements, but also the requirements themselves. We do not take only the client’s expectations into consideration, but the end user’s experience too. This means that our concept of quality also includes components such as usability, UI texts, responsiveness, and release frequency.&lt;/p&gt;

&lt;p&gt;High-quality execution means that different needs are satisfied, namely those of the developer, the client, and the end-user.&lt;/p&gt;

&lt;p&gt;How can this be achieved? It’s not easy by any means, but you should adopt a mindset of built-in quality from the start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quality is about development, not about testing
&lt;/h2&gt;

&lt;p&gt;Quality is often associated with testing. But why?&lt;/p&gt;

&lt;p&gt;Quality is determined by the way in which a product is built, not how it is tested.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfkq68bww63fu8c40ldq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfkq68bww63fu8c40ldq.jpg" alt="Responsibility"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The whole team is responsible for quality — especially the developer — who must be sure that the feature under development works correctly. It is wrong to say that a task is done when there is still uncertainty surrounding its completion. You can be confident that everything works well in two different ways: by how you write the code, and by how you organize the whole development process, including testing. However, it is crucial that quality assurance comes down to more than just testing. Moreover, the post-development manual testing stage should not be a bottleneck, and ideally should not be needed at all.&lt;/p&gt;

&lt;p&gt;So, quality engineering should be included in the development process. To say that everything is “done” means that quality is assured.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resilience
&lt;/h2&gt;

&lt;p&gt;In products with long life cycles, changes are inevitable. So alongside its quality at the moment of feature development, “system quality” and its level of resilience are also important.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljc0eelqvvcbac3tiqcr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljc0eelqvvcbac3tiqcr.jpg" alt="Resilience"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Making regular changes is completely normal, and products are likely to require much more than just one-off correction. This is only possible if it is certain that changes won’t break anything, and if this is the case, we can say that the system is resilient to change.&lt;/p&gt;

&lt;p&gt;There are issues with resilience or quality if you do not want to touch anything while it is operating, or if the developers are reluctant to discard code they have already written. &lt;/p&gt;

&lt;p&gt;The codebase is not something that we build and hand over. It is our environment that we should make comfortable to work in. It should be easy to add, edit and delete code.&lt;/p&gt;

&lt;h2&gt;
  
  
  No detailed requirements — no problem
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg6u0czprf7vot6lmjrqv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg6u0czprf7vot6lmjrqv.jpg" alt="Requirements"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If there are no detailed requirements, this does not mean you need to run to the client to ask “where in the UI should this button be?” Nor does it mean that it can go anywhere, however. &lt;/p&gt;

&lt;p&gt;Apart from the incoming requirements (or lack thereof) it’s important to rely on common sense, experience, and taste — and high levels of each of these must be maintained. &lt;/p&gt;

&lt;p&gt;The need to write detailed requirements can put pressure on clients to make important decisions regarding the product despite the fact that they lack either the knowledge or information to do so.&lt;/p&gt;

&lt;p&gt;The absence of detailed requirements is not a problem, but rather an opportunity to do the job as well as possible and adopt a flexible approach towards the project’s scope, taking into consideration the available time and budget. In other words, focusing on the most important elements and ignoring the less significant ones is the best strategy. &lt;/p&gt;

&lt;p&gt;Of course, we should understand what we are doing and why we are doing it, but a detailed description of everything is not necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bugs are inevitable, but not in excess
&lt;/h2&gt;

&lt;p&gt;“Bugs are inevitable” is often said to justify low-quality development. Just because it is impossible to create bugless software does not mean that an excessive amount of bugs is acceptable. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F059dbrdo5pq8p0vx9xom.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F059dbrdo5pq8p0vx9xom.jpg" alt="Bugs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bugs are OK provided that: they do not prevent you from reaching project goals, they can be fixed quickly, and are not critical for the system’s stability. Severe bugs that break the main use cases occur quite rarely.&lt;/p&gt;

&lt;p&gt;However, if every task is reopened after testing, or if fixing one bug causes three new ones to spring up, it means that there is an issue with quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not everything is a bug
&lt;/h2&gt;

&lt;p&gt;Bugs can also be viewed from another perspective. Their quantity depends not only on how the code is written, but also on the definition of a bug. Formally, a bug can be found in software of any quality. But not everything needs to be reported because it can just lead to some extra work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmpv52b7fiz8qgp4wk9o.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmpv52b7fiz8qgp4wk9o.jpg" alt="Important bug"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are not suggesting that you ignore bugs, although it is nonetheless important that you understand what requires your attention, and when you can move on. Testers can get bogged down in the details to such an extent that they run out of time to focus on what is actually significant. A lot of time can be lost on checking the layout, which then leaves little opportunity to check the main user scenario. Every task can be returned because of insignificant details, but this can mean that you lose sight of the bigger picture when it comes to quality. When all the tasks are reopened, it is not clear what has been done.&lt;/p&gt;

&lt;p&gt;Moreover, you should not test the developer’s competence. If you spend more time testing their tasks purely because you don’t trust their ability, then bugs aren’t your problem. Instead, it is likely that there is mistrust in the team or the task is too complex for the developer. Ultimately, you should test software, not people — trust them instead.&lt;/p&gt;

&lt;p&gt;In addition, we see little value in testing the design or the written requirements. They themselves, when they are not implemented, bring no value to end-users. You can and should review, discuss, and design them among your team, yet, there is no need to test them formally.&lt;/p&gt;

&lt;p&gt;In a world of endless resources, it would be great to test everything, of course. However, in the here and now, there are simply more important tasks to consider. &lt;/p&gt;

&lt;h2&gt;
  
  
  So what should we test then?
&lt;/h2&gt;

&lt;p&gt;The QA engineer is a product’s “user zero” who knows it well both from outside and inside. They should prioritize the user’s experience rather than checking the developer’s work. They should check what has been done, not what was being done, in other words features, not tasks.&lt;/p&gt;

&lt;p&gt;The QA engineer’s objective is not to find as many bugs as possible, but to ensure that fewer of them make it into the final product. From this point of view, the fewer bugs they find the better.&lt;/p&gt;

&lt;p&gt;The QA engineer is also responsible for accessibility and usability, including copywriting, animations, etc.&lt;/p&gt;

&lt;p&gt;The QA engineer can also improve development quality by contributing their own thought processes. For example, they can help developers to write tests, cover edge cases, and ensure sufficient and reasonable coverage.&lt;/p&gt;

&lt;p&gt;Testing is effective when it aims to bring additional value, and not when it compensates for the drawbacks of development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Compliance with the requirements that were set initially shouldn’t be the goal. It’s much more important to make a great product.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User experience should be taken into consideration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The quality level is set during the development. If time is wasted on compensating poor development with testing, then development, and thus quality, is neglected. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manual testing should not be a critical need but something that adds to the value.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>codequality</category>
      <category>testing</category>
      <category>qualityassurance</category>
      <category>qa</category>
    </item>
  </channel>
</rss>
