<?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>Forem: Bruno Pinheiro</title>
    <description>The latest articles on Forem by Bruno Pinheiro (@brunofpinheiro).</description>
    <link>https://forem.com/brunofpinheiro</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%2F1028397%2F63f3b2da-2593-4b02-b2b2-e8a44682da2b.jpg</url>
      <title>Forem: Bruno Pinheiro</title>
      <link>https://forem.com/brunofpinheiro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/brunofpinheiro"/>
    <language>en</language>
    <item>
      <title>GitHub Copilot: great assistant, terrible architect</title>
      <dc:creator>Bruno Pinheiro</dc:creator>
      <pubDate>Mon, 13 Oct 2025 08:35:56 +0000</pubDate>
      <link>https://forem.com/brunofpinheiro/github-copilot-great-assistant-terrible-architect-174a</link>
      <guid>https://forem.com/brunofpinheiro/github-copilot-great-assistant-terrible-architect-174a</guid>
      <description>&lt;p&gt;When the AI hype train arrived, I just observed, as I was skeptical about its actual power. I still didn’t know exactly what to expect.&lt;/p&gt;

&lt;p&gt;A while later, AI assistants began to work their way into our IDEs, aiming to ease our work. Again, I was skeptical, but eventually I started using some tools, especially GitHub Copilot.&lt;/p&gt;

&lt;p&gt;It’s been almost one year since I started using it daily for my development tasks. Although I didn’t use it for everything (and I still don’t), I tried using it anytime I needed help.&lt;/p&gt;

&lt;p&gt;After this time, here are some of my thoughts on Copilot and other similar AI assistants.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Treat it as an assistant, not a code generator&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Don't ask it to write something too big, like an entire class, or worse, a whole application. I like to think of it as an assistant developer who has all the theoretical knowledge available, including documentation, syntax, and code examples. You name it, Copilot has it. This is great, don’t get me wrong, but it’s not enough. Especially when it comes to architectural decisions, it doesn’t help much.&lt;/p&gt;

&lt;p&gt;Copilot only knows what it was trained on. It doesn’t understand the particularities of your application. By particularities, you know what I mean, right? I'm talking about that piece of code or architectural decision that is fundamentally wrong, but it has to be that way in your application. As an example, I can say that I have some endpoints on the system I work on that are used to fetch some information. They should be a GET endpoint, right? But they are a POST, and they were meant to be like that.&lt;/p&gt;

&lt;p&gt;Anyone who sees the code knows that it’s wrong (in theory), but they understand why it was done like this.&lt;/p&gt;

&lt;p&gt;Copilot doesn’t understand things like that. Not yet, at least.&lt;/p&gt;

&lt;p&gt;Another keyword when getting Copilot to understand you is &lt;strong&gt;context&lt;/strong&gt;. When giving an instruction, the assistant will only know the context you pass to it. If you don’t pass the correct context, it will not know what you are talking about, and the output will be compromised. You know that saying, garbage in, garbage out? It applies very well here. The better your input, your prompt, the better the output.&lt;/p&gt;

&lt;p&gt;In summary, use it for smaller tasks, on a single method, or a SQL query, for example. Something that you know what you want, so you can check if the output is correct or not.&lt;/p&gt;

&lt;p&gt;Do &lt;strong&gt;NOT&lt;/strong&gt; blindly trust the output.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Copilot teaches you about your own coding style&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Just like other AI tools, Copilot is predictive. The more of your code it sees, the better its predictions. I’ve noticed that after a while, the predictions got pretty accurate, which I saw as a good thing. That means my code is consistent in its style, and Copilot started helping with good suggestions.&lt;/p&gt;

&lt;p&gt;Part of software development is a creative process, but another part is not. It’s the boilerplate, the repetitive code, the same old recipes. That’s where Copilot truly shines, not on the creative part.&lt;/p&gt;

&lt;p&gt;Given its predictive nature, it thrives in those repetitive tasks, like when you rename a variable and have to update it throughout the class, or when you start typing the variable type, and it suggests the variable name and its initialization. After a while, Copilot picks up your style, and the suggestions tend to get very accurate and very close to what you would write.&lt;/p&gt;

&lt;p&gt;Being able to write less of this repetitive code and just checking and accepting suggestions is a huge win for me. I know this might seem small, but believe me, these small things do add up.&lt;/p&gt;

&lt;p&gt;Just like any other tool, Copilot is here to make our lives easier, and it does it very well when helping with those repetitive tasks.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Trust, but verify&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Remember what I said about not blindly trusting the output?&lt;/p&gt;

&lt;p&gt;Think of a junior dev, for example. You cannot just trust that his or her code will be correct. You'll have to verify it thoroughly to make sure. Treat Copilot's output the same way. Expect it to be correct, but always verify to make sure.&lt;/p&gt;

&lt;p&gt;Even though it has all the information about syntax, best practices, etc., that doesn't guarantee a good output. For example, you can use a badly written prompt, so you would get a bad response, or the model could just hallucinate. I'm pretty sure you heard of the hallucinations. I had Copilot suggest to me a piece of code with a method that turned out simply not to exist. Where did it get the method from? Absolutely no idea.&lt;/p&gt;

&lt;p&gt;It's also nice to always check the response for vulnerabilities. After making sure that the output is correct, ask Copilot itself to look for vulnerabilities. Make sure the code is the best it can be before adding it to your repository.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The shift from writing code to reading/validating code&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Even though Copilot and other LLMs aim to help us be more productive, what I've noticed is that I'm not really writing more code; it’s quite the opposite, actually. I'm writing less code, but I am reading a lot more.&lt;/p&gt;

&lt;p&gt;If we shouldn't simply trust the output, that means we should read it carefully. So the more we use it, the more code we have to read.&lt;/p&gt;

&lt;p&gt;I’m spending less time writing raw code and more time validating AI output. Does the output make sense? Is it correct? Is it optimized when it comes to performance? Could the variables be named better? These are all valid questions to ask when deciding if an output deserves to be put in your application or not.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After almost one year of using Copilot daily, I can say it has definitely earned a place in my toolbox. But as an assistant, not as a replacement.&lt;/p&gt;

&lt;p&gt;It shines the most when helping with small, repetitive tasks, but it still needs guidance, context, and careful review.&lt;/p&gt;

&lt;p&gt;Using it has shifted how I work. I now spend less time typing code and more time reading, validating, and improving it.&lt;/p&gt;

&lt;p&gt;In the end, Copilot makes me a faster developer, but not because it writes the code for me, it’s because it helps me focus on writing better code myself.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>productivity</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>Sharing data between Angular components with observables</title>
      <dc:creator>Bruno Pinheiro</dc:creator>
      <pubDate>Fri, 07 Feb 2025 09:47:45 +0000</pubDate>
      <link>https://forem.com/brunofpinheiro/sharing-data-between-angular-components-with-observables-3hp3</link>
      <guid>https://forem.com/brunofpinheiro/sharing-data-between-angular-components-with-observables-3hp3</guid>
      <description>&lt;p&gt;One of the main parts of any Angular application is the components. Normally each component takes care of only one aspect of the application, so in larger projects, you could end up with quite a few of them.&lt;/p&gt;

&lt;p&gt;Despite their single-responsibility nature, they are not isolated structures. They need to send data to other components/services and also receive it. And that's where the concept of Observables from RxJS comes in handy.&lt;/p&gt;

&lt;p&gt;They are one of the ways of sharing data between components.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you do that?
&lt;/h3&gt;

&lt;p&gt;An Observable is an object you can subscribe to, so you receive new values when they are emitted.&lt;/p&gt;

&lt;p&gt;Think about a newsletter that you get on your email. You subscribe to a certain topic and every time a new email is sent about that topic, you get the email too.&lt;/p&gt;

&lt;p&gt;That's the same concept with Observables. Each one will emit a certain type of data, and you can subscribe to them, so you receive updates from that Observable.&lt;/p&gt;

&lt;p&gt;To emit new values, you can use another feature of RxJS called Subject.&lt;/p&gt;

&lt;p&gt;A Subject is a special type of Observable that can be multicasted to several observers simultaneously.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Subjects
&lt;/h2&gt;

&lt;p&gt;Currently, there are 5 types of Subjects: Subject, BehaviorSubject, ReplaySubject, AsyncSubject, and VoidSubject.&lt;/p&gt;

&lt;p&gt;Subject is the father of them all, the other ones are variations.&lt;/p&gt;

&lt;p&gt;We will talk about 3 of them, which I have used the most.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subject&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can create a Subject and have multiple ‘listeners’ subscribing to it at the same time, so when a new value is emitted, all of them will receive the same value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fancmw1klp9u8isz7802d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fancmw1klp9u8isz7802d.png" alt="code showing a subject with multiple listeners" width="572" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BehaviorSubject&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the one I’ve used the most when passing data through components.&lt;br&gt;
It works almost in the same way as the Subject. The difference is that the moment you subscribe to it, besides receiving the next values, you also immediately receive the last value emitted.&lt;/p&gt;

&lt;p&gt;This is useful when you want to know the current/latest value when you subscribe.&lt;/p&gt;

&lt;p&gt;Say for example that you are passing data from component A to component B, and you have a BehaviorSubject on a shared-state.service. For example, it could be a search filter.&lt;/p&gt;

&lt;p&gt;On the state service you might have something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ffemvuh0ssuijh93mt918.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ffemvuh0ssuijh93mt918.png" alt="code showing a behavior subject" width="769" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then say on component A you push a value ‘userId=2’ to this subject.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzo02twyphbm2zv18lwvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzo02twyphbm2zv18lwvv.png" alt="code showing a filter being set" width="485" height="35"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can go to component B and subscribe to this subject. When you do, you will receive this ‘userId=2’ value immediately.&lt;br&gt;
As long as this subscription remains active, you will also receive new values emitted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fvjj583j5gihk7hm0kuvc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fvjj583j5gihk7hm0kuvc.png" alt="code showing a subscription to the getFilter method" width="620" height="88"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VoidSubject&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I haven’t used this one as much as the others, but it can be quite useful in the right circumstances. &lt;br&gt;
As the name implies, a VoidSubject is of type void. Which means it emits an event, but with no value.&lt;/p&gt;

&lt;p&gt;For that, just create a regular Subject, with a void type. You don't have to pass any parameter when you call its emit() function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbh5p9i8ouzpagt2jeqdh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbh5p9i8ouzpagt2jeqdh.png" alt="code showing a void subject" width="548" height="57"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But Bruno, why would I want something that does not emit a value?&lt;/p&gt;

&lt;p&gt;You use that when you don’t care about the value, you just want to know when something happens, like an action from the user, or when some processing finishes, for example.&lt;/p&gt;

&lt;h3&gt;
  
  
  What now?
&lt;/h3&gt;

&lt;p&gt;Now, to know more about Observables and how they help us in our daily activities, I highly recommend you check out the source material on the &lt;a href="https://rxjs.dev" rel="noopener noreferrer"&gt;RxJS&lt;/a&gt; page. There is a lot of great information there.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Simplifying Angular components with Facade</title>
      <dc:creator>Bruno Pinheiro</dc:creator>
      <pubDate>Thu, 05 Sep 2024 22:24:36 +0000</pubDate>
      <link>https://forem.com/brunofpinheiro/simplifying-angular-components-with-facade-1c1f</link>
      <guid>https://forem.com/brunofpinheiro/simplifying-angular-components-with-facade-1c1f</guid>
      <description>&lt;p&gt;On an Angular project, you have your components, managing the interaction with the user, and, quite often they can become massive and complex, making it hard to refactor anything, and for newcomers to understand the code.&lt;/p&gt;

&lt;p&gt;One way to improve this situation is to use the design pattern &lt;strong&gt;Facade&lt;/strong&gt;. This pattern is used to mask or hide more complex interactions.&lt;/p&gt;

&lt;p&gt;When structuring Angular projects, I like to think like this: the component should worry only about user interaction, showing and receiving information.&lt;/p&gt;

&lt;p&gt;If the component needs something, it shouldn't go after it itself, but rather request it from someone else.&lt;/p&gt;

&lt;p&gt;For example, the user enters a page with a list of products. The component shouldn't be the one to go after the products list. It should ask the facade service to fetch that instead. When the component receives the list, it can display it to the user. That's the only thing the component should have to worry about, the interaction with the user.&lt;/p&gt;

&lt;p&gt;The component should communicate only with the facade, using the facade service to simplify information processing.&lt;/p&gt;

&lt;p&gt;Let's see it more visually now.&lt;/p&gt;

&lt;p&gt;Think about the product list again.&lt;/p&gt;

&lt;p&gt;When the user enters a page with the list you could have something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private findAllProducts() {
    this.productsApiService.findAllProdutcs().pipe(map(response =&amp;gt; {
      // transform data
      return transformedData;
    })).subscribe((products: IProducts[]) =&amp;gt; {
      this.products = products;
    });
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The component needs to know where to get the products and how to transform the response it gets. The component shouldn't be the one doing this as it makes the component unnecessarily complex.&lt;/p&gt;

&lt;p&gt;Instead, create a products-facade.service.ts (the name is up to you) and move the above method to it.&lt;/p&gt;

&lt;p&gt;Now the component only needs this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private findAllProducts() {
    this.productsFacadeService.findAllBooks().subscribe((products: IProduct[]) =&amp;gt; {
      this.products = products;
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See how much simpler it is?&lt;/p&gt;

&lt;p&gt;With this, the component goes to the facade and requests a list of products. Now, where the facade will get this information and if it will need some transformation are questions that don't concern the component. It's the facade's job to go and get what the component asks. It should deliver it in a way that the component only has to show it to the user.&lt;br&gt;
You can think of the facade like a secretary or a butler (like Alfred and Batman).&lt;/p&gt;

&lt;p&gt;If you are using some state service to manage data, it's the same idea.&lt;/p&gt;

&lt;p&gt;Remember that the component should communicate only with the facade, so it doesn't have to know how this state service works or what methods it has. The component should go to the facade, and the facade should get the state information.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Only the facade should know where to get the information, the component doesn't have to.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Think of the interaction like this.&lt;br&gt;
&lt;strong&gt;Component:&lt;/strong&gt; Hey, the user typed their username and password. Check if it's a valid user.&lt;br&gt;
&lt;strong&gt;Facade:&lt;/strong&gt; Sure, I'll check and let you know.&lt;br&gt;
&lt;strong&gt;Facade:&lt;/strong&gt; It is a valid user. You can let him in.&lt;br&gt;
&lt;strong&gt;Component:&lt;/strong&gt; Ok, I'll tell him.&lt;/p&gt;

&lt;p&gt;That's it. The component reacted to a user's action and asked the facade to verify the information. It got the response and delivered it to the user.&lt;/p&gt;

&lt;p&gt;That way, you are separating responsibilities. Component with user interactions and facade with business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Warning&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Just be careful not to create a single facade to handle everything, ok? Otherwise, you will end up with a monster that is impossible to manage.&lt;/p&gt;

&lt;p&gt;For me, it doesn't really matter how you choose to divide the facades.&lt;br&gt;
For example, you can separate by domain (products, sales, login, etc), or by component, having one smaller facade for each component, or any other way you can think of.&lt;/p&gt;

&lt;p&gt;What matters is that it makes sense and you keep to it through the whole project. It's pretty bad when you find that something works in one way in one part of the project and in a different way in another part.&lt;/p&gt;

&lt;p&gt;That's the idea of this approach. To separate responsibilities. Component with user interactions and facade with business logic.&lt;/p&gt;

&lt;p&gt;Remember this and try it on your next project.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>designpatterns</category>
      <category>programming</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Simplifying Angular components with Facade</title>
      <dc:creator>Bruno Pinheiro</dc:creator>
      <pubDate>Wed, 04 Sep 2024 06:10:53 +0000</pubDate>
      <link>https://forem.com/brunofpinheiro/simplifying-angular-components-with-facade-3ibd</link>
      <guid>https://forem.com/brunofpinheiro/simplifying-angular-components-with-facade-3ibd</guid>
      <description>&lt;p&gt;On an Angular project, you have your components, managing the interaction with the user, and, quite often they can become massive and complex, making it hard to refactor anything, and for newcomers to understand the code.&lt;/p&gt;

&lt;p&gt;One way to improve this situation is using the design pattern &lt;strong&gt;Facade&lt;/strong&gt;. This pattern is used to mask, or hide, more complex interactions.&lt;/p&gt;

&lt;p&gt;When structuring Angular projects, I like to think like this: the component should worry only about user interaction, showing and receiving information.&lt;/p&gt;

&lt;p&gt;If the component needs something, it shouldn't go after it itself, but rather request it from someone else.&lt;/p&gt;

&lt;p&gt;For example, the user enters a page with a list of products. The component shouldn't be the one to go after the products list. It should ask for the facade service to fetch that instead. When the component receives the list, it can display it to the user. That's the only thing the component should have to worry about, the interaction with the user.&lt;/p&gt;

&lt;p&gt;The component should communicate only with the facade, using it to simplify the processing of information.&lt;/p&gt;

&lt;p&gt;Think about the product list again.&lt;/p&gt;

&lt;p&gt;The user enters a page with the list. The component goes to the facade and requests a list of products. Now, where the facade will get this information and if it will need some transformation are questions that don't concern the component. It's the facades’ job to go and get what the component asks. It should deliver it in a way that the component only has to show it to the user.&lt;br&gt;
You can think of the facade like a secretary or a butler (like Alfred and Batman).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  private findAllProducts() {
    this.productsApiService.findAllProducts().subscribe((product: IProducts[]) =&amp;gt; {
      this.products = books;
    });
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using some state service to manage data, it's the same idea.&lt;/p&gt;

&lt;p&gt;Remember that the component should communicate only with the facade, so it doesn't have to know how this state service works or what methods it has. The component should go to the facade, and the facade should get this state information.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Only the facade should know where to get the information, the component doesn't have to.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Think of the interaction like this.&lt;br&gt;
&lt;strong&gt;Component:&lt;/strong&gt; hey, the user typed its username and password. Check if it's a valid user.&lt;br&gt;
&lt;strong&gt;Facade:&lt;/strong&gt; Sure, I'll check and let you know.&lt;br&gt;
&lt;strong&gt;Facade:&lt;/strong&gt; It is a valid user. You can let him in.&lt;br&gt;
&lt;strong&gt;Component:&lt;/strong&gt; Ok, I'll tell him.&lt;/p&gt;

&lt;p&gt;That's it. The component reacted to a user's action and asked the facade to verify the information. It got the response and delivered it to the user.&lt;br&gt;
That way, you are separating responsibilities. Component with user interactions and facade with business logic.&lt;br&gt;
CAUTION&lt;br&gt;
Just be careful not to create a single facade to handle everything, ok? Otherwise, you will end up with a monster that is impossible to manage.&lt;br&gt;
For me, it doesn't really matter how you choose to divide the facades.&lt;br&gt;
For example, you can separate by domain (products, sales, login, etc), or by component, having one smaller facade for each component, or any other way you can think of. What matters is that it makes sense and you keep to it through the whole project.&lt;br&gt;
It's pretty bad when you find that something works in one way in one part of the project and in a different way in another part.&lt;br&gt;
That's the idea of this approach. To separate responsibilities. Component with user interactions and facade with business logic.&lt;/p&gt;

&lt;p&gt;Remember this and try it on your next project.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>designpatterns</category>
      <category>programming</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Semantic Versioning: simple but powerful</title>
      <dc:creator>Bruno Pinheiro</dc:creator>
      <pubDate>Mon, 04 Mar 2024 14:13:05 +0000</pubDate>
      <link>https://forem.com/brunofpinheiro/semantic-versioning-simple-but-powerful-5939</link>
      <guid>https://forem.com/brunofpinheiro/semantic-versioning-simple-but-powerful-5939</guid>
      <description>&lt;p&gt;If you have started any project, even if you didn’t publish or finish it, I bet you saw some versioning for it, for the project itself, or the dependencies.&lt;/p&gt;

&lt;p&gt;For example, when you start a new project in Angular, you should see something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fucrulbvuiltjeyxyzess.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fucrulbvuiltjeyxyzess.png" alt="screenshot of the package.json file inside an Angular project" width="447" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mobile games are good for you to see this. They usually have their version number on the bottom of their login screen.&lt;/p&gt;

&lt;p&gt;There are many ways to give a version number to something. Actually, it doesn’t even have to be a number. You can work on a project and give it version A, B, C, etc. The important part is that you can differentiate each version.&lt;/p&gt;

&lt;p&gt;When it comes to versioning, there is not a hard rule. Like I said, you can use numbers, letters, or anything you want. As long as you can differentiate the versions you're fine.&lt;/p&gt;

&lt;p&gt;On one hand, this is good because of the freedom you have. On the other hand, this is bad because it creates a lack of pattern, so each project could have its own versioning system, and you would have to understand each one separately.&lt;/p&gt;

&lt;p&gt;Versioning systems are supposed to help with that issue. They provide a clear and logical pattern for the versions.&lt;/p&gt;

&lt;p&gt;There are quite a few options for this, but the one we’re talking about today is Semantic Versioning. I really like this one because it's simple to understand and powerful enough to represent everything we need to know.&lt;/p&gt;

&lt;p&gt;The basic idea of Semantic Versioning is that it represents the version with three digits, separated by a point, like &lt;strong&gt;x.y.z.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It may not look like it, but this simple representation can tell us what type of change was made, helping us to decide if we can safely upgrade a dependency for example.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;How, you may ask? Let’s delve into this.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Each digit represents something. The first one represents the &lt;strong&gt;‘Major’&lt;/strong&gt; version, the second &lt;strong&gt;‘Minor’&lt;/strong&gt; version and the third represents the &lt;strong&gt;‘Patch’&lt;/strong&gt; version.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Patch:&lt;/strong&gt; you should increase the patch number if there are one or more bug fixes or corrections. No new stuff, just correction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eg: if the current version of your project is 1.0.1 you should advance to 1.0.2.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minor:&lt;/strong&gt; you should increase the minor version if there are one or more backward-compatible implementations or new features. When you increase the minor, you should reset the patch to 0.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eg: If you are on version 1.0.2 the next one should be 1.1.0.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Major:&lt;/strong&gt; this should be increased when you have backward-incompatible changes. You can have minor and/or patch changes as well, but if something changes in an incompatible way, you should increase the major version number. When you increment the major, you should reset the minor and patch to 0.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eg: if the current version is 1.1.0 the next one should be 2.0.0&lt;/p&gt;

&lt;p&gt;What you must remember about the resets, is that whenever you increase one of the numbers, you reset the others to the right. So, when you increase the major you reset the minor and patch. When you increase the minor you reset only the patch.&lt;/p&gt;

&lt;p&gt;Resetting the numbers to 0 is necessary to correctly tell what is in the new version.&lt;/p&gt;

&lt;p&gt;Let’s take the same example as before, you are on version 1.1.0. This means that major version 1 had one minor version released. When we increase the major to 2 we must reset the other numbers because this new major version doesn’t have any minor or patch versions released.&lt;/p&gt;

&lt;p&gt;Besides using those three digits, you can also say that a version is a pre-release one, and you can also attach some metadata if you want. Let’s talk about that later on.&lt;/p&gt;

&lt;p&gt;That’s the idea behind the semantic versioning.&lt;/p&gt;

&lt;p&gt;Now, let’s talk about its 11 rules. (don’t worry, they’re not hard, and some of them you already know).&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Rules of Semantic Versioning&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Public API:&lt;/strong&gt; must have a public API. It can be on the documentation or the code, but it must have it, and it should be clear and concise.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Version number format:&lt;/strong&gt; the version number must be in the format x.y.z. All digits must be non-negative integers and it must not start with zero.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Immutable versions:&lt;/strong&gt; once a version is released it should not be modified in any circumstance. If it needs a correction or modification then you should release a new version.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Initial development:&lt;/strong&gt; when you first start working on a project you must start its major version with 0.y.z. That’s because during the initial development, many things will change and the public API should NOT be considered stable at this point.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Version 1.0.0:&lt;/strong&gt; a public API will be considered as defined and stable after the release of version 1.0.0. All other versions from now on should be based on this one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Patch version:&lt;/strong&gt; the patch version indicates that one or more bugs were fixed and the code remains compatible with the previous version. This means that version 1.0.1 fixes a problem with version 1.0.0 and it’s compatible with it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Minor version:&lt;/strong&gt; the minor version can only be increased under two circumstances: when new features are being added, but still compatible with the previous version, or to deprecate some published feature. When you update the minor version you should reset the patch version to 0. For example, a project with version 1.0.6 just had a new minor version released. The next version should be 1.1.0, not 1.1.6.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Major version:&lt;/strong&gt; when new changes that are incompatible with previous versions of the public API are released, you should increase the major version, and reset minor and patch to 0.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pre-release version:&lt;/strong&gt; you can indicate a pre-release version by adding a hyphen and a series of point-separated identifiers after the patch version. The identifiers should contain only alphanumeric ASCII characters, and hyphens (0-9A-Za-z-). Also, the identifiers should not be empty or have trailing zeros.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Eg: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-beta&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build metadata:&lt;/strong&gt; similar to the pre-release version, you may add build metadata information by adding a plus sign after the patch version followed by point-separated identifiers. The identifiers should be only alphanumeric characters and hyphens (0-9A-Za-z-). You can add information like the timestamp of the build or the hash code for the commit for example.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Eg: 1.0.0+20240229072000&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Version precedence:&lt;/strong&gt; this defines how each version should be compared to others.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You start by separating the numbers. Separate the major, minor, patch and, pre-release. The build metadata info is not used to compare the versions.&lt;/p&gt;

&lt;p&gt;Start comparing each number individually, from left to right until you find a difference.&lt;/p&gt;

&lt;p&gt;Eg 1.0.0 &amp;lt; 2.0.0, 1.1.1 &amp;lt; 1.1.2&lt;/p&gt;

&lt;p&gt;If major, minor and patch are the same, you check the pre-release info. If there is pre-release information, then it has a lower precedence.&lt;/p&gt;

&lt;p&gt;Eg: 1.0.0-beta &amp;lt; 1.0.0&lt;/p&gt;

&lt;p&gt;This is the idea behind Semantic Versioning. It’s quite simple but really powerful. You have a lot of information for such a small versioning number.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Let’s recap the main topics.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;3 digits separated by a point, x.y.z&lt;/p&gt;

&lt;p&gt;They are called, &lt;strong&gt;major&lt;/strong&gt;, &lt;strong&gt;minor&lt;/strong&gt;, and &lt;strong&gt;patch.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You increase the major when you have changes that are incompatible with the previous version. When you do that you should reset minor and patch versions to 0.&lt;/p&gt;

&lt;p&gt;You increase minor to deprecate something or to add changes that are compatible with the previous version. When you do that you should reset the patch to 0.&lt;/p&gt;

&lt;p&gt;You increase the patch when you have one or more bug fixes and the code remains compatible with the previous version.&lt;/p&gt;

&lt;p&gt;You can also have a pre-release version, for that, you add an identifier after the patch version separated by a hyphen, like 1.0.0-alpha.&lt;/p&gt;




&lt;p&gt;If you want to get a more in-depth look at this topic I highly recommend going to the source material.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://semver.org" rel="noopener noreferrer"&gt;semver.org&lt;/a&gt;
&lt;/h3&gt;

</description>
      <category>programming</category>
      <category>semanticversioning</category>
    </item>
    <item>
      <title>Using the Richardson maturity model to improve your APIs</title>
      <dc:creator>Bruno Pinheiro</dc:creator>
      <pubDate>Wed, 14 Jun 2023 16:55:53 +0000</pubDate>
      <link>https://forem.com/brunofpinheiro/using-the-richardson-maturity-model-to-improve-your-apis-1k99</link>
      <guid>https://forem.com/brunofpinheiro/using-the-richardson-maturity-model-to-improve-your-apis-1k99</guid>
      <description>&lt;p&gt;It doesn't matter what kind of developer you are, if you write APIs or would like to learn, you should know who Leonard Richardson is and how he can help you.&lt;/p&gt;

&lt;p&gt;I’m more of a front-end developer, and just recently started writing APIs, so I had no idea who Richardson was until a while ago. Leonard Richardson is an expert on restful API design who proposed in 2008, a maturity model for REST services. The idea is to grade the services based on how much they comply with the constraints of REST.&lt;/p&gt;

&lt;p&gt;He proposed a maturity model consisting of four levels. It goes from level 0, which is the most basic implementation of a service, all the way up to level 3, which means the service is totally REST compliant.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How does it work?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Level 0&lt;/strong&gt;&lt;br&gt;
Services at this level will use HTTP basically as a tunneling mechanism for remote interactions. They will have a single URI for all interactions and won’t use the correct HTTP verbs, typically using POST for everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 1 - Resources&lt;/strong&gt;&lt;br&gt;
At this level the services improve a bit, having separate URIs for different interactions. The use of HTTP verbs (or in this case, the lack of it) remains the same.&lt;br&gt;
Only by separating resources among different URIs the services are already a lot better than those at level 0, but can't be considered RESTFUL yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 2 - HTTP verbs&lt;/strong&gt;&lt;br&gt;
This is where the majority of services are. At this level, they use separate URIs for the many resources, and the correct HTTP verbs, not simply spamming POST for everything.&lt;/p&gt;

&lt;p&gt;But here we have a little controversy. Some say that reaching this level of maturity is already enough to call this service RESTFUL, while others say that you can only claim that at level 3. Either way, at this level you have much more mature services that are easier to use and understand from the documentation.&lt;/p&gt;

&lt;p&gt;Say you are developing endpoints for a company that sells video games. One of the first things you may need is to show a list of available titles. For that, you can make a GET request to an endpoint like this: &lt;code&gt;/api/v1/games&lt;/code&gt;. Simple as that.&lt;/p&gt;

&lt;p&gt;Now say that a new game was released and you need to add it to the company's catalog. You can use a POST request to &lt;code&gt;/api/v1/games/&lt;/code&gt; and pass the game’s information on the request.&lt;/p&gt;

&lt;p&gt;Sales season is coming and you need to update the price? No problem, just do something like this &lt;code&gt;PUT: /api/v1/games/{id}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Something won’t be sold anymore? Maybe this will help &lt;code&gt;DELETE: /api/v1/games/{id}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Did you notice that to edit and delete you can basically use the same URI, changing only the HTTP verb? That makes it easier to understand what is going on. Using the correct HTTP verbs allows you to write much cleaner endpoints.&lt;/p&gt;

&lt;p&gt;Maybe you’ve seen something like this for a CRUD:&lt;br&gt;
&lt;code&gt;/api/v1/games/listAll&lt;br&gt;
/api/v1/new/game&lt;br&gt;
/api/v1/edit/game/{id}&lt;br&gt;
/api/v1/delete/game/{id}&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
I don’t know about you, but for me, this kind of naming is more confusing and harder to read.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;How to improve it?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By using the first approach you can have shorter URIs and even use the same prefix for the entire controller, having even more concise naming. For example, if you use &lt;code&gt;/api/v1/games&lt;/code&gt; for the controller, the other endpoints can look like this:&lt;br&gt;
&lt;code&gt;GET: /&lt;br&gt;
POST: /&lt;br&gt;
PUT: /{id}&lt;br&gt;
DELETE: /{id}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;See what I mean? It’s much cleaner, easier to read, easier to maintain and you even write less code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 3 - Hypermedia&lt;/strong&gt;&lt;br&gt;
The last level introduces the use of hypermedia controls, or HATEOAS (Hypermedia as the engine of application state). The idea here is that the response to a request would hold the information necessary for other operations.&lt;/p&gt;

&lt;p&gt;Let’s say you make a GET request for the list of available games. Besides returning what you requested, the response could also return the URI for updating the price and deleting the game, for example. With this, whoever is consuming the API wouldn’t need to know its endpoints beforehand, they would only need to know the entry point, and the rest would be shown on the responses.&lt;/p&gt;

&lt;p&gt;Another advantage of this is the liberty it gives to the back end to change and evolve if the front end keeps an eye out for these changes. Remember that all the front end needs to know is the entry point, and subsequent steps would be given in the responses. By doing this the backend can change freely without breaking anyone who’s consuming the API, because they will be looking for the data in the responses, not using predefined routes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;And now?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For me, level 2 should be the primary goal of anyone working with APIs. The benefits massively outweigh the complexity of reaching this level of maturity.&lt;/p&gt;

&lt;p&gt;If you want to take your APIs to the next level (literally), the use of hypermedia controls should bring valuable benefits to those building the APIs and those consuming them.&lt;/p&gt;

</description>
      <category>rest</category>
      <category>api</category>
      <category>backend</category>
    </item>
    <item>
      <title>3 ways a Java developer can work with games</title>
      <dc:creator>Bruno Pinheiro</dc:creator>
      <pubDate>Thu, 16 Mar 2023 22:54:02 +0000</pubDate>
      <link>https://forem.com/brunofpinheiro/3-ways-a-java-developer-can-work-with-games-26e0</link>
      <guid>https://forem.com/brunofpinheiro/3-ways-a-java-developer-can-work-with-games-26e0</guid>
      <description>&lt;p&gt;When you'd think about game development what languages come to mind? C++? Maybe C#? But what if you only know Java and want to work in the gaming industry? Is there a way? Will you have to learn another language?&lt;/p&gt;

&lt;p&gt;Yes, there is a way, but it may come out as a surprise: you don't have to work with games to work with games.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Wait, what?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It's exactly what you read. The gaming industry is more than just game development itself. A game, just like any other software, needs some support to be made and delivered.&lt;/p&gt;

&lt;p&gt;For example, you may know how a backend is often used by an app to process data, well, the app could very well be a highly-played mobile game instead of regular boring enterprise software.&lt;/p&gt;

&lt;p&gt;Did you get the idea? You don't have to develop the game itself to work in a game development environment. You could work with several other things, and some of them, you may already be awesome at.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let me give you some examples
&lt;/h2&gt;

&lt;p&gt;I already mentioned the backend. Games, just like other software, often use a separate backend to process some things, maybe access a database to retrieve some data and deliver it back to whoever requested it. Sure, a game can have some characteristics or limitations that differentiate it from 'regular' software, but for you, the backend developer, the basic idea is the same.&lt;/p&gt;

&lt;p&gt;Another opportunity is the website. It could be used for the whole company, just for one game, or even be a landing page for a new game or expansion, either way, it's all web development. Imagine the landing page of an upcoming hyped new game. How many thousand users would see it daily? Did you picture that? Now try to picture yourself reaching all those people. How awesome would that be?&lt;/p&gt;

&lt;p&gt;Do you know what else is often used? E-commerce. It could be used for the players to buy in-game items such as premium subscriptions, expansions, and cosmetic items or maybe it could be used to sell other products from the company, like mugs, shirts, keychains, and that sort of stuff. Either way, if you have worked with e-commerce in the past, then you can work with it again, but in a gaming environment. Think about how many transactions are completed every single day. It could be dozens of thousands, and you could very well be part of it, being valuable to all those people daily.&lt;/p&gt;

&lt;h2&gt;
  
  
  And now what?
&lt;/h2&gt;

&lt;p&gt;This is not just guessing, I went to game development companies' websites and took a look at some of the published Java openings, and I encourage you to do the same. You can find jobs like the ones I've mentioned even in huge companies like Riot Games or Codemasters.&lt;/p&gt;

&lt;p&gt;So why don't you take a look? Chances are you are a lot closer to working with games than you think.&lt;/p&gt;

</description>
      <category>discipline</category>
      <category>productivity</category>
      <category>sideprojects</category>
    </item>
  </channel>
</rss>
