<?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: Emre Savcı</title>
    <description>The latest articles on DEV Community by Emre Savcı (@mstryoda).</description>
    <link>https://dev.to/mstryoda</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%2F324395%2F685e70d0-8b8c-4bc2-89ce-39195fa0cace.jpg</url>
      <title>DEV Community: Emre Savcı</title>
      <link>https://dev.to/mstryoda</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mstryoda"/>
    <language>en</language>
    <item>
      <title>Troubleshooting Kubernetes Application - Istio Service Mesh Upstream Connect Error</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Sat, 10 Jun 2023 20:55:00 +0000</pubDate>
      <link>https://dev.to/mstryoda/troubleshooting-kubernetes-application-istio-service-mesh-upstream-connect-error-3b5f</link>
      <guid>https://dev.to/mstryoda/troubleshooting-kubernetes-application-istio-service-mesh-upstream-connect-error-3b5f</guid>
      <description>&lt;p&gt;Hello everyone, in this article I will explain how did we troubleshoot a network error between our microservices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🚀 Service Mesh in Trendyol&lt;br&gt;
❌ Error Case&lt;br&gt;
📝 Determining Troubleshooting Paths&lt;br&gt;
🚨 Reproducing the Error&lt;br&gt;
🕵️ Sniffing the Pod Network&lt;br&gt;
🔍 Inspecting Code&lt;br&gt;
✅ Problem and Solution&lt;br&gt;
📚 Conclusion&lt;/p&gt;


&lt;h2&gt;
  
  
  Service Mesh in Trendyol 🚀
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0prjg33st80havskwwd8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0prjg33st80havskwwd8.png" alt="Image description" width="431" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Trendyol, our microservice applications run in Kubernetes along with service mesh Istio. We have thousands of clusters, almost ~200K pods running on it.&lt;/p&gt;

&lt;p&gt;We empower microservices with the help of service mesh features like service authorization, load balancing, weighted request routing, traffic mirroring, interrupting incoming and outgoing requests, manipulating request flows etc.&lt;/p&gt;

&lt;p&gt;Beyond that, we are extending our service mesh functionality by leveraging Envoy’s extensibility features as we described in &lt;a href="https://medium.com/trendyol-tech/extending-envoy-proxy-wasm-filter-with-golang-9080017f28ea"&gt;Envoy Wasm Filters&lt;/a&gt; article.&lt;/p&gt;

&lt;p&gt;If you wonder more about Trendyol infrastructure, you can take a look our infra metrics publicly &lt;a href="https://inframetrics.trendyol.com/"&gt;on here&lt;/a&gt;.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://inframetrics.trendyol.com/d/gP0c_Sc7z/home?orgId=1&amp;amp;kiosk" rel="noopener noreferrer"&gt;
      inframetrics.trendyol.com
    &lt;/a&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  Error Case ❌
&lt;/h2&gt;

&lt;p&gt;Couple of days ago, we (Platform — Developer Productivity Engineering team) got a support request from one of our domain teams for a microservice that they developed. They described issue as a connectivity problem between a two services. The strange point is the application was facing with issue while sending a request to existing resource (/resources/1) and working correctly on non existing resource (/resources/133).&lt;/p&gt;

&lt;p&gt;To reproduce the error we demanded the example requests and application urls. From now on, I explain the situation and the steps we followed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Determining Troubleshooting Paths 📝
&lt;/h2&gt;

&lt;p&gt;While troubleshooting an error, visualizing the process with big picture helps a lot to reveal overlooked points. So we started to draw the request flow.&lt;/p&gt;

&lt;p&gt;What we know about process is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We have a reverse proxy in-front of Kubernetes&lt;/li&gt;
&lt;li&gt;We have Istio Envoy Proxy in pods&lt;/li&gt;
&lt;li&gt;We have two service that run in Kubernetes and access each-others&lt;/li&gt;
&lt;li&gt;Gateway service handles the request and makes a call to an API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s see the big picture 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3fjhd78khdv4kvt1ort.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3fjhd78khdv4kvt1ort.png" alt="Image description" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a user make a request to a URL, it is handled by Tengine and then Tengine forwards request to the cluster, request first handled via Istio Ingress Gateway inside clusters. Inside the pod, request handled by istio-proxy (Envoy) container and then forwarded to the application container.&lt;/p&gt;

&lt;p&gt;Now we can ready to dig in.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reproducing the Error 🚨
&lt;/h2&gt;

&lt;p&gt;According to those informations, we started to eliminate components one by one. First we sent requests by bypassing load balancer (Tengine). Because we now that load-balancer can access to Kubernetes because it works on some requests to the same URL.&lt;/p&gt;

&lt;p&gt;So we are now removed the Tengine from big picture 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kl4di6m7hi8p7plvf50.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kl4di6m7hi8p7plvf50.png" alt="Image description" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We directly sent requests to the Kubernetes cluster’s ip address and Istio Ingress Gateway port. To be sure about Istio configuration, we also sent direct requests to NodePort port of our service, this bypasses Istio Ingress Gateway from our request flow.&lt;/p&gt;

&lt;p&gt;But either way, we faced with the same following result 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0nyfs9132p6p63e2llc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0nyfs9132p6p63e2llc.png" alt="Image description" width="720" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The error says “upstream connect error or disconnect/reset before headers. reset reason: connection termination”.&lt;/p&gt;

&lt;p&gt;We wanted to sure that our upstream API works correctly, so we removed the gateway from the picture and we directly sent requests to the API 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7mbodt95kg9eksgsp8t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7mbodt95kg9eksgsp8t.png" alt="Image description" width="720" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We got our responses successfully for both existing and non existing resources while sending direct requests to the API.&lt;/p&gt;

&lt;p&gt;After bunch of request combinations to the both gateway and API, we began considering the likelihood of an error occurring within the communication of the gateway pod.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sniffing the Pod Network 🕵️
&lt;/h2&gt;

&lt;p&gt;We could not find any reason to this error just by outlooking by sending requests. We decided to sniff the gateway pod’s network and see whats going on.&lt;/p&gt;

&lt;p&gt;Thanks to the wonderful kubectl plugin named “&lt;a href="https://github.com/eldadru/ksniff"&gt;ksniff&lt;/a&gt;” we easily sniff our network and track it on Wireshark.&lt;/p&gt;

&lt;p&gt;To sniff our pod network let’s run the kubectl command below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl sniff pod-name -f 'tcp[tcpflags] &amp;amp; (tcp-syn|tcp-fin|tcp-rst|tcp-push)!=0'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When we start sniffing it opens up a Wireshark with bunch of package traces like in the following screenshot👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg707b8wto61h7deyb2n9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg707b8wto61h7deyb2n9.png" alt="Image description" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, it contains a lot of unnecessary informations, we need to track a specific request flow.&lt;/p&gt;

&lt;p&gt;We started to send couple of different requests to the application to see whats happening on the network so we can filter out easily by typing a filter like &lt;code&gt;http.request.full_uri contains “/eligibility”&lt;/code&gt; and this shows us filtered requests👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1qesuqielimbq26hp8sn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1qesuqielimbq26hp8sn.png" alt="Image description" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now we can select a request and follow it’s HTTP or TCP stream by right clicking on it 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltll046esmxgdgb1dbsx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltll046esmxgdgb1dbsx.png" alt="Image description" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now when we follow this process on our invalid request, we can easily see that our TCP stream does not contain any error 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuci82i31f3aw6ljp7lj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuci82i31f3aw6ljp7lj4.png" alt="Image description" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we do the same thing on the failed responses, we faced with the following screen👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96npnbh9eyii3e9sbwut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96npnbh9eyii3e9sbwut.png" alt="Image description" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see there is a big difference between two TCP stream. Failed stream contains [RST] flag. This means that somehow the application causes to close connection with istio-proxy (Envoy).&lt;/p&gt;

&lt;p&gt;We can actually see that our gateway application communicates with the Eligibility API.&lt;/p&gt;

&lt;p&gt;So we can downgrade the error scope to the only gateway application pod. There must be something between gateway container and istio-proxy (Envoy) container.&lt;/p&gt;




&lt;h2&gt;
  
  
  Inspecting Code 🔍
&lt;/h2&gt;

&lt;p&gt;Finally we ended up with the idea of there must be a difference between response flows of this application.&lt;/p&gt;

&lt;p&gt;There is one thing to take a look: code difference between the error and success responses.&lt;/p&gt;

&lt;p&gt;When we took a look to source code of gateway application, we notices that application has a global error handler which returns a fresh new response object created by handler.&lt;/p&gt;

&lt;p&gt;BUT…&lt;/p&gt;

&lt;p&gt;In the controller requests are sent by Feign Client to the API application and the response is directly return to the caller ⚠️&lt;/p&gt;

&lt;p&gt;We found the reason of the error is because of this behavior of the controller. It corrupting the response header which expected by istio-proxy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem and Solution ✅
&lt;/h2&gt;

&lt;p&gt;Here is the problematic code that we saw in the controller 👇&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@GetMapping("/some/path")
public ResponseEntity&amp;lt;Response&amp;gt; getResponse(
    @RequestParam(name = "id", required = false) Integer id) 
{
    return externalApiClient.get(id); //directly returning the ResponseEntity&amp;lt;Response&amp;gt; from Feign client
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We made a tiny change to fix this issue, just by wrapping the response body of the API call request with a newly created Response object👇&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@GetMapping("/some/path")
public ResponseEntity&amp;lt;Response&amp;gt; getResponse(
            @RequestParam(name = "id", required = false) Integer id)
{
    return ResponseEntity.ok(externalApiClient.get(id).getBody());  //creating a fresh new  ResponseEntity&amp;lt;Response&amp;gt; from Feign client response body
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It fixed all of our issues.&lt;/p&gt;

&lt;p&gt;Just because we got this issue in Java it does not mean that you may not encounter it in another language. This problem is language agnostic. You may encounter it in Go, C# or any other language as well.&lt;/p&gt;

&lt;p&gt;Remember the main reason of this issue is directly returning response headers too of external requests. You need to create a custom response 👍&lt;/p&gt;


&lt;h2&gt;
  
  
  Conclusion 📚
&lt;/h2&gt;

&lt;p&gt;We made couple of inferences after resolving this problem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do not directly proxy responses of your external requests to the caller, wrap it with custom response&lt;/li&gt;
&lt;li&gt;Code implementation may vary over different flows, do not make assumptions&lt;/li&gt;
&lt;li&gt;Always try to make your application observable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We learned a lot while investigating this issue. Thanks a lot to my team mates Onur Yilmaz and Gokhan Karadas.&lt;/p&gt;

&lt;p&gt;I hope you find this article entertaining and informative. Thanks for your attention, happy coding ⌨️&lt;/p&gt;



&lt;p&gt;Ready to take your career to the next level? Join our dynamic team and make a difference at Trendyol.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://jobs.lever.co/trendyol" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--pJwifdDA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lever-client-logos.s3.us-west-2.amazonaws.com/a81a734c-54a8-4378-85ba-2eee13010fb6-1694179942661.png" height="315" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://jobs.lever.co/trendyol" rel="noopener noreferrer" class="c-link"&gt;
          Trendyol
        &lt;/a&gt;
      &lt;/h2&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
        jobs.lever.co
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>kubernetes</category>
      <category>programming</category>
      <category>microservices</category>
      <category>devops</category>
    </item>
    <item>
      <title>Golang -What is Broken Pipe Error? Tcp Http Connections and Pools</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Mon, 06 Feb 2023 13:39:48 +0000</pubDate>
      <link>https://dev.to/mstryoda/golang-what-is-broken-pipe-error-tcp-http-connections-and-pools-4699</link>
      <guid>https://dev.to/mstryoda/golang-what-is-broken-pipe-error-tcp-http-connections-and-pools-4699</guid>
      <description>&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%2Fkd1a4taynpbs0jp3fczs.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%2Fkd1a4taynpbs0jp3fczs.png" alt="https://content.techgig.com/technology-guide/5-top-advantages-of-using-golang-programming-language/articleshow/82278297.cms" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you ever encountered a "broken pipe" error in the applications you have developed, during database operations or when making requests to the systems you have connected over the network?&lt;/p&gt;

&lt;p&gt;In this article, we will look at the causes and solutions of some errors that you may encounter in network operations while using Golang, wherever TCP connection is established. These network operations can be operations that you perform by establishing a database connection or by making an HTTP request.&lt;/p&gt;

&lt;p&gt;Although Golang is mentioned in the topic and content, you can apply the explained approach here in many programming languages. You can even apply the approaches to be explained when designing a system, communicating with multiple applications, using Reverse Proxy, Load Balancer, and client-server communications.&lt;/p&gt;




&lt;h2&gt;
  
  
  Connection Pools are Everywhere
&lt;/h2&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%2Fr5an3lsfnwwhvecxvu5n.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%2Fr5an3lsfnwwhvecxvu5n.png" alt="connection pool by Emre Savcı" width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most application developers that make network communication use the connection pool structure consciously or unconsciously. Because it is a costly operation to open TCP connections over and over, "pool" structures are well suited to improve application performance and resource utilization. HTTP packets, database drivers or libraries, web frameworks, load balancers and reverse proxies, in short, most systems that communicate via TCP in the background (if there is no inherent contradiction) embrace "connection pool".&lt;/p&gt;




&lt;h2&gt;
  
  
  HTTP Client - Server Communication with Golang
&lt;/h2&gt;

&lt;p&gt;Let's take a look at how a connection pool has a place in HTTP operations and how it is used in the Golang HTTP package.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP Keep Alive
&lt;/h2&gt;

&lt;p&gt;When you write an HTTP server with Go and send a request via a standard Go HTTP client, the opened "connection" will be stored on a pool to be used again in future requests, unless you specify otherwise.&lt;/p&gt;

&lt;p&gt;Now let's create a simple HTTP server instance with the following code:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The server is running on the "8080" port, and it outputs the connection statuses on the server with the ConnState function as console output.&lt;/p&gt;

&lt;p&gt;Now let's write the HTTP client code to send our request:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We use the httptrace package to monitor client connection status. The thing to note here is that the http response is read completely with the &lt;code&gt;io.ReadAll()&lt;/code&gt; function. If we do not do this, the connection keep-alive function will not be performed.&lt;/p&gt;

&lt;p&gt;Let's run our server and client code and look at the outputs:&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%2F60yyxwems8m4hx1x8ehv.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%2F60yyxwems8m4hx1x8ehv.png" alt="server.go" width="800" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our server application prints the connection status as &lt;strong&gt;New&lt;/strong&gt; for the first request and remains &lt;strong&gt;Active&lt;/strong&gt; throughout the request. When the request is completed, the opened connections switches to the &lt;strong&gt;Idle&lt;/strong&gt; state.&lt;/p&gt;

&lt;p&gt;Subsequent requests switch between &lt;strong&gt;Active&lt;/strong&gt; and &lt;strong&gt;Idle&lt;/strong&gt; states. Because a new connection is not opened, the first connection is used again and again.&lt;/p&gt;

&lt;p&gt;Let's look at the output of our Client application during this process:&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%2Foxietf8thazg4fv6j5ue.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%2Foxietf8thazg4fv6j5ue.png" alt="client.go" width="800" height="652"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the first request is sent, we see that the &lt;strong&gt;connection start&lt;/strong&gt; process takes place. When the request is completed, the connection switches to the Idle state and the same connection is used again for subsequent requests.&lt;/p&gt;

&lt;p&gt;Go maintains a connection pool on the &lt;strong&gt;Transport&lt;/strong&gt; type within the HTTP client.&lt;/p&gt;

&lt;p&gt;In the screenshot below, we can see the idle conn pool in the Transport definition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Transport&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;idleMu&lt;/span&gt;       &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;
   &lt;span class="n"&gt;closeIdle&lt;/span&gt;    &lt;span class="kt"&gt;bool&lt;/span&gt;                                &lt;span class="c"&gt;// user has requested to close all idle conns&lt;/span&gt;
   &lt;span class="n"&gt;idleConn&lt;/span&gt;     &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;connectMethodKey&lt;/span&gt;&lt;span class="p"&gt;][]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;persistConn&lt;/span&gt; &lt;span class="c"&gt;// most recently used at end&lt;/span&gt;
   &lt;span class="n"&gt;idleConnWait&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;connectMethodKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;wantConnQueue&lt;/span&gt;  &lt;span class="c"&gt;// waiting getConns&lt;/span&gt;
   &lt;span class="n"&gt;idleLRU&lt;/span&gt;      &lt;span class="n"&gt;connLRU&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Idle Connection Settings
&lt;/h2&gt;

&lt;p&gt;If we want, we can make various settings for idle connections on both client and server.&lt;/p&gt;

&lt;p&gt;We can make the following settings for idle connections to be kept on the HTTP client:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Transport&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Transport&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;DisableKeepAlives&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;MaxIdleConns&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;MaxIdleConnsPerHost&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;IdleConnTimeout&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="m"&gt;60&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;DisableKeepAlives&lt;/strong&gt; : Does not maintain keep alive connections if set as true&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MaxIdleConns&lt;/strong&gt; : Total connection number can be hold on Transport&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MaxIdleConnsPerHost&lt;/strong&gt; : Total connection number can be hold for a specific host on Transport&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IdleConnTimeout&lt;/strong&gt; : Idle connection timeout on the pool&lt;/p&gt;


&lt;h2&gt;
  
  
  Creating a TCP Connection in Golang
&lt;/h2&gt;

&lt;p&gt;We made a quick introduction to the connection pool structure with HTTP requests and saw its implementation on a real example.&lt;/p&gt;

&lt;p&gt;Now let's create a TCP server ourselves and establish a connection.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;We created a TCP server listening on port 8080 with the Golang &lt;strong&gt;net&lt;/strong&gt; package. And we processed all incoming connections with a goroutine.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We created a client that makes TCP connection requests using the &lt;strong&gt;net&lt;/strong&gt; package. We sent the hello data over the connection we created in the loop.&lt;/p&gt;

&lt;p&gt;Now let's run our program and look at the application outputs.&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%2Fkn4lon2bkuv1pl7dyttl.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%2Fkn4lon2bkuv1pl7dyttl.png" alt="tcp-server.go" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We ran our server application and immediately after that we also ran our client application. Our server application has received a new request and printed the received data to the screen.&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%2Fexhm1h305trl5jxzxkp3.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%2Fexhm1h305trl5jxzxkp3.png" alt="tcp-client.go" width="800" height="549"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our client application also successfully wrote the size of the data it sent to the screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Broken Pipe Error
&lt;/h2&gt;

&lt;p&gt;So what happens if we close our server application while both applications are running?&lt;/p&gt;

&lt;p&gt;Now, after running the example above, let's end the server application for a while and look at the output.&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%2Fy9cb582pa9e7ydbqeo31.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%2Fy9cb582pa9e7ydbqeo31.png" alt="tcp-client.go" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After closing our server application, our client application gives an output as above.&lt;/p&gt;

&lt;p&gt;After the server is shut down, our client application encounters an error as seen. The error message appears exactly as &lt;code&gt;write tcp 127.0.0.1:58766-&amp;gt;127.0.0.1:8080: write: broken pipe&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As it can be understood from here, if an opened TCP connection is closed by the server, it cannot be notified until the client side writes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lets Create Our Own TCP Connection Pool
&lt;/h2&gt;

&lt;p&gt;We have seen how the Broken pipe error happens. If an opened TCP connection is closed by the server while it is still in use, client applications receive an error as expected.&lt;/p&gt;

&lt;p&gt;Let's create a connection pool to bring this error closer to real life examples.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This is quite basic pool. Let's run our client application again.&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%2F4fo13hlegmb2uc29zmdf.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%2F4fo13hlegmb2uc29zmdf.png" alt="tcp-client-pool.go" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we close the server after a while after running the client application, we see that the connection received from the pool on the client side encounters with a &lt;strong&gt;broken pipe&lt;/strong&gt; error.&lt;/p&gt;

&lt;p&gt;In our examples we are talking about closing the server application, but this may not always be the case. In fact, the important thing here is to close the &lt;strong&gt;connection&lt;/strong&gt; on the server side.&lt;/p&gt;

&lt;p&gt;An idle timeout value can be given for connections created on the server side, and the connections of requests that are satisfied after a certain period of time can be closed automatically.&lt;/p&gt;

&lt;p&gt;In such a case, a connection opened and used by the client and stored in the idle pool may be closed by the server. In such a scenario, the client will encounter a &lt;strong&gt;broken pipe&lt;/strong&gt; error when trying to reuse the connection from the idle pool.&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%2Fr4h544fw4243k3rclj8r.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%2Fr4h544fw4243k3rclj8r.png" alt="broken pipe - by emre savcı" width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Where can we encounter with this broken pipe error?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database Connections&lt;/strong&gt;: The libraries we use while connecting to databases can contain pools. We may use packages containing pools. In this case, we should consider that we may receive an error on the application side against the idle connections closed by the database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reverse Proxy &amp;amp; Load Balancer Applications&lt;/strong&gt;: Many reverse proxies and load balancer applications have a connection pool structure on their own. In the configuration of such applications, the idle connection timeout values must be less than the timeout value specified on the server side, so that the connection is terminated by the client before the server shuts down.&lt;/p&gt;

&lt;p&gt;See you on the next article, I wish the bug free developments to all of you.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Let's Connect:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://twitter.com/mstrYoda_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mstrYoda" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can support me on Github: &lt;a href="https://github.com/sponsors/mstrYoda/" rel="noopener noreferrer"&gt;Support mstrYoda on Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>web3</category>
      <category>announcement</category>
      <category>devto</category>
      <category>offers</category>
    </item>
    <item>
      <title>No-Code Tools For Your Next SaaS &amp; Side-Project</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Tue, 06 Dec 2022 13:25:07 +0000</pubDate>
      <link>https://dev.to/mstryoda/no-code-tools-for-your-next-saas-side-project-3fp2</link>
      <guid>https://dev.to/mstryoda/no-code-tools-for-your-next-saas-side-project-3fp2</guid>
      <description>&lt;p&gt;Hi all, hope you are well 👋 In this post I will introduce you couple of no-code tools that might help you to create your next SaaS or side-project. Now let's take a look into  no-code tools 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  AirTable
&lt;/h2&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%2Fsidpw4vu3az3u332oe4h.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%2Fsidpw4vu3az3u332oe4h.png" alt="airtable" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our first tool is &lt;a href="https://airtable.com" rel="noopener noreferrer"&gt;AirTable&lt;/a&gt;, which is known and used by many as a database tool.&lt;/p&gt;

&lt;p&gt;AirTable allows you to create various databases, workflows, charts where you can store your data 💪&lt;/p&gt;




&lt;h2&gt;
  
  
  BaseRow
&lt;/h2&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%2Ftxy4o64t2jvim66x18pk.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%2Ftxy4o64t2jvim66x18pk.png" alt="baserow" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another no-code database platform is &lt;a href="https://baserow.io" rel="noopener noreferrer"&gt;BaseRow&lt;/a&gt;. They advertise themselves as AirTable alternative 💪&lt;/p&gt;




&lt;h2&gt;
  
  
  Notion
&lt;/h2&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%2Fm2mld6baeomr5y4heyeb.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%2Fm2mld6baeomr5y4heyeb.png" alt="notion" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am using Notion in my daily basis. It is quite helpful to organize my notes, ToDo lists, even my schedule on a calendar view 💪&lt;/p&gt;

&lt;p&gt;Although it is not a database product we can use it as, if we want, we can also open a database page and keep our data on &lt;a href="//notion.so"&gt;Notion.so&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  AwesomeTable
&lt;/h2&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%2Fm0y1lqh4jk9biwix06ny.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%2Fm0y1lqh4jk9biwix06ny.png" alt="awesometable" width="800" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What if you want to use the Google Sheet data on your site as a data source, instead of creating a database from scratch?&lt;/p&gt;

&lt;p&gt;Here we come across a very nice product &lt;a href="https://awesome-table.com" rel="noopener noreferrer"&gt;AwesomeTable&lt;/a&gt;. It allows us to connect our existing Google Sheets and create a website based on that data 💪&lt;/p&gt;




&lt;h2&gt;
  
  
  ParseHub
&lt;/h2&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%2Fy9zse6vadfur28b0h9ds.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%2Fy9zse6vadfur28b0h9ds.png" alt="ParseHub" width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes you may need data collection (crawling) from various websites and in that case if you don't know how to code &lt;a href="https://parsehub.com" rel="noopener noreferrer"&gt;ParseHub&lt;/a&gt; will help you about it 💪&lt;/p&gt;




&lt;h2&gt;
  
  
  GlideApps
&lt;/h2&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%2Ff3q5k3dwb3qwryrfzd6r.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%2Ff3q5k3dwb3qwryrfzd6r.png" alt="glideapps" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's say you want to create a mobile application with the data that you already have.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://glideapps.com" rel="noopener noreferrer"&gt;glideapps.com&lt;/a&gt; is a product that transforms your data from various sources such as Google Sheets, Airtable, Excel, BigQuery into a mobile application 💪&lt;/p&gt;




&lt;h2&gt;
  
  
  WebFlow
&lt;/h2&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%2Fukm57ct2rw59xr48930h.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%2Fukm57ct2rw59xr48930h.png" alt="webflow" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All that's left is to create your website. For this, I will share 2 different tools. The first of these is &lt;a href="http://webflow.io" rel="noopener noreferrer"&gt;WebFlow.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It offers the opportunity to create a free design using its own editor and publish it under the webflow.io domain 💪&lt;/p&gt;




&lt;h2&gt;
  
  
  Pory
&lt;/h2&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%2Fqujxpe5w03wn71yqr7ra.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%2Fqujxpe5w03wn71yqr7ra.png" alt="Pory" width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another website creation tool is &lt;a href="https://pory.io" rel="noopener noreferrer"&gt;Pory.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can create your website using your existing data by importing them from different data sources such as Airtable and Notion 💪&lt;/p&gt;




&lt;p&gt;Now we have almost everything to quickly create our next SaaS product or side-project 🚀 Let's create a website, a landing page, create contents like blog posts, collect some data, visualize them in website and create a mobile application using that data. Good luck 🎉&lt;/p&gt;

</description>
      <category>design</category>
    </item>
    <item>
      <title>Golang Blazing Fast Unit Tests - Fiber/fasthttp/http Internals and Optimizing HTTP Server Tests</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Mon, 12 Sep 2022 07:35:46 +0000</pubDate>
      <link>https://dev.to/mstryoda/golang-blazing-fast-unit-tests-fiberfasthttphttp-internals-and-optimizing-http-server-tests-4i7p</link>
      <guid>https://dev.to/mstryoda/golang-blazing-fast-unit-tests-fiberfasthttphttp-internals-and-optimizing-http-server-tests-4i7p</guid>
      <description>&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%2F1689fqydeywmfxbf2wxy.png" 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%2F1689fqydeywmfxbf2wxy.png" alt="greeting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Greetings, in this article, I will tell you how we can increase the test performance of our HTTP servers in the projects we have developed with Go.&lt;/p&gt;

&lt;p&gt;Recently, while I was working on a new feature for an application we were developing, I realized that I could commute to get coffee while waiting for unit tests to complete. And it was not possible to run the tests in parallel. If we wanted to run it in parallel in its current form, this test period could have taken much longer.&lt;/p&gt;

&lt;p&gt;Now, let's take a brief look at the content and move on to the details of our subject.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contents
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Go HTTP Internals
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;http.ListenAndServe&lt;/li&gt;
&lt;li&gt;net.Conn &amp;amp; net.Listener&lt;/li&gt;
&lt;li&gt;http.Client Dial Function&lt;/li&gt;
&lt;li&gt;net.Pipe&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing in Different Packages
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Fiber
&lt;/h4&gt;

&lt;p&gt;- app.Test Internals&lt;br&gt;
- app.ServeConn&lt;/p&gt;
&lt;h4&gt;
  
  
  fasthttp
&lt;/h4&gt;

&lt;p&gt;- fasthttputil.NewInmemoryListener&lt;/p&gt;
&lt;h4&gt;
  
  
  Go HTTP
&lt;/h4&gt;

&lt;p&gt;- httptest.NewUnstartedServer&lt;br&gt;
- Mock InMemListener Example&lt;/p&gt;
&lt;h4&gt;
  
  
  Our Test Performance Improvement
&lt;/h4&gt;
&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;


&lt;h2&gt;
  
  
  Go HTTP Internals
&lt;/h2&gt;

&lt;p&gt;Let's take a look at what we need to do when we want to run a simple HTTP server with the Go language.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  http.ListenAndServe
&lt;/h3&gt;

&lt;p&gt;When we want to run a server that we wrote using the Go standard library, we use the ListenAndServe method.&lt;/p&gt;

&lt;p&gt;Let's take a look at the details of the &lt;strong&gt;ListenAndServe&lt;/strong&gt; method:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now let's look at the details of the &lt;strong&gt;server.ListenAndServe()&lt;/strong&gt; method:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Finally, let's look at the details of the &lt;strong&gt;srv.Serve(ln)&lt;/strong&gt; method. I've removed some code so it's not too long.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The part that we should pay attention to here is the &lt;strong&gt;l.Accept&lt;/strong&gt; method.&lt;/p&gt;

&lt;p&gt;The summary of the process done in the codes I have shared so far is actually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;http.ListenAndServe method creates a server in the background and server ListenAndServe method is run&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The server creates a net.Listener object that accepts a request from the port specified by the &lt;code&gt;net.Listen("tcp", addr)&lt;/code&gt; method call and runs the Serve method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Serve method acts on the net.Conn object that represents the new incoming connections with the &lt;code&gt;Accept()&lt;/code&gt; method of the net.Listener object that it receives as a parameter.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So far, we have seen the process of creating an API in its basic form.&lt;/p&gt;

&lt;p&gt;Now, I can hear you slowly saying, "Well, sir, what will they do in real life?"&lt;/p&gt;

&lt;p&gt;Don't worry, we'll soon see how we can improve our testing performance using this information.&lt;/p&gt;

&lt;h3&gt;
  
  
  net.Listen &amp;amp; net.Conn
&lt;/h3&gt;

&lt;p&gt;Now let's take a closer look at these two basic types included in the HTTP package.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We see that these two types are actually interfaces.&lt;/p&gt;

&lt;p&gt;Well, what does it mean? We can give special structs that we implement these interfaces as parameters to methods that expect these interface types as parameters. This is an important point for us.&lt;/p&gt;

&lt;h3&gt;
  
  
  http.Client Dial Function
&lt;/h3&gt;

&lt;p&gt;Now let's look at how the http.Client object is used, which allows us to make HTTP requests with Go.&lt;br&gt;
There are two methods of sending requests using the Go HTTP package.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first method is to use the &lt;strong&gt;http.Get http.Post&lt;/strong&gt; methods directly&lt;/li&gt;
&lt;li&gt;The second method is to use the http.Client object &lt;code&gt;resp, _ := http.Get("http://localhost:8080/test")&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Actually, the first method, http.Get, also uses the http.Client object in the background.&lt;br&gt;
Let's take a brief look:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In other words, both methods do the same thing in the background.&lt;/p&gt;

&lt;p&gt;Now let's look at the fields that we can customize when creating the &lt;strong&gt;http.Client&lt;/strong&gt; object.&lt;/p&gt;

&lt;p&gt;http.Client provides all connection establishment processes with &lt;strong&gt;RoundTripper&lt;/strong&gt; interface. And it uses the &lt;strong&gt;Transport&lt;/strong&gt; object as a RoundTripper implementation in itself.&lt;/p&gt;

&lt;p&gt;If we want, we can create this Transport object ourselves when creating http.Client.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The Transport object we created has a method called &lt;strong&gt;DialContext&lt;/strong&gt;. This method is the method that enables connection opening in the background, it returns a value of type &lt;strong&gt;net.Conn&lt;/strong&gt; as a variable.&lt;/p&gt;

&lt;p&gt;In a moment, we will combine this information and the information that the server.Serve method we just saw is listening for connections with net.Conn using the accept method of the net.Listener variable that takes as a parameter.&lt;/p&gt;

&lt;p&gt;Little by little the pieces are falling into place, aren't they?&lt;/p&gt;




&lt;h3&gt;
  
  
  net.Pipe
&lt;/h3&gt;

&lt;p&gt;Finally, there is another method I would like to mention: &lt;code&gt;net.Pipe()&lt;/code&gt;. It returns two net.Conn type variables as return value.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;One of these variables can be used as a writing point and the other as a reading point. So what does this mean? How can we use this?&lt;/p&gt;

&lt;p&gt;If you remember, the &lt;strong&gt;Listen()&lt;/strong&gt; method of the Listener object returned the variable &lt;strong&gt;net.Conn&lt;/strong&gt;. The &lt;strong&gt;Dial()&lt;/strong&gt; method of the HTTP client Transport object also returns the variable &lt;strong&gt;net.Conn&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Starting from here, when we give one end of the connections returned by the &lt;code&gt;net.Pipe()&lt;/code&gt; method to the &lt;strong&gt;Dial&lt;/strong&gt; method of our HTTP client and the other end to the &lt;code&gt;Listen&lt;/code&gt; method of our &lt;strong&gt;Listener&lt;/strong&gt; object, the request we made with the HTTP client will create the connection expected by the &lt;strong&gt;Listener&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing in Different Packages
&lt;/h2&gt;

&lt;p&gt;Now, let's create an API using several different web application libraries common in the Go language and write tests for them.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/gofiber/fiber" rel="noopener noreferrer"&gt;Fiber&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;First, let's take a look at the Fiber library, which we often use in our projects and to which I contribute.&lt;/p&gt;

&lt;p&gt;Writing a test with Fiber is quite simple because it contains a direct Test method.&lt;/p&gt;

&lt;p&gt;Now let's look at a sample Fiber application and how it was tested:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here we need to pay attention to the line &lt;code&gt;app.Test(r, -1)&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;We're sending our HTTP request here so we can test it.&lt;br&gt;
So how did this HTTP request go without calling &lt;code&gt;app.Listen(":8080")&lt;/code&gt; which we normally do to run a Fiber application and make it listen on a port?&lt;/p&gt;

&lt;p&gt;Let's take a look at what's behind the &lt;code&gt;app.Test()&lt;/code&gt; method (you can access all the code &lt;a href="https://github.com/gofiber/fiber/blob/master/app.go/#L845" rel="noopener noreferrer"&gt;here&lt;/a&gt;):&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When we examine the code, we see that Fiber actually creates its own connection objects by &lt;code&gt;conn := new(testConn)&lt;/code&gt; in order to test the application, as we explained in the &lt;code&gt;net.Pipe()&lt;/code&gt; section. &lt;br&gt;
It writes the HTTP request to this conn object and sends this conn object to the server with the &lt;code&gt;app.server.ServeConn(conn)&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;So what happens when we say &lt;code&gt;app.Listen(":8080")&lt;/code&gt; in Fiber app normally? Let's take a quick look at this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here we see that Fiber does the &lt;code&gt;net.Listen()&lt;/code&gt; operation within itself and gives the listener object it created to the server by saying &lt;code&gt;app.server.Serve(ln)&lt;/code&gt;. The server listens to the connections from this listener object and passes it as a parameter to the &lt;code&gt;serveConn()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;In other words, it implements an approach that brings together the Listener and net.Conn objects that we explained at the beginning, allowing us to test it without physically listening to the port.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/gofiber" rel="noopener noreferrer"&gt;
        gofiber
      &lt;/a&gt; / &lt;a href="https://github.com/gofiber/fiber" rel="noopener noreferrer"&gt;
        fiber
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      ⚡️ Express inspired web framework written in Go
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;
  &lt;a href="https://gofiber.io" rel="nofollow noopener noreferrer"&gt;
    
      
      &lt;img height="125" alt="Fiber" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fgofiber%2Fdocs%2Fmaster%2Fstatic%2Fimg%2Flogo.svg"&gt;
    
  &lt;/a&gt;
  &lt;br&gt;
  &lt;a href="https://pkg.go.dev/github.com/gofiber/fiber/v3#pkg-overview" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/5140b60155572122a7d51faf0ddfdcab144059c3b3f2293c548fe94dc3842b53/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f254630253946253933253941253230676f646f632d706b672d3030414344372e7376673f636f6c6f723d303041434437267374796c653d666c61742d737175617265"&gt;
  &lt;/a&gt;
  &lt;a href="https://goreportcard.com/report/github.com/gofiber/fiber/v3" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/8f8a70bdba33b94f6e0c9047416cfa702c70b428aa8ccc342df38ee8c340874a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f254630253946253933253944253230676f7265706f72742d412532422d3735433436423f7374796c653d666c61742d737175617265"&gt;
  &lt;/a&gt;
  &lt;a href="https://codecov.io/gh/gofiber/fiber" rel="nofollow noopener noreferrer"&gt;
   &lt;img alt="Codecov" src="https://camo.githubusercontent.com/9d5c4b9ff98cc7d9d16f9f362a06bba9b144b74d04a27c3cce96d32dc321908d/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f676f66696265722f66696265723f746f6b656e3d33437239324377615051267374796c653d666c61742d737175617265266c6f676f3d636f6465636f76266c6162656c3d636f6465636f76"&gt;
 &lt;/a&gt;
  &lt;a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest" rel="noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/284da195bcf47faf2a0812a7b67deafd4f2315c630f2d1842060b0513b179369/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f676f66696265722f66696265722f746573742e796d6c3f6272616e63683d6d6173746572266c6162656c3d2546302539462541372541412532307465737473267374796c653d666c61742d73717561726526636f6c6f723d373543343642"&gt;
  &lt;/a&gt;
    &lt;a href="https://docs.gofiber.io" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/1d60da00c27ab2ed1e6cfa53607f1b03731c032da17dced80314468c0711e9a3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f25463025394625393225413125323066696265722d646f63732d3030414344372e7376673f7374796c653d666c61742d737175617265"&gt;
  &lt;/a&gt;
  &lt;a href="https://gofiber.io/discord" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/0e6b707fc37c3e2ab8d7b717f2fdc13f41594b835bc59b53eb08124e0b932c3f/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f3730343638303039383537373531343532373f7374796c653d666c61742d737175617265266c6162656c3d254630253946253932254143253230646973636f726426636f6c6f723d303041434437"&gt;
  &lt;/a&gt;
&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;
  &lt;em&gt;&lt;b&gt;Fiber&lt;/b&gt; is an &lt;a href="https://github.com/expressjs/express" rel="noopener noreferrer"&gt;Express&lt;/a&gt; inspired &lt;b&gt;web framework&lt;/b&gt; built on top of &lt;a href="https://github.com/valyala/fasthttp" rel="noopener noreferrer"&gt;Fasthttp&lt;/a&gt;, the &lt;b&gt;fastest&lt;/b&gt; HTTP engine for &lt;a href="https://go.dev/doc/" rel="nofollow noopener noreferrer"&gt;Go&lt;/a&gt;. Designed to &lt;b&gt;ease&lt;/b&gt; things up for &lt;b&gt;fast&lt;/b&gt; development with &lt;a href="https://docs.gofiber.io/#zero-allocation" rel="nofollow noopener noreferrer"&gt;&lt;b&gt;zero memory allocation&lt;/b&gt;&lt;/a&gt; and &lt;b&gt;performance&lt;/b&gt; in mind.&lt;/em&gt;
&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;
⚠️ &lt;strong&gt;Attention&lt;/strong&gt;
&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Fiber v3 is currently in beta and under active development. While it offers exciting new features, please note that it may not be stable for production use. We recommend sticking to the latest stable release (v2.x) for mission-critical applications. If you choose to use v3, be prepared for potential bugs and breaking changes. Always check the official documentation and release notes for updates and proceed with caution. Happy coding! 🚀&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;⚙️ Installation&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Fiber requires &lt;strong&gt;Go version &lt;code&gt;1.22&lt;/code&gt; or higher&lt;/strong&gt; to run. If you need to install or upgrade Go, visit the &lt;a href="https://go.dev/dl/" rel="nofollow noopener noreferrer"&gt;official Go download page&lt;/a&gt;. To start setting up your project. Create a new directory for your project and navigate into…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/gofiber/fiber" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;





&lt;p&gt;&lt;a href="https://github.com/valyala/fasthttp" rel="noopener noreferrer"&gt;fasthttp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We said that Fiber is using the Fasthttp package in the background. If we want, we can develop high-performance API applications directly using the Fasthttp package.&lt;br&gt;
Now let's see how we can test an application we developed with Fasthttp.&lt;/p&gt;

&lt;p&gt;In the code above, we created a simple server and defined a handler, and when a GET request was made to the /test endpoint, we returned the "OK" response.&lt;/p&gt;

&lt;p&gt;Here, unlike the previous code, we see a definition like &lt;code&gt;ln := fasthttputil.NewInmemoryListener()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, we define a http.Client and give the Dial method of the ln variable we created to the DailContext method of the Transport object.&lt;/p&gt;

&lt;p&gt;So does this remind you of anything? Yes, we mentioned above that we can give the net.Listener object to our http.Client variable and test it in-memory. &lt;br&gt;
Fasthttp does exactly this approach with a utility package in the background.&lt;br&gt;
Those who are curious about the details of the code can read it &lt;a href="https://github.com/valyala/fasthttp/blob/master/fasthttputil/inmemory_listener.go" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/valyala" rel="noopener noreferrer"&gt;
        valyala
      &lt;/a&gt; / &lt;a href="https://github.com/valyala/fasthttp" rel="noopener noreferrer"&gt;
        fasthttp
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Fast HTTP package for Go. Tuned for high performance. Zero memory allocations in hot paths. Up to 10x faster than net/http
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;fasthttp &lt;a href="https://pkg.go.dev/github.com/valyala/fasthttp" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1bca3d6fe1adec48c5411fd2d5a75b99c9d2af825bc7fb15f0d7c311656a72a0/68747470733a2f2f706b672e676f2e6465762f62616467652f6769746875622e636f6d2f76616c79616c612f6661737468747470" alt="GoDoc"&gt;&lt;/a&gt; &lt;a href="https://goreportcard.com/report/github.com/valyala/fasthttp" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/dc5b79288750447c35e82be0c85cb94d487a588674773e3247041dacf0993886/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f76616c79616c612f6661737468747470" alt="Go Report"&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/fasthttp/docs-assets/raw/master/banner@0.5.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Ffasthttp%2Fdocs-assets%2Fraw%2Fmaster%2Fbanner%400.5.png" alt="FastHTTP – Fastest and reliable HTTP implementation in Go"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Fast HTTP implementation for Go.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;fasthttp might not be for you!&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;fasthttp was designed for some high performance edge cases. &lt;strong&gt;Unless&lt;/strong&gt; your server/client needs to handle &lt;strong&gt;thousands of small to medium requests per second&lt;/strong&gt; and needs a consistent low millisecond response time fasthttp might not be for you. &lt;strong&gt;For most cases &lt;code&gt;net/http&lt;/code&gt; is much better&lt;/strong&gt; as it's easier to use and can handle more cases. For most cases you won't even notice the performance difference.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;General info and links&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Currently fasthttp is successfully used by &lt;a href="https://vertamedia.com/" rel="nofollow noopener noreferrer"&gt;VertaMedia&lt;/a&gt;
in a production serving up to 200K rps from more than 1.5M concurrent keep-alive
connections per physical server.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.techempower.com/benchmarks/#section=data-r19&amp;amp;hw=ph&amp;amp;test=plaintext" rel="nofollow noopener noreferrer"&gt;TechEmpower Benchmark round 19 results&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/valyala/fasthttp#http-server-performance-comparison-with-nethttp" rel="noopener noreferrer"&gt;Server Benchmarks&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/valyala/fasthttp#http-client-comparison-with-nethttp" rel="noopener noreferrer"&gt;Client Benchmarks&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/valyala/fasthttp#install" rel="noopener noreferrer"&gt;Install&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://pkg.go.dev/github.com/valyala/fasthttp" rel="nofollow noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://pkg.go.dev/github.com/valyala/fasthttp#pkg-examples" rel="nofollow noopener noreferrer"&gt;Examples from docs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/valyala/fasthttpexamples" rel="noopener noreferrer"&gt;Code examples&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/fasthttp" rel="noopener noreferrer"&gt;Awesome fasthttp tools&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/valyala/fasthttp#switching-from-nethttp-to-fasthttp" rel="noopener noreferrer"&gt;Switching from net/http to fasthttp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/valyala/fasthttp#fasthttp-best-practices" rel="noopener noreferrer"&gt;Fasthttp best practices&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/valyala/fasthttp#tricks-with-byte-buffers" rel="noopener noreferrer"&gt;Tricks with byte buffers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/valyala/fasthttp#related-projects" rel="noopener noreferrer"&gt;Related projects&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/valyala/fasthttp#faq" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;HTTP server performance comparison with &lt;a href="https://pkg.go.dev/net/http" rel="nofollow noopener noreferrer"&gt;net/http&lt;/a&gt;
&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;In short, fasthttp server is…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/valyala/fasthttp" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;h3&gt;
  
  
  Go HTTP
&lt;/h3&gt;

&lt;p&gt;Now, let's write a test for an API that we developed with Go's own packages without using any external libraries.&lt;/p&gt;

&lt;p&gt;Let's say we developed an API like above. So how do we test this?&lt;br&gt;
We can write our tests by using the techniques we learned above here as well. Go language has a package called httptest which contains some utility methods. In this package, a method named &lt;code&gt;NewUnstartedServer()&lt;/code&gt; returns us an unstarted test server object.&lt;/p&gt;

&lt;p&gt;Let's take a look at the source code:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When we create a Server with the &lt;code&gt;httptest.NewUnstartedServer()&lt;/code&gt; method, a Listener is created in the background that listens to a random port with the newLocalListener() internal method.&lt;/p&gt;

&lt;p&gt;When we say start, it listens for connections from the listener in a goroutine with the s.goServe() method.&lt;br&gt;
What comes to mind when we see Listener? As in Fasthttp, if we create an InMemoryListener and give it to our server, we can perform our test without listening a physical port.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the above code, we run our server by actually listening to a physical port in the test named TestHttpServer. I put the time.Sleep to wait for the server to start. Using the &lt;code&gt;srv.Listener.Addr().String()&lt;/code&gt; method, we can obtain the address (including the port randomly assigned by the OS) to which we need to request.&lt;/p&gt;

&lt;p&gt;In the test called &lt;strong&gt;TestHttpServerInMemory&lt;/strong&gt;, we performed the http server-client communication via an in-memory listener we created without listening to a physical port.&lt;br&gt;
Here I used the &lt;code&gt;fasthttputil.NewInMemoryListener&lt;/code&gt; method for convenience. If we want, we can do the same thing by creating a struct and implementing the Listener interface.&lt;br&gt;
Let's take a quick look at it:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As we saw above, we can provide in-memory server-client communication by implementing the Listener interface ourselves and using the net.Pipe() method. The reason why I gave connection objects to our InMemListener struct over a channel is that the server calls the Accept() method in a loop and waits for a new connection. Thus, only if we give a connection to our Listener object, the Server side will receive a new connection.&lt;/p&gt;

&lt;p&gt;So why isn't this in-memory server approach provided by default by Go?&lt;/p&gt;

&lt;p&gt;In fact, there is a timely issue about it and there have been some people working on it, but the process has not been finalized yet.&lt;/p&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/golang/go/issues/14200" rel="noopener noreferrer"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        net/http/httptest: optional faster test server
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#14200&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/bradfitz" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F2621%3Fv%3D4" alt="bradfitz avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/bradfitz" rel="noopener noreferrer"&gt;bradfitz&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/golang/go/issues/14200" rel="noopener noreferrer"&gt;&lt;time&gt;Feb 02, 2016&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;Look into making httptest.Server have a way to use in-memory networking (i.e. net.Pipe) instead of localhost TCP. Might be faster/cheaper and not hit ephemeral port issues under load?&lt;/p&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/golang/go/issues/14200" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  Our Test Performance Improvements
&lt;/h2&gt;

&lt;p&gt;Now let's see how we improved our own test performance using the methods I described above.&lt;br&gt;
We developed our application with fasthttp and this application was acting as a basic reverse proxy. We also use some functionality provided by fasthttp for reverse proxy operation.&lt;/p&gt;

&lt;p&gt;For our tests, we need a reverse proxy (our application) and a fake API to represent the server we are redirecting in the background.&lt;/p&gt;

&lt;p&gt;We used &lt;code&gt;httptest.NewUnstartedServer&lt;/code&gt; for this and we used &lt;code&gt;fasthttptest.NewInmemoryListener&lt;/code&gt;.&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%2F9z4odgrebfhmlkn4xoo9.png" 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%2F9z4odgrebfhmlkn4xoo9.png" alt="ss-our-code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Previously, we were actually listening on a port to run test servers in our tests, and this slowed down our testing process quite a bit. When I looked from our CI pipeline, our testing process was taking about 10 seconds.&lt;/p&gt;

&lt;p&gt;As a result of our development, after using the in-memory listener approach, all our tests were completed in ~0.3 seconds.&lt;/p&gt;

&lt;p&gt;In the image below, we can see all our tests and total uptime.&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%2Fmvn4vnzhye8h21v1xjge.png" 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%2Fmvn4vnzhye8h21v1xjge.png" alt="ss-test-time"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When we want to test an HTTP server, we can perform our test faster without listening to a physical PORT.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Our tests run much faster with this technique&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can simulate in-memory net operations using net.Pipe(), net.Listener, &lt;code&gt;net.Conn&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can use the &lt;code&gt;app.Test()&lt;/code&gt; method when testing our applications with fiber.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can create in-memory Listener using &lt;code&gt;fasthttputil.InMemoryListener()&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I hope this was a fun and informative article for you. See you in the next post :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's Connect:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://twitter.com/mstrYoda_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mstrYoda" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can support me on Github: &lt;a href="https://github.com/sponsors/mstrYoda/" rel="noopener noreferrer"&gt;Support mstrYoda on Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>performance</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>My Contribution to a Popular Open-Source Package Caused a Panic in Golang Projects</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Sat, 27 Aug 2022 13:11:21 +0000</pubDate>
      <link>https://dev.to/mstryoda/my-contribution-to-a-popular-open-source-package-caused-a-panic-in-golang-projects-14pi</link>
      <guid>https://dev.to/mstryoda/my-contribution-to-a-popular-open-source-package-caused-a-panic-in-golang-projects-14pi</guid>
      <description>&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%2Ffuipfnibupjdzo2n0clw.png" 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%2Ffuipfnibupjdzo2n0clw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hello, today I will tell you how my development to a popular open-source project caused errors to people using the project around the world and what I learned from this process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content&lt;/strong&gt;&lt;br&gt;
— Swaggo Project&lt;br&gt;
— Our Requirement and My Contribution&lt;br&gt;
— The Problem&lt;br&gt;
— Reason of The Problem&lt;br&gt;
— Function Definition Withtout Body (go:linkname)&lt;br&gt;
— The Solution&lt;br&gt;
— Learned Lessons&lt;/p&gt;


&lt;h3&gt;
  
  
  SWAGGO Project
&lt;/h3&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%2Fous9bluvnacyw6y6m9ss.png" 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%2Fous9bluvnacyw6y6m9ss.png" alt="https://raw.githubusercontent.com/swaggo/swag/master/assets/swaggo.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating swagger documents for your API projects developed in Go language is a little different from languages such as Java, C#. Generally, you can create it by adding Swagger directives in the comment lines of the code you write, and you don't have many alternatives for this.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/swaggo/swag/" rel="noopener noreferrer"&gt;swaggo/swag&lt;/a&gt; project is one of the most popular and widely used solutions.&lt;/p&gt;

&lt;p&gt;The basic process of this project is creating the swagger document by browsing the Go files and processing the comment lines in the definitions. It does this by creating an &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;Abstract Syntax Tree (AST)&lt;/a&gt; and navigating it.&lt;/p&gt;


&lt;h3&gt;
  
  
  Our Requirements and My Contribution
&lt;/h3&gt;

&lt;p&gt;While trying to create a swagger document for a project with my teammate, we realized that we could not make the definition we wanted using the &lt;a href="https://github.com/swaggo/swag/" rel="noopener noreferrer"&gt;swaggo/swag&lt;/a&gt; tool.&lt;/p&gt;

&lt;p&gt;What we wanted to do was to define the request and response objects inside the handler function we created and ensure that they can only be accessed from within the function. But when we did this, the &lt;a href="https://github.com/swaggo/swag/" rel="noopener noreferrer"&gt;swaggo/swag&lt;/a&gt; parser package could not access the related request and response objects.&lt;/p&gt;

&lt;p&gt;I wanted to make a contribution to the &lt;a href="https://github.com/swaggo/swag/" rel="noopener noreferrer"&gt;swaggo/swag&lt;/a&gt; library in order to overcome this problem.&lt;/p&gt;

&lt;p&gt;First of all, I opened an issue to the library and asked if we needed such a thing and that I wanted to contribute by making this development.&lt;br&gt;
In response, they said that it is not possible to parse private definitions and when they asked how I would do it, they were curious about my proposal and were waiting to see it.&lt;/p&gt;

&lt;p&gt;I rolled up my sleeves. I did the development at the first opportunity and opened PR for the project.&lt;/p&gt;

&lt;p&gt;As a result of the development I made, request/response objects became definable within the function. 💪&lt;/p&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/swaggo/swag/pull/1283" rel="noopener noreferrer"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        add functio scoped struct parse, tests
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#1283&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/mstrYoda" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F12763626%3Fv%3D4" alt="mstrYoda avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/mstrYoda" rel="noopener noreferrer"&gt;mstrYoda&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/swaggo/swag/pull/1283" rel="noopener noreferrer"&gt;&lt;time&gt;Aug 07, 2022&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;&lt;strong&gt;Describe the PR&lt;/strong&gt;
I added the functionality of parsing function scoped structs.&lt;/p&gt;
&lt;p&gt;With this development we will be able to define our request response types in the same function scope as our handlers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;package main

// @Param request body main.Fun.request true "query params" 
// @Success 200 {object} main.Fun.response
// @Router /test [post]
func Fun()  {
    type request struct {
        Name string
    }
    
    type response struct {
        Name string
        Child string
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Relation issue&lt;/strong&gt;
&lt;a href="https://github.com/swaggo/swag/issues/1274" rel="noopener noreferrer"&gt;https://github.com/swaggo/swag/issues/1274&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Additional context&lt;/strong&gt;
All tests passed in parser_tests.go. Changes look backward compatible.&lt;/p&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/swaggo/swag/pull/1283" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&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%2Fu0hhb3f5gra7vuzdg1xw.png" 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%2Fu0hhb3f5gra7vuzdg1xw.png" alt="Image description"&gt;&lt;/a&gt;&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%2Fdsiexf63ctmd7s1mku3j.png" 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%2Fdsiexf63ctmd7s1mku3j.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;It's a Friday evening... The work is over, there are minutes... I'm looking forward to the weekend... And... I got a message from my teammate that one of our projects got an error 😞&lt;/p&gt;

&lt;p&gt;I actually want to share the full conversation:&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%2Fv6hoh93m01awcynpblrw.png" 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%2Fv6hoh93m01awcynpblrw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Translation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vural: bro I will tell you something&lt;/li&gt;
&lt;li&gt;Me: yes bro&lt;/li&gt;
&lt;li&gt;Vural: one of our services getting error while generating swagger do, and guess what on which part :D&lt;/li&gt;
&lt;li&gt;Me: is that because of my development asdfasdf&lt;/li&gt;
&lt;li&gt;Vural: yes, I guess asdfsadfs&lt;/li&gt;
&lt;li&gt;Me: you can't be serious asdfasdf&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We immediately went to the project's Github page and looked at the issues. And what we saw made me a little uneasy.&lt;/p&gt;

&lt;p&gt;Many &lt;a href="https://github.com/swaggo/swag/" rel="noopener noreferrer"&gt;swaggo/swag&lt;/a&gt; package users were experiencing errors and they were all getting errors in the CI/CD pipelines or while manually generating swagger due to my development.&lt;/p&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/swaggo/swag/issues/1309" rel="noopener noreferrer"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        Segmentation fault running `swag init` after 1.8.5 release
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#1309&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/mackrorysd" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F2249805%3Fv%3D4" alt="mackrorysd avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/mackrorysd" rel="noopener noreferrer"&gt;mackrorysd&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/swaggo/swag/issues/1309" rel="noopener noreferrer"&gt;&lt;time&gt;Aug 26, 2022&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;&lt;strong&gt;Describe the bug&lt;/strong&gt;
Since 1.8.5 was released, when running &lt;code&gt;swag init --parseDependency true&lt;/code&gt; on my code I encounter a segfault. After switching back to 1.8.4 (or other versions in the 1.8 line) the command completes successfully.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To Reproduce&lt;/strong&gt;
I'm unable to share the entire code this happens on. I will see if I can isolate this to a small code sample I can share.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stack trace&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x85c8a8]

goroutine 1 [running]:
github.com/swaggo/swag.(*PackagesDefinitions).parseFunctionScopedTypesFromFile(0xc00000e7c8, 0xc00035b980, {0xc0003e15c0, 0x18}, 0xc000cff680)
    /home/sean/go/pkg/mod/github.com/swaggo/swag@v1.8.5/packages.go:168 +0xa8
github.com/swaggo/swag.(*PackagesDefinitions).ParseTypes(0xc00000e7c8)
    /home/sean/go/pkg/mod/github.com/swaggo/swag@v1.8.5/packages.go:110 +0xc9
github.com/swaggo/swag.(*Parser).ParseAPIMultiSearchDir(0xc0001e22a0, {0xc0001d7fb0?, 0x1?, 0x0?}, {0x9587e8?, 0x7?}, 0x64)
    /home/sean/go/pkg/mod/github.com/swaggo/swag@v1.8.5/parser.go:362 +0x3bf
github.com/swaggo/swag/gen.(*Gen).Build(0xc0001db980, 0xc0001e1790)
    /home/sean/go/pkg/mod/github.com/swaggo/swag@v1.8.5/gen/gen.go:177 +0x5c9
main.initAction(0xc0001af680?)
    /home/sean/go/pkg/mod/github.com/swaggo/swag@v1.8.5/cmd/swag/main.go:151 +0x757
github.com/urfave/cli/v2.(*Command).Run(0xc0001ad560, 0xc0001ec580)
    /home/sean/go/pkg/mod/github.com/urfave/cli/v2@v2.3.0/command.go:163 +0x5bb
github.com/urfave/cli/v2.(*App).RunContext(0xc000204000, {0xa25860?, 0xc0000240f0}, {0xc000020080, 0x4, 0x4})
    /home/sean/go/pkg/mod/github.com/urfave/cli/v2@v2.3.0/app.go:313 +0xb48
github.com/urfave/cli/v2.(*App).Run(...)
    /home/sean/go/pkg/mod/github.com/urfave/cli/v2@v2.3.0/app.go:224
main.main()
    /home/sean/go/pkg/mod/github.com/swaggo/swag@v1.8.5/cmd/swag/main.go:221 +0x55d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Your swag version&lt;/strong&gt;
1.8.5 (1.8.4 and earlier worked)&lt;/p&gt;
&lt;p&gt;Go version: 1.18&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Desktop (please complete the following information):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OS: Pop! OS 22.04 (essentially Ubuntu)&lt;/li&gt;
&lt;/ul&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/swaggo/swag/issues/1309" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&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%2F6bafkncxnmcwc411t68o.png" 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%2F6bafkncxnmcwc411t68o.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Frankly, I was surprised by this situation because I wrote unit tests for my development and the code was working correctly. In fact, the successful passing of the current unit tests proved that it did not break any previous development.&lt;/p&gt;

&lt;p&gt;So what could be the problem? 🤔&lt;/p&gt;




&lt;h3&gt;
  
  
  Reason of The Problem
&lt;/h3&gt;

&lt;p&gt;I'm attaching a screenshot from my development for &lt;a href="https://github.com/swaggo/swag/" rel="noopener noreferrer"&gt;swaggo/swag&lt;/a&gt;.&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%2Fzv5dkgfa64d5sm0n64y9.png" 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%2Fzv5dkgfa64d5sm0n64y9.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As we can see in the error messages, the error is received in the &lt;code&gt;parseFunctionScopedTypesFromFile&lt;/code&gt; method. In fact, the exact line number of the error is 168.&lt;/p&gt;

&lt;p&gt;Now let's take a closer look at this method I wrote.&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%2Fgksq74uu05y952gilgpj.png" 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%2Fgksq74uu05y952gilgpj.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;In line 168, AST is visited and if there is &lt;strong&gt;FunctionDecleration&lt;/strong&gt; among the definitions, what written inside the defined function is iterated with a for loop.&lt;/p&gt;

&lt;p&gt;So if we are sure that a function definition exists, why do we get an error when trying to iterate this function definition with a for loop?&lt;br&gt;
What causes the nil pointer error?&lt;/p&gt;

&lt;p&gt;When we look at the &lt;code&gt;functionDeclaration.Body&lt;/code&gt; variable, we see that it is a pointer type.&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%2Fjixq9yc6opgoyvngjjq9.png" 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%2Fjixq9yc6opgoyvngjjq9.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;I didn't do a nil check here because I assumed that if a function was defined, that function would have a body definition.&lt;/p&gt;

&lt;p&gt;But in reality it may not be so.👇&lt;/p&gt;


&lt;h3&gt;
  
  
  Function Definition Without Body
&lt;/h3&gt;

&lt;p&gt;Does this term sound foreign to you? Can we define a function without writing a body?&lt;/p&gt;

&lt;p&gt;Consider the code below, do you think this code is a valid definition in Go?&lt;/p&gt;

&lt;p&gt;Will we get an error if we try to run it?&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Yes, as you guessed, we cannot run or even compile this code because it is not a valid definition.&lt;/p&gt;

&lt;p&gt;Can we run the code below?&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here, unlike the previous one, the answer will be yes, we can run it.&lt;/p&gt;

&lt;p&gt;A little-known feature of Go is that we can link a function definition to the function definitions of other packages with the &lt;code&gt;go:linkname&lt;/code&gt; directive.&lt;/p&gt;

&lt;p&gt;Thus, we can define a function without defining a body.&lt;/p&gt;

&lt;p&gt;And if you have noticed, this feature allowed me to use a private function defined under the Go runtime package.&lt;/p&gt;

&lt;p&gt;External dependencies that we use in our projects can have such function definitions. And when we tried to create a swagger document with the &lt;code&gt;swag --parseDependency&lt;/code&gt; command, functions with this definition caused a panic in my development because it also parsed dependencies.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;I was going to do a development to fix the problem right away, but the good thing about the open-source community is that another developer wrote the code that fixed the bug before me and created a PR.&lt;/p&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/swaggo/swag/pull/1310" rel="noopener noreferrer"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        fix: funcDeclaration body check
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#1310&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/rytsh" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F700458%3Fv%3D4" alt="rytsh avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/rytsh" rel="noopener noreferrer"&gt;rytsh&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/swaggo/swag/pull/1310" rel="noopener noreferrer"&gt;&lt;time&gt;Aug 26, 2022&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;&lt;strong&gt;Describe the PR&lt;/strong&gt;
Nil pointer check in function scoped types.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Relation issue&lt;/strong&gt;
#1309&lt;/p&gt;
&lt;p&gt;This is fixes problem on running swag build.&lt;/p&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/swaggo/swag/pull/1310" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&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%2Fkh736b2u9li52vdc5bi1.png" 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%2Fkh736b2u9li52vdc5bi1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Learned Lessons
&lt;/h3&gt;

&lt;p&gt;With this problem, I learned some lessons for myself.&lt;/p&gt;

&lt;p&gt;✅ Never bypass the nil pointer check hypothetically&lt;br&gt;
✅ Unit tests may not always be enough. Do the end to end test&lt;br&gt;
✅ We can write functions without body definition using &lt;code&gt;go:linkname&lt;/code&gt; with Go, we can import functions from private packages&lt;br&gt;
✅ Never make the package dependencies the latest version, specify the version you are sure is working &lt;/p&gt;




&lt;p&gt;I hope it was a fun and useful content for you. Take care of yourself, I wish you bug-free codes 🙏&lt;/p&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Let's Connect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://twitter.com/mstrYoda_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mstrYoda" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can support me on Github: &lt;a href="https://github.com/sponsors/mstrYoda/" rel="noopener noreferrer"&gt;Support mstrYoda on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/mstrYoda" rel="noopener noreferrer"&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%2Ftwve1hh3j8ewl5aowo7r.png" alt="Buy Me A Coffee"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>programming</category>
      <category>github</category>
    </item>
    <item>
      <title>Application Architecture for Microservices: Sidecar Pattern</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Tue, 02 Aug 2022 08:05:00 +0000</pubDate>
      <link>https://dev.to/mstryoda/application-architecture-for-microservices-sidecar-pattern-34m6</link>
      <guid>https://dev.to/mstryoda/application-architecture-for-microservices-sidecar-pattern-34m6</guid>
      <description>&lt;p&gt;What should our microservice application architectures be like?&lt;/p&gt;

&lt;p&gt;Let's examine together how we use sidecar to solve cross-cutting concerns such as authorization, caching, configuration secret management, and observability.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cross-Cutting Concerns
&lt;/h2&gt;

&lt;p&gt;Let's start with explaining cross-cutting concerns.&lt;/p&gt;

&lt;p&gt;Some of the requirements outside of the application's business code are needed in the different layers of an application.&lt;/p&gt;

&lt;p&gt;For example logging, configuration, caching, authorization, observability…&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%2Faqnh23oduaq5ivl82qcl.png" 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%2Faqnh23oduaq5ivl82qcl.png" alt="mstrYoda_"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Traditional Development
&lt;/h2&gt;

&lt;p&gt;The traditional way is to code and use all this tooling within our development service. If we have different services written in the same language, we can share those codes between services and use them as packages/libraries between services.&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%2Fjcgytuzypqvvn2db08h6.png" 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%2Fjcgytuzypqvvn2db08h6.png" alt="mstrYoda_"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So what is a bad scenario?&lt;/p&gt;

&lt;p&gt;In an environment where services are written in more than one language, these requirements had to be reimplemented with each language.&lt;/p&gt;

&lt;p&gt;Imagine that you (or your teams) are writing same functionality over and over with different languages...&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%2Fk1ndaf34sojt70qygjxd.png" 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%2Fk1ndaf34sojt70qygjxd.png" alt="mstrYoda_"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Is there a solution in this case instead of writing the same code?&lt;/p&gt;

&lt;p&gt;The first thing that comes to mind is to write separate API services for those requirements.&lt;/p&gt;

&lt;p&gt;So is this a correct solution?&lt;/p&gt;

&lt;p&gt;What problems can we encounter?&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%2Fvieroa3x1na7tjlajc72.png" 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%2Fvieroa3x1na7tjlajc72.png" alt="mstrYoda_"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How to scale these shared services when the number of consumer services increase?&lt;/p&gt;

&lt;p&gt;Moving the application code to another service that accessing  over the network will cause the network latency(delay) to our application. It will slow down our application.&lt;/p&gt;

&lt;p&gt;So, what would you do if you do not want to rewrite the same stories in different languages, or to face with network latencies?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer&lt;/strong&gt;: We will use to Sidecar pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sidecar Pattern
&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%2F2q6tnsdu9x9krjozysfo.png" 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%2F2q6tnsdu9x9krjozysfo.png" alt="https://devopedia.org/design-patterns-for-microservices-and-containers"&gt;&lt;/a&gt;&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%2Fazg3l5nomqeisptmzvpn.png" 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%2Fazg3l5nomqeisptmzvpn.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;So what is this Sidecar?&lt;/p&gt;

&lt;p&gt;We can run multiple containers inside our pods running on Kubernetes. We can call the containers running beside our main application container as sidecars.&lt;/p&gt;

&lt;p&gt;These additional features can develop in a single language and then we can "inject" it to our applications. We develop our sidecars with Go language and inject them into microservices.&lt;/p&gt;

&lt;p&gt;This "&lt;strong&gt;inject&lt;/strong&gt;" operation is performed by Kubernetes on the basis of a concept which name is &lt;strong&gt;Dynamic Admission Webhook&lt;/strong&gt;. I will leave the source link at the end of the article for details.&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%2F05lknl2vg5cawjwhwnou.png" 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%2F05lknl2vg5cawjwhwnou.png" alt="mstrYoda_"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a pod scales up, the additional sidecars also go with it.&lt;/p&gt;

&lt;p&gt;In addition, with the network interface created specifically for the pod shared across sidecars, network latency can be ignored because it is over localhost.&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%2Fklfeii1we7dmkfunjnmf.png" 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%2Fklfeii1we7dmkfunjnmf.png" alt="mstrYoda_"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What else can be done with the sidecars?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pod network configurations&lt;/li&gt;
&lt;li&gt;Pod network requests/responses can be interrupted/manipulated&lt;/li&gt;
&lt;li&gt;Service mesh can be made&lt;/li&gt;
&lt;li&gt;Microservice runtime implementation can be done&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, Istio Service Mesh can work as sidecar. The pod's entire network control is taken over by the incoming istio-proxy as a sidecar and can manipulate incoming and outgoing requests/responses.&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%2Fvt5e9c5j10vb1xz1n16w.png" 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%2Fvt5e9c5j10vb1xz1n16w.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You can write various network rules. When the whole network passes through the istio-proxy sidecar, there is metric data for all network processes and we can visualize microservice inter-service calls.&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%2Fimex9h28iprq536ii8gy.png" 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%2Fimex9h28iprq536ii8gy.png" alt="istio"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I want to complete my post here. We take a quick look into the sidecar approach with you. See you in the next posts.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/" rel="noopener noreferrer"&gt;https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://betterprogramming.pub/understanding-kubernetes-multi-container-pod-patterns-577f74690aee" rel="noopener noreferrer"&gt;https://betterprogramming.pub/understanding-kubernetes-multi-container-pod-patterns-577f74690aee&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://istio.io/" rel="noopener noreferrer"&gt;https://istio.io/&lt;/a&gt;&lt;/p&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Let's Connect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://twitter.com/mstrYoda_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mstrYoda" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can support me on Github: &lt;a href="https://github.com/sponsors/mstrYoda/" rel="noopener noreferrer"&gt;Support mstrYoda on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/mstrYoda" rel="noopener noreferrer"&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%2Ftwve1hh3j8ewl5aowo7r.png" alt="Buy Me A Coffee"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>kubernetes</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Configure RBAC in Kubernetes Like a Boss</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Wed, 27 Jul 2022 21:47:38 +0000</pubDate>
      <link>https://dev.to/mstryoda/configure-rbac-in-kubernetes-like-a-boss-h67</link>
      <guid>https://dev.to/mstryoda/configure-rbac-in-kubernetes-like-a-boss-h67</guid>
      <description>&lt;p&gt;In this post I will explain how to configure RBAC in kubernetes. We will configure RBAC both with kubectl and yaml definitions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is RBAC
&lt;/h2&gt;

&lt;p&gt;In kubernetes there are several authorization mechanism like RBAC, ABAC.&lt;/p&gt;

&lt;p&gt;With RBAC we can add constraints to access kubernetes resources. For example we can give permission to listing pods for specific namespace to a ServiceAccount and prevent it to delete any resource. We can do it for a specific namespace or cluster wide as well.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key points of RBAC
&lt;/h2&gt;

&lt;p&gt;There are 3 important concept in RBAC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subject&lt;/strong&gt; : Users, groups or service accounts.&lt;br&gt;
&lt;strong&gt;Resources&lt;/strong&gt; : Kubernetes API objects which we will operate on.&lt;br&gt;
&lt;strong&gt;Verbs&lt;/strong&gt; : The operations which we want to do with our resources.&lt;/p&gt;
&lt;h2&gt;
  
  
  Role &amp;amp; ClusterRole
&lt;/h2&gt;

&lt;p&gt;Role and ClusterRole contains set of rules to access &amp;amp; modify kubernetes resources. Difference between them is Role works in particular namespace while ClusterRole is cluster wide which is obvious from it’s name.&lt;/p&gt;

&lt;p&gt;If you need define permissions inside a namespace use Role, if you need that cluster wide use ClusterRole.&lt;/p&gt;

&lt;p&gt;Creating Role via kubectl is simple like I showed you below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl create role my-custom-role --verb=list --resource=pods --namespace k8boss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We can also specify multiple verbs and resources as well:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl create role my-custom-role --verb=list --verb=get --resource=pods --resource=services --namespace k8boss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If we want to make it via yaml:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f role.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If we did will not specify namespace in our role.yaml it will considered as default namespace.&lt;/p&gt;

&lt;p&gt;ClusterRole is not much differs:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;It is almost same with Role definition only without a namespace.&lt;/p&gt;




&lt;h2&gt;
  
  
  ServiceAccount
&lt;/h2&gt;

&lt;p&gt;Service accounts are used by processes inside pods to interact with the Kubernetes API. If you write custom application to work with kubernetes you will probably need to create a custom ServiceAccount with some specialized roles assigned to it. &lt;/p&gt;

&lt;p&gt;For example when you deploy kubernetes dashboard you can give additional roles to kubernetes-dashboard service account or create a custom ServiceAccount with a cluster-admin role bindings.&lt;/p&gt;

&lt;p&gt;Creating a ServiceAccount is so simple with kubectl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl create serviceaccount custom-sa -n k8boss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Or yaml:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;After creating ServiceAccount lets show it’s yaml content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get sa custom-sa -n k8boss -o yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;As you can see there is an additional field “secrets” which we did not specify while creating ServiceAccount. A secret has been created which related to our ServiceAccount by kubernetes.&lt;/p&gt;

&lt;p&gt;Lets take a look our secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get secret custom-sa-token-jcq7h -n k8boss -o yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;We can see a token key value here. We can use these secret to access kubernetes-dashboard. But we need to decode it because kubernetes stores secret values in base64 encoded format. Simply we can describe secret and take the token value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl describe secret custom-sa -n k8boss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fnvtheuafeu1p21xpy2es.png" 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%2Fnvtheuafeu1p21xpy2es.png" alt="screen shot"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  RoleBinding &amp;amp; ClusterRoleBinding
&lt;/h2&gt;

&lt;p&gt;Role bindings as indicates from names makes us bind roles to subjects (user or set of users or service accounts). Again the only difference is in usage, we use RoleBinding to bind Roles while ClusterRoleBinding to bind ClusterRoles. But as an addition we can use RoleBinding to bind a ClusterRole to a Role within a namespace.&lt;/p&gt;

&lt;p&gt;Before creating role binding we can ask our service account’s capabilities with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl auth can-i list pods --as=system:serviceaccount:k8boss:custom-sa -n k8boss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You will see “no” as output of that command.&lt;/p&gt;

&lt;p&gt;Lets create a role binding with kubectl:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl create rolebinding my-custom-role-binding --role=my-custom-role --serviceaccount=k8boss:custom-sa --namespace k8boss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Equivalent yaml file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;ClusterRoleBinding is not much differs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl create clusterrolebinding my-custom-clusterrole-binding --clusterrole=my-custom-cluster-role --serviceaccount=k8boss:custom-sa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now again lets ask our capabilities:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl auth can-i list pods --as=system:serviceaccount:k8boss:custom-sa -n k8boss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now you can see “yes” as an answer.&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%2Fczcb3ro2mipdliga5gko.png" 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%2Fczcb3ro2mipdliga5gko.png" alt="screen shot"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Aggregated ClusterRoles
&lt;/h2&gt;

&lt;p&gt;Last thing we will mention is Aggregated ClusterRoles. Sometimes we might want to combine several cluster role into one.&lt;/p&gt;

&lt;p&gt;To do this we can use aggregationRule field of ClusterRole. We can select roles using label selectors. For example lets assume we have two ClusterRole one for listing pods one for listing services. So we need another ClusterRole to list pods and services. We can now use aggregationRule to combine our two ClusterRoles.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;




&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;p&gt;There are other useful articles about RBAC I suggest you to read those too:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkubernetes.io%2Fimages%2Fkubernetes-horizontal-color.png" height="auto" class="m-0"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/" rel="noopener noreferrer" class="c-link"&gt;
          Using RBAC Authorization | KubernetesUsing RBAC Authorization | Kubernetes
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within your organization.
RBAC authorization uses the rbac.authorization.k8s.io API group to drive authorization decisions, allowing you to dynamically configure policies through the Kubernetes API.
To enable RBAC, start the API server with the --authorization-mode flag set to a comma-separated list that includes RBAC; for example:
kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options API objects The RBAC API declares four kinds of Kubernetes object: Role, ClusterRole, RoleBinding and ClusterRoleBinding.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fkubernetes.io%2Fimages%2Fkubernetes.png"&gt;
        kubernetes.io
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.cncf.io/blog/2018/08/01/demystifying-rbac-in-kubernetes/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.cncf.io%2Fwp-content%2Fuploads%2F2020%2F08%2FScreenshot-2018-08-02-09.35.47-1.png" height="auto" class="m-0"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.cncf.io/blog/2018/08/01/demystifying-rbac-in-kubernetes/" rel="noopener noreferrer" class="c-link"&gt;
          Demystifying RBAC in Kubernetes | CNCF
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Today’s post is written by Javier Salmeron, Engineer at Bitnami Many experienced Kubernetes users may remember the Kubernetes 1.6 release, where the Role-Based Access Control (RBAC) authorizer was…
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.cncf.io%2Fwp-content%2Fthemes%2Fcncf-twenty-two%2Fimages%2Ffavicon.ico"&gt;
        cncf.io
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/containerum/configuring-permissions-in-kubernetes-with-rbac-a456a9717d5d" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afill%3A88%3A88%2F1%2A0WNeZDa1gz-8ABme7BZySw.png" alt="Containerum"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/containerum/configuring-permissions-in-kubernetes-with-rbac-a456a9717d5d" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Configuring permissions in Kubernetes with RBAC | by Containerum | Containerum | Medium&lt;/h2&gt;
      &lt;h3&gt;Containerum ・ &lt;time&gt;Aug 1, 2018&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&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%2Fassets%2Fmedium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Thank you for reading so far. See you on the next article.&lt;/p&gt;

&lt;p&gt;You can follow me on:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mstrYoda" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/mstrYoda_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/mstrYoda" rel="noopener noreferrer"&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%2Ftwve1hh3j8ewl5aowo7r.png" alt="Buy Me A Coffee"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
    <item>
      <title>How To Become an Open Source Contributor</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Tue, 26 Jul 2022 11:17:00 +0000</pubDate>
      <link>https://dev.to/mstryoda/how-to-become-an-open-source-contributor-4pgp</link>
      <guid>https://dev.to/mstryoda/how-to-become-an-open-source-contributor-4pgp</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllx8ex2f5zdtkg7qp4ht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllx8ex2f5zdtkg7qp4ht.png" alt="Open Source" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a software developer, I feel happy when I contribute to the community. It is an opportunity to improve your development skills and learn new things. It is both an educative and entertaining process. There are few things that satisfy me as much as an accepted pull request :)&lt;/p&gt;

&lt;p&gt;Becoming an open source contributor is a dream for some developers. If you are a new developer or never made a contribution before and want to become a contributor, in this post, I have several suggestions for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where To Start
&lt;/h2&gt;

&lt;p&gt;Well, let’s assume you found a project on Github and you want to contribute to that project. Which steps to follow to become a contributor? What might be helpful to the contribution process? I will list those baby steps that I followed and made the contribution process easy for me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1- Use that project in production as much as possible&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This might be the most important part of becoming a contributor. Using a tool in production or in daily life helps you to understand it better. While using the tool, you will probably face errors that are actually bugs that need to be fixed.&lt;/p&gt;

&lt;p&gt;At this point, you can start contributing by creating an issue that describes the steps to reproduce that error.&lt;/p&gt;

&lt;p&gt;After that, you can get your hands dirty to get dive into the source code to investigate the root cause of that bug.&lt;/p&gt;

&lt;p&gt;When you find the problem and fix it, you can create a pull request.&lt;/p&gt;

&lt;p&gt;As an example, about 2.5 years ago, when I was writing C#, we used to use RestSharp as http client like most of the other developers. At that time, we had trouble comparing two almost identical DateTime; we investigated it and found that RestSharp had missed a DateTime format while deserializing json string. And I decided to fix that issue by opening a pull request. After that, my pr merged, and I became a contributor to RestSharp.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;2- Take a look at the source code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgr12hofbpph63fo41n2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgr12hofbpph63fo41n2.png" alt="Image description" width="608" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I am curious about a project, I will clone it and take a look at the source code of it. It is not always a good starting point to contribute but it might help you to find some code to refactor.&lt;/p&gt;

&lt;p&gt;As an example, when I started my career at Trendyol, I forked a project which was an internal framework used for legacy projects. When I looked at the source code, I found a piece of code to refactor.&lt;/p&gt;

&lt;p&gt;Another example of looking at source code is while we were using Consul in our project, I looked at the source code, and I saw an array declaration without specified length (declaring length while initialization is a performance improvement for arrays in Golang ). So I made one line contribution by specifying the length of that array. Even that was satisfying for me :)&lt;/p&gt;

&lt;p&gt;There is one more thing to do in the source code: “Measuring test coverage.” Writing unit tests to increase test coverage is another way to contribute to the project. For example, I am preparing a pr to Kubernetes that contains unit tests which increase test coverage.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;3- Read documentations and apply examples&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftutf5el4ek9my70bw9ub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftutf5el4ek9my70bw9ub.png" alt="Image description" width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reading documentation helps you to understand how to use the tool. There are two things related to reading docs. One is that you might need information about a feature and you can not find it in docs. Here you can contribute by writing documentation about that part. The second one is that sometimes documentation might not be up to date or have typos. When you are faced with that, you can contribute by fixing docs.&lt;/p&gt;

&lt;p&gt;I remember I was following an example on Istio documentation, applied it, and got an error. I realized that the example has a typo on yaml configuration. I created a pr and fixed that documentation to save other developers time.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;4- Use the client of that project (if exists)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Diving right into the source code of an open source project might be hard, especially if the project has a huge source code. At this point, it might be helpful to start using the client code of that project. This also helps to understand the internal structures of that project.&lt;/p&gt;

&lt;p&gt;Let’s take Kubernetes as an example, it has quite a huge source code, and it is not straightforward to dive into source code as a stranger. But, you can use Kubernetes client and make some example projects which interact with Kubernetes. You will see that it helps you to understand the internals of Kubernetes better.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;5- Search for issues&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpo7wkq3gaaxs2joaoqas.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpo7wkq3gaaxs2joaoqas.png" alt="Image description" width="800" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Searching for issues to resolve is another alternative to start contributing, but it might be hard for a beginner. You can always start searching for issues labeled as GoodFirstIssue.&lt;/p&gt;

&lt;p&gt;When I wrote Java, we used to use OpenFeign within our Spring Boot projects. I decided to search for issues to find if there is an easy one to get involved in the project. And I found it!&lt;/p&gt;

&lt;p&gt;I start to resolve that issue and opened a pr for it. It was accepted by authors, and I got my name in contributors.&lt;/p&gt;

&lt;p&gt;There are sites that help you to find projects to contribute to. You can filter projects by tags or languages.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://www.codetriage.com/" rel="noopener noreferrer"&gt;
      codetriage.com
    &lt;/a&gt;
&lt;/div&gt;



&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://up-for-grabs.net/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--xVidQ9yk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://up-for-grabs.net/images/logo.png" height="230" class="m-0" width="200"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://up-for-grabs.net/" rel="noopener noreferrer" class="c-link"&gt;
          Up For Grabs
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Want to contribute to open source, but not sure where to start?
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--iatlZFGq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://up-for-grabs.net/icons/favicon-196x196.png" width="196" height="196"&gt;
        up-for-grabs.net
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;You can also use Github directly to find projects by filtering:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://github.com/search?q=label%3Afirst-timers-only&amp;amp;amp;state=open&amp;amp;amp;type=Issues" rel="noopener noreferrer"&gt;
      github.com
    &lt;/a&gt;
&lt;/div&gt;

&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;6- Create an open source project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Creating an open source project might sound very hard at first glance. But in time you will realize that open sourcing your codes, even basic automated tasks, might help others too.&lt;/p&gt;

&lt;p&gt;So following this thought, I created a repository called docker-shell, which does auto-completion and suggestions for docker commands. It grew further than I expected. It helps developers who use docker in daily life.&lt;/p&gt;

&lt;p&gt;You can contribute to the docker-shell project as well: &lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Trendyol"&gt;
        Trendyol
      &lt;/a&gt; / &lt;a href="https://github.com/Trendyol/docker-shell"&gt;
        docker-shell
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A simple interactive prompt for docker
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;docker-shell&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A simple interactive prompt for Docker. Inspired from &lt;a href="https://github.com/c-bata/kube-prompt"&gt;kube-prompt&lt;/a&gt; uses &lt;a href="https://github.com/c-bata/go-prompt"&gt;go-prompt&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://opensource.org/licenses/MIT" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/beb36c5248e0aaac973b57049c0cd96c11e020362efc532905b796060f1930bf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d6c69677468677265656e2e737667" alt="License: MIT"&gt;&lt;/a&gt; &lt;a href="https://github.com/Trendyol/docker-shellCONTRIBUTING.md"&gt;&lt;img src="https://camo.githubusercontent.com/bacb6bec7efccfaf540397fbb8bb56a5fd143f46230d3ced34a08097085f8575/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6e7472696275746f72253230436f76656e616e742d76312e3425323061646f707465642d6666363962342e737667" alt="Contributor Covenant"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table Of Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Trendyol/docker-shell#features"&gt;Features:&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/Trendyol/docker-shell#installation"&gt;Installation&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Trendyol/docker-shell#homebrew"&gt;Homebrew&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Trendyol/docker-shell#build-from-source-code"&gt;Build From Source Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Trendyol/docker-shell#how-to-use"&gt;How To Use&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Trendyol/docker-shell#how-to-contribute"&gt;How To Contribute&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;

&lt;/div&gt;
&lt;ul class="contains-task-list"&gt;
&lt;li class="task-list-item"&gt;
 Suggest docker commands&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 List container ids&amp;amp;names after docker exec/start/stop commands&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Suggest command parameters based on typed command&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 List images from docker hub after docker pull command &lt;a href="https://github.com/Trendyol/docker-shell/milestone/1"&gt;v1.2.0&lt;/a&gt;
&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Suggest port mappings after docker run command &lt;a href="https://github.com/Trendyol/docker-shell/milestone/2"&gt;v1.3.0&lt;/a&gt;
&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Suggest available images after docker run command &lt;a href="https://github.com/Trendyol/docker-shell/milestone/2"&gt;v1.3.0&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Homebrew&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;You can install by using &lt;em&gt;homebrew&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;brew tap trendyol/trendyol-tap

brew install docker-shell&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Build From Source Code&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;You can build the command from source code by following the steps below:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;git clone git@github.com:Trendyol/docker-shell.git

&lt;span class="pl-c1"&gt;cd&lt;/span&gt; docker-shell

sudo go build -o /usr/local/bin/docker-shell &lt;span class="pl-c1"&gt;.&lt;/span&gt;

docker-shell&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How To Use&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;After installation, you can type &lt;code&gt;docker-shell&lt;/code&gt; and run the interactive shell.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://asciinema.org/a/AKDTBnD3gKKzACDdj7Tm670PJ" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/e35419d9ef5bf5dc857b948abce965aa74dc135bc0603260059fb3c3a93a59f6/68747470733a2f2f61736369696e656d612e6f72672f612f414b4454426e4433674b4b7a414344646a37546d363730504a2e737667" alt="asciicast"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Image suggestion from docker hub:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://asciinema.org/a/UCfYZNXCcVxIiqNKsAMtEhmiM" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/3de31d830682718ea57dd37f096f95b0b717a30be814904dc918da95b3785b7e/68747470733a2f2f61736369696e656d612e6f72672f612f554366595a4e58436356784969714e4b73414d7445686d694d2e737667" alt="asciicast"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Port mapping suggestion:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://asciinema.org/a/7aWKWQJqqHZkpWZXwfy8AcrPj" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/1833bd1f262d46659d297b1f2d9b691a16025b295c94832da9749d1b33722d0f/68747470733a2f2f61736369696e656d612e6f72672f612f3761574b57514a7171485a6b70575a5877667938416372506a2e737667" alt="asciicast"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How To Contribute&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Contributions are &lt;strong&gt;welcome&lt;/strong&gt; and will be fully &lt;strong&gt;credited&lt;/strong&gt;…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Trendyol/docker-shell"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Another open source project created by me is "kubernetes-kitap" project, which is a book written in Turkish for Kubernetes to help Turkish developers to understand Kubernetes:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mstrYoda"&gt;
        mstrYoda
      &lt;/a&gt; / &lt;a href="https://github.com/mstrYoda/kubernetes-kitap"&gt;
        kubernetes-kitap
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/mstrYoda/kubernetes-kitap/master/kubernetes.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KYjtOTIs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/mstrYoda/kubernetes-kitap/master/kubernetes.png" alt="k8s"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Hoş geldiniz&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Open Source severler olarak bir araya gelip, Kubernetes için Türkçe kaynak olması açısından bu kitabı hazırladık ve siz değerli okuyuculara sunduk.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Kitabın adresi: &lt;a href="https://mstryoda.github.io/kubernetes-kitap/#/" rel="nofollow"&gt;https://mstryoda.github.io/kubernetes-kitap/#/&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Konu Başlıkları&lt;/h1&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Giriş&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/kubernetes-nedir.md"&gt;Kubernetes Nedir&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/cluster.md"&gt;Kubernetes Cluster Mimarisi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/pod-container.md"&gt;Pod ve Container Kavramı&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes Node Elemanları&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/control-plane.md"&gt;Control Plane Elemanları&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/control-plane?id=api-server.md"&gt;api-server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/control-plane?id=etcd.md"&gt;etcd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/control-plane?id=controller-manager.md"&gt;controller-manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/control-plane?id=scheduler.md"&gt;scheduler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/data-plane.md"&gt;Worker Node Elemanları&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/data-plane?id=kubelet.md"&gt;kubelet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/data-plane?id=kube-proxy.md"&gt;kube-proxy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Development Ortamı Kurulumu&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/kind.md"&gt;&lt;strong&gt;kind&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/minikube.md"&gt;&lt;strong&gt;minikube&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/k3s.md"&gt;&lt;strong&gt;k3s&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/k3d.md"&gt;&lt;strong&gt;k3d&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/microk8s.md"&gt;&lt;strong&gt;microk8s&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubectl Kullanımı&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/kubeconfig.md"&gt;kubeconfig&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubectl İşlemleri&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/kubectl-resource-islemleri?id=kubectl-apply.md"&gt;Kubectl Apply&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/kubectl-resource-islemleri?id=resource-listelemek.md"&gt;Resource Listelemek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/kubectl-resource-islemleri?id=resource-editlemek.md"&gt;Resource Editlemek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/kubectl-resource-islemleri?id=jsonpath-ile-field-filtreleme.md"&gt;JsonPath ile Field filtreleme&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/kubectl-resource-islemleri?id=deployment-olu%C5%9Fturmak.md"&gt;Deployment Oluşturmak&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/kubectl-resource-islemleri?id=deployment-scale.md"&gt;Deployment Scale&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Controllerlar&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/controller.md"&gt;Controller Kavramı Nedir&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/deployments.md"&gt;Deployments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/statefulsets.md"&gt;StatefulSets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/daemonsets.md"&gt;DaemonSets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/replicasets.md"&gt;ReplicaSets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pod Genel Bakış&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pod Yaşam Döngüsü&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/container-faz.md"&gt;Container Statüleri&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/pod-durum.md"&gt;Pod Durumları&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/init-container.md"&gt;Init Container&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/pod-preset.md"&gt;Pod Preset&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/static-pod.md"&gt;Static Pod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/ephemeral-container.md"&gt;Ephemeral Container&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Podların Çalışacağı Nodeları Belirleme - Scheduling&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/nodeselector.md"&gt;NodeSelector Alanı&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/taint-toleration.md"&gt;Taint ve Tolerant Kavramı&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/affinity-anti-affinity.md"&gt;Node Affinity ve Pod Affinity Kavramı&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Uygulama Kaynaklarının Konfigürasyonu&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/resourcequata.md"&gt;ResourceQuata Objesi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/limitrange.md"&gt;LimitRange Objesi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Health Check İşlemleri&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/health-check-yontemleri.md"&gt;Health Check Yöntemleri&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/liveness.md"&gt;LivenessProbe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/readiness.md"&gt;ReadinessProbe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/startup.md"&gt;StartupProbe&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HorizontalPodAutoscaler ile Scaling&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mstrYoda/kubernetes-kitap./docs/hpa.md"&gt;Ram &amp;amp; Cpu Bazlı Uygulama Scale Etme&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mstrYoda/kubernetes-kitap"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;Before finishing the post, I want to say that contributing to other projects has its own benefits. The first and obvious one is that it improves your development skills. Your code is reviewed by other developers, and this gives you a new perspective. Also, you are making new networks and friendships with other developers.&lt;/p&gt;




&lt;p&gt;Bonus: Here is another site that might be helpful to start open source:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://opensource.guide/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--rwVsyjsE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://opensource.guide/assets/images/cards/default.png" height="429" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://opensource.guide/" rel="noopener noreferrer" class="c-link"&gt;
          Open Source Guides | Learn how to launch and grow your project.
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Learn how to launch and grow your project.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--JWDsuwm6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.githubassets.com/favicon.ico" width="32" height="32"&gt;
        opensource.guide
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;You can follow me on:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://github.com/mstrYoda" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--fgL_MVGC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://avatars.githubusercontent.com/u/12763626%3Fv%3D4%3Fs%3D400" height="460" class="m-0" width="460"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://github.com/mstrYoda" rel="noopener noreferrer" class="c-link"&gt;
          mstrYoda (Emre Savcı) · GitHub
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Tech. Lead @Trendyol | K8S &amp;lt;3 | Loves Golang
| Contributions: [docker-shell, awesome-istio, awesome-dapr, @gofiber, @swaggo, kustomize, gocb] - mstrYoda
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--GiYjWU4I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.githubassets.com/favicons/favicon.svg" width="32" height="32"&gt;
        github.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://twitter.com/mstrYoda_"&gt;Twitter&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Thank you for reading so far. Take care of yourself until next post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/mstrYoda"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CQvhqaK6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.buymeacoffee.com/buttons/default-black.png" alt="Buy Me A Coffee" width="434" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Become Cross Functional Polyglot Developer</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Mon, 25 Jul 2022 10:03:00 +0000</pubDate>
      <link>https://dev.to/mstryoda/how-to-become-cross-functional-polyglot-developer-4g3e</link>
      <guid>https://dev.to/mstryoda/how-to-become-cross-functional-polyglot-developer-4g3e</guid>
      <description>&lt;p&gt;How to become a production ready developer?&lt;/p&gt;

&lt;p&gt;In these days sticking to a single technology / programming language / tool is not enough for a developer. There are so many things to consider, especially in the microservice’s world.&lt;/p&gt;

&lt;p&gt;This might make developers freak.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhs6ron6ze5fe5fei80aa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhs6ron6ze5fe5fei80aa.png" alt="CNCF Landscape and Developers" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a software developer in my daily job I am handling different stuffs like designin architecture, writing code, testing it, writing CI/CD pipelines, creating alerts according to logs or events, monitoring the app etc..&lt;/p&gt;

&lt;p&gt;In this article I am aiming to enlighten the new developers or the ones who does not involved in multi-tech stack.&lt;/p&gt;

&lt;p&gt;What is the requirements of developing applications and deploying to production?&lt;/p&gt;

&lt;p&gt;What are some concepts to follow?&lt;/p&gt;




&lt;h2&gt;
  
  
  Unit Tests (Coding)
&lt;/h2&gt;

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

&lt;p&gt;We need to develop applications in a testable matter. All the business requirements and features must be testable. With unit testing, we prove that our code works respecting to what business said.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Domain Driven Design (Architecture)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6x4ldbqbgncuhljw4ao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6x4ldbqbgncuhljw4ao.png" alt="https://docs.microsoft.com/tr-tr/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/media/ddd-oriented-microservice/domain-driven-design-microservice.png" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To talking the same language in business persons we need to develop a language. Also to build extensible, testable, understandable application we need some abstractions&amp;amp;rules to follow. In DDD we can provide a clean solution to complex business domains.&lt;/p&gt;

&lt;p&gt;I recommend the red book of Vaughn Vernon: “Implementing Domain Driven Design”.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Clean Code Practices (Coding)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0d2r5gg2off5n4jwbfj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0d2r5gg2off5n4jwbfj.png" alt="Image description" width="302" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to follow clean code practices to write clean, understandable, readable code.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Integration&amp;amp;Automation Tests (Testing)
&lt;/h2&gt;

&lt;p&gt;We need to prove that our application can work without trouble with 3rd party applications. Also we want to test our application from outside point of view. And we want to avoid doing that manually every time for any change occurs. So we write integration&amp;amp;automation tests to automate that process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Consumer Driven Contract Tests (Testing)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8ba42y5dsjbafjxdowj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8ba42y5dsjbafjxdowj.png" alt="https://reflectoring.io/assets/img/posts/consumer-driven-contracts-with-angular-and-pact/mocks.jpg" width="700" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How do we sure about our consumers will not affected when we made a change to an endpoint in our rest api?&lt;/p&gt;

&lt;p&gt;What if we change a field’s name which is used by a consumer by accidentally?&lt;/p&gt;

&lt;p&gt;CDC tests to rescue. We and our consumers writes CDC tests and run those tests in pipeline to prevent deploying any breaking change.&lt;/p&gt;

&lt;p&gt;Take a look to project pact: &lt;a href="https://docs.pact.io"&gt;https://docs.pact.io&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Hexagonal Architecture &amp;amp; Ports Adapters &amp;amp; CQRS (Architecture)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fti10rimagep5n8amt8f2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fti10rimagep5n8amt8f2.png" alt=" https://herbertograca.files.wordpress.com/2018/11/100-explicit-architecture-svg.png" width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to provide extensibility and a well abstraction to our project. Abstracting application/domain/infrastructure/api levels of our project is much more important compared to what framework we used. Here is hexagonal architecture and port&amp;amp;adapters comes into view.&lt;/p&gt;

&lt;p&gt;Also we might want to scale our application’s read and write parts separately. Or we want to divide/abstract that responsibility in the code. Here is what CQRS tells us.&lt;/p&gt;

&lt;p&gt;Take a look for more information: &lt;a href="https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/"&gt;https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Containers &amp;amp; Docker (Devops)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fviylr1js9bj4r6xhua47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fviylr1js9bj4r6xhua47.png" alt="https://i0.wp.com/www.docker.com/blog/wp-content/uploads/011f3ef6-d824-4d43-8b2c-36dab8eaaa72-1.jpg?fit=650%2C530&amp;amp;ssl=1" width="650" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can dive into containers from a higher level with Docker. Mostly used de-facto standart in container tech.&lt;/p&gt;

&lt;p&gt;Also there are some other tools to build containers like buildah &amp;amp; podman.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. CI/CD Pipelines (Devops)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc3km60vrvuxus7ajizje.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc3km60vrvuxus7ajizje.png" alt="https://qph.fs.quoracdn.net/main-qimg-2ed37e37f01fa5a24091c52f4a487479" width="800" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to automate our test / build / deploy steps of our applications.&lt;/p&gt;

&lt;p&gt;With using CI/CD tools (Jenkins, Gitlab etc.) we can achieve this.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Kubernetes (Devops)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgkkce2vklwb9uenqnf7e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgkkce2vklwb9uenqnf7e.png" alt="Image description" width="730" height="389"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Well K8S is the de-facto standart for container orchestration. We can run/scale/discover our services with kubernetes.&lt;/p&gt;

&lt;p&gt;As a developer we need to be familiar with it to understand the environment which our application works on.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Logging (Monitoring)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fti2sjlwt6yxnpj49fhxp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fti2sjlwt6yxnpj49fhxp.png" alt="https://www.tigera.io/wp-content/uploads/2020/10/Solving-Microservices-Connectivity-Issues-with-Network-Logs.png" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Logs are the one of the way to help us to understand our application’s behavior. With a good logging system we can catch unexpected behaviors/errors and take actions to them.&lt;/p&gt;

&lt;p&gt;There are many different logging techs like ELK stack.&lt;/p&gt;

&lt;p&gt;For example, we are trying to follow 12 factor app strategy. Our applications does not aware of the underlying tech about logging. All our microservices print their logs to stdout and we collect it with fluentbit/fluentd in kubernetes. With this way we are abstracting the logging technology from applications. We can switch the log storage without affecting applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Monitoring
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyz9cdrofyba73wypbu4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyz9cdrofyba73wypbu4y.png" alt="Image description" width="800" height="570"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Softwares are alive systems. They need to be watched all the time. To determine any anomaly (like high resource usage, total requests, response times) and optimize those we need to keep track it.&lt;/p&gt;

&lt;p&gt;There are tools like NewRelic, Jaeger, Elastic APM which helps us to monitor applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. IaC (Devops)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8dagcjs2avco1325gt3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8dagcjs2avco1325gt3d.png" alt="https://www.suntechnologies.com/wp-content/uploads/2020/04/image-1-2-scaled.jpg" width="800" height="565"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Infrastructure as code help us to automate any machine provision &amp;amp; configuration process. Tools like terraform, ansible, chef, puppet, vagrant, docker help us to achieve IaC. We can write our environment in a terraform/ansible as code and we automatically run those in a pipeline to bootstrap the environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  13. Message Brokers (Architecture)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4wsq12a0vhqbcsnh8y8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4wsq12a0vhqbcsnh8y8.png" alt="https://miro.medium.com/max/2412/0*gFwb04MsfqtVB5bY.png" width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We might want to design our service communications in an async way. Mostly we do it as a performance optimization. For example, sending information mail end of a process can be async. So we can separate those services and provide communication between separated services with a message broker.&lt;/p&gt;

&lt;p&gt;There are some popular tools like RabbitMQ, ActiveMQ, Kafka, Aws Sqs etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  14. Databases &amp;amp; Cache (Storage)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f1f6jhwac53tydj7iup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f1f6jhwac53tydj7iup.png" alt="https://docs.microsoft.com/tr-tr/dotnet/architecture/cloud-native/media/types-of-nosql-datastores.png" width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We use storage systems. So we need to know how to use them. Underlying storage systems might affect our data structure. Wrongly designed schemas affects performance of the application.&lt;/p&gt;

&lt;p&gt;How to store and retrieve data? Is there a faster way to access data? Do I need to do db calls all the time? We need to be able to answer these questions.&lt;/p&gt;

&lt;p&gt;When we using a database (sql/nosql), we need to take a look how to index data, how to apply right schema, how to retrieve it etc.&lt;/p&gt;

&lt;p&gt;We also might need to take the overhead from db and use a cache solution. We can cache frequently accessed data.&lt;/p&gt;




&lt;p&gt;I am stopping here and wishing you to enjoy while reading.&lt;/p&gt;

&lt;p&gt;This list contains the first things that comes into my mind. There are so many other parts to consider while developing an application. Like eventually consistency, event sourcing, circuit breaker, retries, distributed locks, saga, state machines etc..&lt;/p&gt;

&lt;p&gt;If you have any suggestion/addition to list write it on comments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You can follow me on:

https://twitter.com/mstrYoda_

https://github.com/mstrYoda

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/mstrYoda"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CQvhqaK6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.buymeacoffee.com/buttons/default-black.png" alt="Buy Me A Coffee" width="434" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>career</category>
    </item>
    <item>
      <title>Extending Envoy Proxy - WASM Filter with Golang</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Sun, 24 Jul 2022 17:50:00 +0000</pubDate>
      <link>https://dev.to/mstryoda/extending-envoy-proxy-wasm-filter-with-golang-j8n</link>
      <guid>https://dev.to/mstryoda/extending-envoy-proxy-wasm-filter-with-golang-j8n</guid>
      <description>&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%2F6vnr2s9a9f2uo66kyt96.png" 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%2F6vnr2s9a9f2uo66kyt96.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Envoy is an open source service proxy especially designed for cloud native applications. It has a wide variety of features like connection pooling, retry mechanism, TLS management, compression, health checking, fault injection, rate limiting, authorization etc. Those are achieved with &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/http_filters" rel="noopener noreferrer"&gt;built-in http filters&lt;/a&gt;. And today I will talk about a special filter which name is &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/wasm_filter" rel="noopener noreferrer"&gt;WASM Filter&lt;/a&gt;.&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%2Fzrxi0yr80kn319furt2p.png" 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%2Fzrxi0yr80kn319furt2p.png" alt="Drawed in excalidraw.com by Emre Savcı&amp;lt;br&amp;gt;
"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This article is not meant for explaining what is WASM, so I am skipping explaining WASM instead I will add resources for that at the end of the article.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why We Use WASM Filter
&lt;/h2&gt;

&lt;p&gt;In Trendyol Tech. We are using Istio as a service mesh. And our team’s (DevX) responsibility is improving developer experience by developing applications which meets common requirements of microservice’s like caching, authorization, rate limiting, cross cluster service discovery etc.&lt;/p&gt;

&lt;p&gt;Since we already use Istio why not take advantages of the power of Envoy Proxy’s extensibility.&lt;/p&gt;

&lt;p&gt;Our use case is acquiring JWT token for microservice’s which identifies that microservice application. When we want to avoid every team to write the same code in different languages, we can create a WASM Filter and inject it into Envoy Proxies.&lt;/p&gt;

&lt;p&gt;Advantages of WASM Filters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It allows to write code in any language which has WASM support&lt;/li&gt;
&lt;li&gt;Dynamically load code to Envoy&lt;/li&gt;
&lt;li&gt;WASM code is isolated from Envoy so crashes in WASM not affect Envoy&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;In Envoy Proxy there are worker threads that handles incoming requests. Every worker thread has its own WASM VM. So if you write time based operational code it works separately for every thread.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In Envoy Proxy every worker thread isolated from each other and has one or multiple WASM VM. There is also a concept called &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/wasm/v3/wasm.proto#extensions-wasm-v3-wasmservice" rel="noopener noreferrer"&gt;WASM Service&lt;/a&gt; for inter thread communications and data sharing (we are not cover this).&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%2Fsb18ug366p0p41nbuy33.png" 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%2Fsb18ug366p0p41nbuy33.png" alt="Drawed in excalidraw.com by Emre Savcı"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Writing WASM in Go
&lt;/h2&gt;

&lt;p&gt;We are going to use &lt;a href="https://github.com/tetratelabs/proxy-wasm-go-sdk" rel="noopener noreferrer"&gt;tetratelabs/proxy-wasm-go-sdk&lt;/a&gt; to write WASM in Go. We also need &lt;a href="https://tinygo.org/" rel="noopener noreferrer"&gt;TinyGo&lt;/a&gt; to build our Go code as WASM.&lt;/p&gt;

&lt;p&gt;Our use case is very simple so we write a code which sends request to JWT Api for every 15 second. It extracts authorization header and sets it’s value to a global variable and puts that value to response header of every incoming request. We also set “hello from wasm” value to another header called “x-wasm-filter“.&lt;/p&gt;

&lt;p&gt;In the OnTick function we are making http call to a service known by Envoy as cluster.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Let’s build our go code as WASM:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

tinygo build -o optimized.wasm -scheduler=none -target=wasi ./main.go


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Now we need to configure Envoy Proxy to use WASM Filter for incoming requests. We will define a routing rule and a WASM filter for our WASM code, also we define a cluster which represents our service.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;I put all of the files into same directory. Now let’s run Envoy Proxy in Docker:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

docker run -it — rm -v "$PWD"/envoy.yaml:/etc/envoy/envoy.yaml -v "$PWD"/optimized.wasm:/etc/envoy/optimized.wasm -p 9901:9901 -p 10000:10000 envoyproxy/envoy:v1.17.0


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;As we can see from logs our WASM Filter started to work and sending request to JWT Api in every 15 secon&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%2F6g5d52fe3jt0o42o146p.png" 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%2F6g5d52fe3jt0o42o146p.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s send a request to Envoy Proxy. We configure Envoy to listen incoming requests from 1000 port and we start our container with port mapping. So we can send request to localhost:10000:&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%2Fhiffztzdp2qerh2jn8xz.png" 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%2Fhiffztzdp2qerh2jn8xz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the response headers we can see “x-wasm-filter: hello from wasm” and “x-auth” values.&lt;/p&gt;



&lt;p&gt;Thank you for reading so far. I hope it will give you a perspective about how and why use WASM in Envoy Proxy.&lt;/p&gt;

&lt;p&gt;You can see full example in github:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mstrYoda" rel="noopener noreferrer"&gt;
        mstrYoda
      &lt;/a&gt; / &lt;a href="https://github.com/mstrYoda/envoy-proxy-wasm-filter-golang" rel="noopener noreferrer"&gt;
        envoy-proxy-wasm-filter-golang
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A WASM Filter for Envoy Proxy written in Golang
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;envoy-proxy-wasm-filter-golang&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;A WASM Filter for Envoy Proxy written in Golang&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Build&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;tinygo build -o optimized.wasm -scheduler=none -target=wasi ./main.go&lt;/code&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Run Envoy Proxy in Docker with WASM Filter&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;docker run -it --rm -v "$PWD"/envoy.yaml:/etc/envoy/envoy.yaml -v "$PWD"/optimized.wasm:/etc/envoy/optimized.wasm -p 9901:9901 -p 10000:10000 envoyproxy/envoy:v1.17.0&lt;/code&gt;&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mstrYoda/envoy-proxy-wasm-filter-golang" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://webassembly.org/" rel="noopener noreferrer"&gt;
      webassembly.org
    &lt;/a&gt;
&lt;/div&gt;



&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/WebAssembly" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.mozilla.org%2Fmdn-social-share.d893525a4fb5fb1f67a2.png" height="auto" class="m-0"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://developer.mozilla.org/en-US/docs/WebAssembly" rel="noopener noreferrer" class="c-link"&gt;
          WebAssembly | MDN
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          WebAssembly is a type of code that can be run in modern web browsers — it is a low-level assembly-like language with a compact binary format that runs with near-native performance and provides languages such as C/C++, C# and Rust with a compilation target so that they can run on the web. It is also designed to run alongside JavaScript, allowing both to work together.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.mozilla.org%2Ffavicon-48x48.bc390275e955dacb2e65.png"&gt;
        developer.mozilla.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://thenewstack.io/wasm-modules-and-envoy-extensibility-explained-part-1/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.thenewstack.io%2Fmedia%2F2021%2F05%2F5a270fb3-creating-3682101_1280.jpg" height="auto" class="m-0"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://thenewstack.io/wasm-modules-and-envoy-extensibility-explained-part-1/" rel="noopener noreferrer" class="c-link"&gt;
          Wasm Modules and Envoy Extensibility Explained, Part 1 - The New Stack
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          If you've ever wondered what WebAssembly (Wasm) is and how it fits into the service mesh ecosystem, this is the article you want to read.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthenewstack.io%2Ffavicon.ico"&gt;
        thenewstack.io
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/tetratelabs" rel="noopener noreferrer"&gt;
        tetratelabs
      &lt;/a&gt; / &lt;a href="https://github.com/tetratelabs/proxy-wasm-go-sdk" rel="noopener noreferrer"&gt;
        proxy-wasm-go-sdk
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      WebAssembly for Proxies (Go SDK)
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-alert markdown-alert-warning"&gt;
&lt;p class="markdown-alert-title"&gt;Warning&lt;/p&gt;
&lt;p&gt;We are no longer recommending this SDK or Wasm in general for anyone due to the fundamental memory issue of TinyGo (See &lt;a href="https://github.com/tetratelabs/proxy-wasm-go-sdk/issues/450#issuecomment-2253729297" rel="noopener noreferrer"&gt;the detailed explanation&lt;/a&gt; by a long-time community member)
as well as &lt;a href="https://github.com/envoyproxy/envoy/issues/35420" rel="noopener noreferrer"&gt;the project state of Proxy-Wasm in general&lt;/a&gt;
If you are not in a position where you have to run untrusted binaries (like for example, you run Envoy proxies while your client gives you the binaries to run), we recommend using other extension mechanism
such as Lua or External Processing which should be comparable or better or worse depending on the use case.&lt;/p&gt;
&lt;p&gt;If you are already using this SDK, but still want to continue using Wasm for some reason instead of Lua or External Processing
we strongly recommend migrating to the Rust or C++ SDK due to the memory issue of TinyGo described in the link above.&lt;/p&gt;
&lt;p&gt;We keep this repository open and not archived…&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/tetratelabs/proxy-wasm-go-sdk" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&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%2Fvox3yovcym9tyhqn7uvp.png" 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%2Fvox3yovcym9tyhqn7uvp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can follow me on:&lt;br&gt;
&lt;a href="https://twitter.com/mstrYoda_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/emre-savc%C4%B1-70a849a6/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mstrYoda" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/mstrYoda" rel="noopener noreferrer"&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%2Ftwve1hh3j8ewl5aowo7r.png" alt="Buy Me A Coffee"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>kubernetes</category>
      <category>devops</category>
    </item>
    <item>
      <title>Software Interview Processes Recommendations</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Thu, 21 Jul 2022 06:56:00 +0000</pubDate>
      <link>https://dev.to/mstryoda/software-interview-processes-recommendations-3j1d</link>
      <guid>https://dev.to/mstryoda/software-interview-processes-recommendations-3j1d</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwt5kcqngkmea3p19l8zf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwt5kcqngkmea3p19l8zf.png" alt="Image description" width="612" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Greetings, in this article, I will share with you some of my views that occurred over a period of time so that both parties can have a good experience in software interviews.&lt;/p&gt;

&lt;p&gt;First of all, regardless of the outcome of the interview, I think that the interview should contribute to both parties. The candidate should be able to leave the interview by learning new things. These things can be a technical topic, process, product, or approach.&lt;/p&gt;

&lt;p&gt;The interviewer, on the other hand, should be able to learn to analyze people with different characters, measure different levels of knowledge, direct the subject, and create a healthy communication environment.&lt;/p&gt;

&lt;p&gt;In this process, there are important responsibilities that fall on the parties. Now let’s go over the topics that we will examine these responsibilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  Preliminary
&lt;/h2&gt;

&lt;p&gt;The first issue I would like to mention is that the parties should have information about each other before the interview.&lt;/p&gt;

&lt;p&gt;Having information about the company, team, and project you are going to interview contains important clues to prepare for an interview, you can predict what you will encounter. It allows you to prepare in advance some questions that you can ask during the interview.&lt;/p&gt;

&lt;p&gt;Having information about the candidate allows the interviewers to have an interview that is suitable for the level and experience of the candidate, to skip the boring interview questions, and measure the hands-on experience of the candidate directly through the tasks he took in his previous projects and the work he has done.&lt;/p&gt;

&lt;p&gt;This preliminary preparation also saves time to be lost by explaining the resume or the team during the interview.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ability to Problem Solving
&lt;/h2&gt;

&lt;p&gt;Rather than trying to measure the mere knowledge of the candidate you are interviewing, asking questions that will reveal the candidate’s problem-solving ability will help you see the abilities of the person you are interviewing. Specific information, a piece of code, and the behavior of a framework may not come to mind at that moment, it may be forgotten. This does not mean that the person in front of you is ignorant.&lt;/p&gt;

&lt;p&gt;One thing that the interviewees should not forget is that they must demonstrate their problem-solving skills in the interview.&lt;/p&gt;




&lt;h2&gt;
  
  
  Not Personalizing Processes
&lt;/h2&gt;

&lt;p&gt;What is meant by personalizing the process? What processes can be personalized in an interview?&lt;/p&gt;

&lt;p&gt;For the candidates who are interviewed, you should consider that the questions posed to you are not so that you cannot answer, but to measure how much you know about a subject. These opposing thoughts will make you tense in the interview and feel cornered.&lt;/p&gt;

&lt;p&gt;Interviewers, on the other hand, should not have an ego-satisfaction motive on candidates. Without focusing on understanding what the candidate knows, interviewers should not try to get pre-prepared answers specific to the subject that already knows. Be aware that you are not in a race for supremacy. There is a very important ethical value here, at that moment your company gives you the responsibility to take the deserved person to the position they deserve. You must not abuse this responsibility.&lt;/p&gt;

&lt;p&gt;Another thing that should not be personalized, regardless of the interview process, is that you should describe your problem (for example, a person with whom you have problems in your working life) without personalizing it, through a cause-effect relationship. So how can this be done? Let’s say that when you are asked about something that you are uncomfortable with, instead of saying, “I am uncomfortable with person A, I do not work with it, he is so and so”, instead of saying “exhibiting x behaviors causes y results, these negative results disturb the motivation/peace of the employees”, it shows that you do not personalize the issue, on the contrary, you are in favor of improving processes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Being realistic
&lt;/h2&gt;

&lt;p&gt;Yes, another important issue is to be realistic. Candidates who are interviewed should first determine their expectations from the company, their working environment, and the team they will work with (salary, fringe benefits, technical responsibility, culture) and should also be able to transparently state that they can add them to the team. This is an important situation in terms of maintaining the motivation of both yourself and the other party. He should also be aware that pretending to do things he hasn’t already done will not make a good impression as it will weaken the current team dynamics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj5zceylurxiqjnw7f87m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj5zceylurxiqjnw7f87m.png" alt="Image description" width="402" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The interviewer, on the other hand, should not raise the candidate’s expectations in such a way that cannot meet them. The image above sums up what I’m about to say. A developer who joins the team thinking that he will deal with different technical challenges every day will lose his motivation and enthusiasm quite quickly when he spends his day only with crud transactions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pieces of Advice
&lt;/h2&gt;

&lt;p&gt;Yes, we’ve gone over the general topics so far. Now, I would like to briefly share a few recommendations with you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers&lt;/strong&gt;: Before starting to solve the problems posed to you, ask questions to find out the extent of the problem. Set limits. How many users will use the system Can the process be managed asynchronously HA, what are the consistency priorities…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6k5sr9pqpj6oo4on2az.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6k5sr9pqpj6oo4on2az.png" alt="Image description" width="700" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interviewers&lt;/strong&gt;: You should not leave the candidate alone in the interview. The moment you feel that the interviewee is lost, you must take on the role of guiding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers&lt;/strong&gt;: Problems do not have a single correct solution. There are different approaches. Don’t be fooled into thinking that the other party is waiting for a single clear answer from you. Interpret the problem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vhi9eif8tvqopjkda6o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vhi9eif8tvqopjkda6o.png" alt="Image description" width="259" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interviewers&lt;/strong&gt;: You cannot measure any knowledge or ability with stereotyped questions. Do not use rote interview questions and techniques.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers&lt;/strong&gt;: When you come across a question you don’t know, don’t just say you don’t know and throw it away. In the worst case, try to find direction by asking questions to find out what you don’t know so that you can come up with a solution. Otherwise, your ability to produce solutions cannot be measured.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr3hrvjgjmhvkcdxd5ve2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr3hrvjgjmhvkcdxd5ve2.png" alt="Image description" width="525" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interviewers&lt;/strong&gt;: The candidates are not the prisoners you question. They do not have to memorize a topic, tool, or code that you have learned specifically at your workplace. Being aware of this, measure the interviewee’s approach specific to a subject. Do not try to measure mere knowledge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers&lt;/strong&gt;: Practice topics like design patterns, microservices, data structures, DDD, unit testing, architecture, caching, scaling, cap, message brokers, CI/CD. These topics will come up in most interviews.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qdswk9x9bb450iwuccf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qdswk9x9bb450iwuccf.png" alt="Image description" width="501" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interviewers&lt;/strong&gt;: Inform the candidate on a question that the candidate does not know or cannot answer correctly. Both you and your company will gain value in the eyes of a candidate who leaves the interview by learning something. Thus, even if the interview is negative, there will be no loss for both parties.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers&lt;/strong&gt;: The team you will work with, the work you will do, the technologies used, the projects developed, the way of doing business, company culture, incident management… Ask questions about anything that comes to your mind. If you do not work in a happy and productive environment, you cannot be beneficial to yourself or the company.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuq4yviug1sep50a5224h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuq4yviug1sep50a5224h.png" alt="Image description" width="265" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interviewers&lt;/strong&gt;: Asking questions about the problems you are dealing with to get the right person to your team allows you to recruit people with the same perspective and interests. If the person you ask utopian questions to writes “just crud”, they will be disappointed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers&lt;/strong&gt;: On something actually you don’t know anything about, do not pretend like you have knowledge about it. It is very easily understood and certainly does not leave a good impression.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interviewers&lt;/strong&gt;: Choose your co-workers from people who fit the current team culture. Someone will not be included in the team just because they have technical knowledge, nor will they be eliminated because you find their technical knowledge insufficient. Technical knowledge can be gained later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers&lt;/strong&gt;: Do not disparage your old company, or your colleagues. If you’ve had a problem, talk about the “problematic behavior” without personalizing it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0bkj8mscc8ev10m4gczd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0bkj8mscc8ev10m4gczd.png" alt="Image description" width="185" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interviewers&lt;/strong&gt;: Get up-to-date information about the candidate’s past projects and interests. Don’t ask funny questions like what is SOLID, what is Factory Pattern, to an experienced candidate who has worked on good projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers&lt;/strong&gt;: Questions will be asked in order to measure how experienced you are on a subject. Don’t feel cornered or questioned. Remember that you can ask counter-questions as part of the process and you don’t have to know everything.&lt;/p&gt;




&lt;p&gt;Thank you for reading so far. See you in another article.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Want to Connect?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/mstrYoda_"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/emre-savc%C4%B1-70a849a6/"&gt;Linkedin&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mstrYoda"&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/mstrYoda"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CQvhqaK6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.buymeacoffee.com/buttons/default-black.png" alt="Buy Me A Coffee" width="434" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Software Developers, You Needn’t Be Perfect</title>
      <dc:creator>Emre Savcı</dc:creator>
      <pubDate>Thu, 21 Jul 2022 06:48:00 +0000</pubDate>
      <link>https://dev.to/mstryoda/software-developers-you-neednt-be-perfect-17gn</link>
      <guid>https://dev.to/mstryoda/software-developers-you-neednt-be-perfect-17gn</guid>
      <description>&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%2Fj9bf8ylqp35oi6jl8gpo.png" 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%2Fj9bf8ylqp35oi6jl8gpo.png" alt="Photo by Vitolda Klein on Unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lately, I have observed that developers, especially the ones who’re starting out — are under the influence of different factors and get lost in the concept of “perfectionism”.&lt;/p&gt;

&lt;p&gt;We, as developers, want the best for ourselves and what we produce. As we build from scratch it’s natural to be committed to what we produce. Hoping it’s flawless. This is one of the factors that force us to be “perfect”.&lt;/p&gt;

&lt;p&gt;So, is being perfect a realistic goal?&lt;/p&gt;

&lt;p&gt;Do we have to be perfect? Or are we unintentionally forced to be perfect?&lt;/p&gt;




&lt;h2&gt;
  
  
  You don’t have to keep up with everything
&lt;/h2&gt;

&lt;p&gt;We know that the software community has a multidisciplinary structure. The emergence of a working code is the result of the collaboration of scientists, mathematicians, and programmers.&lt;/p&gt;

&lt;p&gt;You will meet people with different knowledge and experience in such a field. In such a situation, you should not feel inadequate.&lt;/p&gt;

&lt;p&gt;Backend, frontend, DevOps, security, AI/ML, design, infrastructure, cloud…&lt;/p&gt;

&lt;p&gt;Go, Java, C#, Python, Kotlin, Scala, Haskell, f#, Elixir, C/C++, JavaScript.&lt;/p&gt;

&lt;p&gt;Different areas of expertise, different tools, different approaches. If you try to learn all of them, at the end of the day you will remain a tired and exhausted “coder” who has not learned any of them completely.&lt;/p&gt;

&lt;p&gt;You don’t have to know everything. No one expects such a thing from you. Which is not an attainable goal in finite human life anyway. You should not expect yourself to know everything.&lt;/p&gt;

&lt;p&gt;“But people on the Internet know many things, they are very good and successful in everything?”&lt;/p&gt;

&lt;p&gt;If you say so, let’s move on to the next topic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Social media fallacy
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The world is like a stage. Everyone plays their part in this scene, and when their role is over, they leave this scene forever.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shakespeare&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;You may be deceived by what you see on Twitter and LinkedIn and get the impression that people are always highly motivated, hard-working, never making mistakes, and know everything. But the truth of the matter is not at all what it seems. Most people do not share the facts, they only share the parts they want you to see. This, in general, reveals the misconception that those persons are “constantly successful and good at everything”.&lt;/p&gt;

&lt;p&gt;People share their best moments on social media because they don’t want their failures to be seen. However, experience is gained as a result of failures and mistakes. It is hidden that this is a natural process and the perception is created that they are flawless and perfect. This is an illusion. Do not lose your motivation and self-confidence when you make a mistake or fail to achieve the desired result after a few tries. You make as many mistakes as anyone else. Treat yourself fairly.&lt;/p&gt;

&lt;p&gt;Having lots of basic-level posts on different topics does not necessarily make a person very knowledgeable.&lt;/p&gt;

&lt;p&gt;As Morpheus said, “There is a difference between knowing the way and walking on it”. Since even specializing in a single subject is something that requires many years of effort, you should not get the thought of “how much people know, I miss everything” after every post you see.&lt;/p&gt;

&lt;p&gt;In the same way, do not view people you see on social media as those who live everyday with a plan. Who do not miss anything. Who continue to write code with one hand while rubbing an avocado on toasted bread in the morning. Who never make mistakes and know the best of everything.&lt;/p&gt;

&lt;p&gt;It wouldn’t hurt to play games for a few hours, spend time with your friends, or even take time for yourself to do nothing sometimes. On the contrary, sometimes you need to do these things to clear your mind and relax.&lt;/p&gt;

&lt;p&gt;So, don’t get caught up in thoughts like “I wish I had written code instead of playing games”, “I wish I had read a few more articles instead of watching movies”, “I should have looked at projects instead of going out with my friends”. There’s nothing wrong with living your life. The activities you will do to distract yourself a little will not hinder your self-development.&lt;/p&gt;

&lt;p&gt;Another concern is the effort people put to be justified — simply by hiding behind the masses. Even when something you think could be wrong, your sense of truth can suffer when too many people take the opposite view.&lt;/p&gt;

&lt;p&gt;Popularity, combined with fanaticism leads to the veiling of reality and the perception that what is being advocated is true. However, every truth can be defended, but not all defended truths.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“There is no doubt that our age… prefers the description to the object, the copy to the original, the representational to the reality, the outer appearance to the essence… The only thing sacred for our age is illusion, the only thing that is not sacred is truth.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Perfection has no limits
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Chasing the impossible is insane.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Marcus Aurelius&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;What is perfect? To be faultless? To be the best?&lt;/p&gt;

&lt;p&gt;What is the definition of good? How good is the best?&lt;/p&gt;

&lt;p&gt;How to gain experience if no mistakes are made?&lt;/p&gt;

&lt;p&gt;Does knowing everything perfection? Can everything be known?&lt;/p&gt;

&lt;p&gt;Go deep into something? How deep do you go?&lt;/p&gt;

&lt;p&gt;Knowing all the libraries of a programming language by heart?&lt;/p&gt;

&lt;p&gt;How many of these do we need? Is it necessary to be perfect if what is needed is enough?&lt;/p&gt;

&lt;p&gt;The answers to the above questions are things that can change from person to person and whose boundaries cannot be determined. Trying to reach something immaterial that cannot be defined in the same way by everyone will be nothing more than a futile effort.&lt;/p&gt;

&lt;p&gt;In the past, perfection for me was knowing at the source code level what the code I wrote and the product I used was doing in the background in each process. But this is not an achievable and sustainable goal.&lt;/p&gt;

&lt;p&gt;Knowing the language, orm tool, http package, database, operating system, kernel/CPU calls, and network operations at the source code level, it is impossible to try to learn more than one in this list. This is not perfection, it is madness. There is no need for such a thing.&lt;/p&gt;

&lt;p&gt;You too may have different definitions of perfection. It doesn’t feel right to generalize such a variable, ambiguous and abstract concept for everyone and to put it in front of people as if it is a goal that needs to be reached.&lt;/p&gt;

&lt;p&gt;Most of the time, it will be “sufficient” to know the tool you use enough to reveal something, solve your problem, to be able to build on it by researching and learning.&lt;/p&gt;

&lt;p&gt;You need a lot to be perfect, and the more your needs, the more restricted your freedom. Freedom is not needed — to be enough, to be self-sufficient…&lt;/p&gt;

&lt;p&gt;So does happiness come from having something or not wanting anything to have?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Freedom is not the right or ability to do whatever you want.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Epictetus&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Perfect is the enemy of the good
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“We are what we constantly do, excellence is a habit, not an act.”&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aristotle&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;How many projects do you have that you strive to be perfect but can’t finish?&lt;/p&gt;

&lt;p&gt;How many codes do you have that you are afraid to share because you think it is not perfect?&lt;/p&gt;

&lt;p&gt;How many attempts have you failed to do because you couldn’t find the perfect idea?&lt;/p&gt;

&lt;p&gt;How many blog posts are there that you didn’t write because there wasn’t great content?&lt;/p&gt;

&lt;p&gt;Do you realize how much trying to be perfect causes us to miss out? In fact, what we need is to come up with a working project, write and share the right code, and have the courage to try an idea. To try, to do, to complete. These are far more important concepts than perfection.&lt;/p&gt;

&lt;p&gt;Don’t let others define how you should be. Keep in mind that striving to be perfect deprives you of how many things.&lt;/p&gt;

&lt;p&gt;In seeking the perfect, we lose the good enough.&lt;/p&gt;




&lt;h2&gt;
  
  
  Not to compete with anyone
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“The wise man does not compete with anyone, so no one can win against him.”&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lao Tzu&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Competing with others is another occupation that will consume you. Comparing yourself to others every day and trying to be like them or better will wear you out both mentally and physically.&lt;/p&gt;

&lt;p&gt;The only thing you need to compare yourself is how you were the day before. Trying to ensure your development by focusing entirely on yourself will eliminate the distraction and demotivating situations that will arise from external factors.&lt;/p&gt;




&lt;h2&gt;
  
  
  Your progress is up to you, not perfection
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;There is only one path to happiness; and not worrying about events that you can do nothing about.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Epictetus&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;We want to improve ourselves to feel better, achieve our goals, and be happy people.&lt;/p&gt;

&lt;p&gt;You don’t have to try to be perfect while doing this.&lt;/p&gt;

&lt;p&gt;Setting achievable goals and working towards those goals will bring you to the level you want. Development is achieved not by trying to be perfect, but by working hard in a disciplined way.&lt;/p&gt;

&lt;p&gt;Setting achievable goals during this process will help you stay motivated. If you constantly set big goals and cannot reach them, you start to feel that you are running out over time and that your old enthusiasm is no longer there.&lt;/p&gt;

&lt;p&gt;What you really need is not to be perfect, but to have discipline and habit.&lt;/p&gt;

&lt;p&gt;As long as you keep yourself in shape by regularly writing code, reading articles, and doing research, the development will be inevitable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It doesn’t matter how slow you go as long as you don’t stop.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Andy Warhol&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;p&gt;Now, without waiting any longer, share your first code, realize your first idea, write your first article, and complete your first project.&lt;/p&gt;

&lt;p&gt;It doesn’t have to be perfect. Being yours makes it special.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Want to Connect?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/mstrYoda_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/emre-savc%C4%B1-70a849a6/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/mstrYoda" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/mstrYoda" rel="noopener noreferrer"&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%2Ftwve1hh3j8ewl5aowo7r.png" alt="Buy Me A Coffee"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>career</category>
    </item>
  </channel>
</rss>
