<?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: Sergio Marcial</title>
    <description>The latest articles on DEV Community by Sergio Marcial (@sergiomarcial).</description>
    <link>https://dev.to/sergiomarcial</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%2F446297%2F29e3bea5-fb1e-4322-8278-f8661eebfdcb.jpg</url>
      <title>DEV Community: Sergio Marcial</title>
      <link>https://dev.to/sergiomarcial</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sergiomarcial"/>
    <language>en</language>
    <item>
      <title>Unveiling gRPC: Empowering Microservices Beyond REST 🚀</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Thu, 05 Oct 2023 15:32:32 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/unveiling-grpc-empowering-microservices-beyond-rest-57mc</link>
      <guid>https://dev.to/sergiomarcial/unveiling-grpc-empowering-microservices-beyond-rest-57mc</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;In the realm of microservices and distributed systems, choosing the right communication protocol is paramount. Enter gRPC, a high-performance, language-agnostic, and versatile framework that's rapidly gaining traction. In this article, we'll embark on a journey to explore gRPC, understand its role in microservices architecture, dissect the differences between gRPC and REST, and unravel when it's advantageous to opt for gRPC over REST. Buckle up; it's going to be an exciting ride!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is gRPC?
&lt;/h2&gt;

&lt;p&gt;gRPC, which stands for Google Remote Procedure Call, is an open-source framework for remote procedure calls (RPC) that enables communication between distributed systems. It uses Protocol Buffers (Protobuf) as its interface definition language (IDL), providing a flexible and efficient way to define service contracts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of gRPC:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High Performance:&lt;/strong&gt; gRPC is known for its speed and efficiency. It uses HTTP/2, which offers multiplexing, header compression, and more, resulting in lower latency and improved throughput.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Language-Agnostic:&lt;/strong&gt; You can generate client and server code in various programming languages, making gRPC suitable for polyglot microservices environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Strong Typing:&lt;/strong&gt; Protobuf enforces a strong type system for messages, reducing errors and ensuring robust communication.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  gRPC in Microservices:
&lt;/h2&gt;

&lt;p&gt;gRPC seamlessly integrates into microservices architectures, enhancing the communication between services. Its features align well with the requirements of microservices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Efficiency:&lt;/strong&gt; gRPC's binary serialization (Protobuf) and multiplexing are well-suited for microservices' resource-constrained environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Streaming:&lt;/strong&gt; gRPC supports both unary (single request, single response) and bidirectional streaming, accommodating various microservices communication patterns.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service Discovery:&lt;/strong&gt; It pairs well with service discovery tools like Kubernetes, Consul, or etcd, facilitating dynamic service registration and resolution.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  gRPC vs. REST:
&lt;/h2&gt;

&lt;p&gt;Now, let's delve into the distinctions between gRPC and REST.&lt;/p&gt;

&lt;h3&gt;
  
  
  gRPC:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Protocol:&lt;/strong&gt; HTTP/2, binary-based, using Protobuf for message serialization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communication:&lt;/strong&gt; Bidirectional streaming is possible, enabling real-time updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code Generation:&lt;/strong&gt; Language-specific client and server code generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency:&lt;/strong&gt; Lower payload size, multiplexing, and binary format contribute to higher efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling:&lt;/strong&gt; gRPC uses status codes and details for precise error handling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Cases:&lt;/strong&gt; Real-time applications, IoT, inter-service communication in microservices.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  REST:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Protocol:&lt;/strong&gt; HTTP/1.1 or HTTP/2, text-based (typically JSON).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communication:&lt;/strong&gt; Stateless and follows the request-response model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code Generation:&lt;/strong&gt; No built-in code generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency:&lt;/strong&gt; JSON can be less efficient for large payloads compared to Protobuf.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling:&lt;/strong&gt; Uses HTTP status codes, but often relies on additional context in response payloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Cases:&lt;/strong&gt; Public APIs, web services, mobile apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to Choose gRPC:
&lt;/h2&gt;

&lt;p&gt;Now, the million-dollar question: When should you opt for gRPC over REST?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Real-Time Updates:&lt;/strong&gt; If your microservices require real-time communication or bidirectional streaming (e.g., chat applications), gRPC is a compelling choice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Efficiency Matters:&lt;/strong&gt; For resource-constrained environments or when bandwidth is a concern, gRPC's binary format and multiplexing offer a clear advantage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Strong Typing:&lt;/strong&gt; When strong typing and code generation are essential for maintaining robust communication contracts across different services.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Code Examples:
&lt;/h2&gt;

&lt;p&gt;Let's take a glimpse at gRPC in action with code examples in various languages:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Go:&lt;/strong&gt; Creating a gRPC server and client.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Find the detailed code example with instructions &lt;a href="https://github.com/sergiommarcial/protobuf-python-example"&gt;here&lt;/a&gt;&lt;/strong&gt;&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="c"&gt;// Import the necessary packages.&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net"&lt;/span&gt;

    &lt;span class="n"&gt;pb&lt;/span&gt; &lt;span class="s"&gt;"github.com/sergiommarcial/gen"&lt;/span&gt; &lt;span class="c"&gt;// Import your generated proto package&lt;/span&gt;

    &lt;span class="s"&gt;"google.golang.org/grpc"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataResponse&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Reply&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Hello, "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;lis&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;":50051"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to listen: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewServer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Create a gRPC client.&lt;/span&gt;
    &lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterMyServiceServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UnimplementedMyServiceServer&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="c"&gt;// Set up a connection to the gRPC server.&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Server started on :50051..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lis&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to serve: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&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;Explanation&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Import the necessary packages, including the gRPC package and your gRPC protocol buffer package (pb), which contains the service definition and message types.&lt;/p&gt;

&lt;p&gt;In the main function, establish a connection to the gRPC server running on localhost:50051. The grpc.Dial function is used to create a connection, and we specify grpc.WithInsecure() for simplicity. In production, you should use a secure connection.&lt;/p&gt;

&lt;p&gt;Create a gRPC client for your service using the generated client code from your .proto definition file. Replace NewYourServiceClient with the actual client constructor generated by protoc.&lt;/p&gt;

&lt;p&gt;Define your request message. Populate this message with the data you want to send to the server.&lt;/p&gt;

&lt;p&gt;Call the gRPC method on the server using the client you created. Replace YourGrpcMethod with the actual method name from your .proto file.&lt;/p&gt;

&lt;p&gt;Handle any errors that occur during the RPC call.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Python:&lt;/strong&gt; Defining a service using Protobuf and Python.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Find the detailed code example with instructions &lt;a href="https://github.com/sergiommarcial/protobuf-python-example"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;grpc&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;concurrent&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;futures&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;example_pb2&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ProtoService&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;example_pb2_grpc&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ProtoServiceGrcp&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyService&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;GetData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ProtoService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;futures&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_workers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;ProtoServiceGrcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_MyServiceServicer_to_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyService&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_insecure_port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'[::]:50051'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wait_for_termination&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'__main__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Node.js:&lt;/strong&gt; Implementing a gRPC server and client in Node.js.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Find the detailed code example with instructions &lt;a href="https://github.com/sergiommarcial/protobuf-nodejs-example"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;grpc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grpc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;protoLoader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@grpc/proto-loader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;packageDefinition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;protoLoader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loadSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./example.proto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;keepCase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;longs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;enums&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;oneofs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myservice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;grpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loadPackageDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;packageDefinition&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;myservice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;grpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myservice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MyService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Hello, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dataRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.0.0.0:50051&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;grpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ServerCredentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createInsecure&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Starting server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Server started&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Further Reading:
&lt;/h3&gt;

&lt;p&gt;Getting deeper into the world of gRPC and its role in microservices? here are some resources to explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grpc.io/docs/"&gt;gRPC Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/web/fundamentals/codelabs/grpc-intro"&gt;gRPC for Web Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grpc.io/blog/grpc-best-practices/"&gt;gRPC Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Conclusion:&lt;/p&gt;

&lt;p&gt;gRPC represents a powerful evolution in the world of microservices communication. Its efficiency, versatility, and support for real-time communication make it a compelling choice, especially for modern, distributed architectures. As you journey through the microservices landscape, understanding gRPC's capabilities and nuances can be a game-changer, unlocking new possibilities for efficient and scalable communication between your services.&lt;/p&gt;

</description>
      <category>software</category>
      <category>coding</category>
      <category>api</category>
      <category>design</category>
    </item>
    <item>
      <title>✨ Mermaid Markdown: Adding Life and Creativity to your GitHub Markdown Files 👩‍💻🌈📄</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Tue, 19 Sep 2023 05:21:24 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/mermaid-markdown-adding-life-and-creativity-to-your-github-markdown-files-3eie</link>
      <guid>https://dev.to/sergiomarcial/mermaid-markdown-adding-life-and-creativity-to-your-github-markdown-files-3eie</guid>
      <description>&lt;h2&gt;
  
  
  Introduction 🚀
&lt;/h2&gt;

&lt;p&gt;As engineers, we often find ourselves documenting our code, ideas, and processes using Markdown files, whether it's READMEs, project documentation, or collaborative notes. Markdown is a simple and widely adopted markup language for creating easy-to-read and aesthetically pleasing files. However, it lacks the ability to visualize complex data structures or create dynamic diagrams. This is where Mermaid Markdown comes to the rescue!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Mermaid Markdown? 🧜‍♀️
&lt;/h2&gt;

&lt;p&gt;Mermaid Markdown is an innovative extension to standard Markdown that allows you to include visually appealing diagrams, flowcharts, and sequence diagrams in your Markdown files. By integrating Mermaid Markdown into your workflow, you can bring life and interactivity to your documentation, making it easier for readers to understand complex ideas and visualize data flows.&lt;/p&gt;

&lt;h2&gt;
  
  
  What problem does Mermaid Markdown aim to solve? 🎯
&lt;/h2&gt;

&lt;p&gt;Traditional Markdown feels limiting when it comes to expressing complex concepts and relationships. When we want to demonstrate the interaction between different components in a system or visualize a sequence of events, we often resort to external tools or screenshots. This can be time-consuming and doesn't provide the same ease of collaboration as Markdown itself.&lt;/p&gt;

&lt;p&gt;With Mermaid Markdown, you can create diagrams directly within your Markdown files using a simple, human-readable syntax. This allows you to document processes, architectures, and data flows seamlessly, without leaving your Markdown file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enriching your Markdown in GitHub with Mermaid Markdown 🌟
&lt;/h2&gt;

&lt;p&gt;Adding Mermaid Markdown support to your GitHub repositories is a breeze! Follow these steps to get started:&lt;/p&gt;

&lt;h2&gt;
  
  
  Install a Markdown editor with Mermaid support 📝
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;VSCode: Install the "Markdown Preview Mermaid Support" extension.&lt;/li&gt;
&lt;li&gt;IntelliJ: Install the "Mermaid" plugin.&lt;/li&gt;
&lt;li&gt;Other editors: Look for similar extensions or packages specific to your editor.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Include Mermaid Markdown in your Markdown file 🖊️
&lt;/h2&gt;

&lt;p&gt;Use the following code snippet to add a Mermaid diagram to your Markdown file:&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Flowchart:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graph TD;
    A--&amp;gt;B;
    A--&amp;gt;C;
    B--&amp;gt;D;
    C--&amp;gt;D;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XSy1yizp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dkabzwhy5u82k2nhtees.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XSy1yizp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dkabzwhy5u82k2nhtees.png" alt="Image description" width="330" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gantt Chart:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gantt
    dateFormat  YYYY-MM-DD
    title Adding Mermaid Diagrams
    section A section
    task Task 1: 2023-09-01, 7d
    task Task 2: 2023-09-08, 5d
    task Task 3: 2023-09-15, 6d
    section Another section
    task Task 4: 2023-09-01, 8d
    task Task 5: 2023-09-11, 5d
    task Task 6: 2023-09-20, 6d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b5Wu154i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/djocduffmytw55a0vx8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b5Wu154i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/djocduffmytw55a0vx8n.png" alt="Image description" width="800" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Class Diagram:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;classDiagram
    Animal &amp;lt;|-- Duck
    Animal &amp;lt;|-- Fish
    Animal &amp;lt;|-- Zebra
    Animal : +int age
    Animal : +String gender
    Animal: +isMammal()
    Animal: +mate()
    class Duck{
        +String beakColor
        +swim()
        +quack()
    }
    class Fish{
        -int sizeInFeet
        -canEat()
    }
    class Zebra{
        +bool isWild
        +run()
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RjicEc5V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5q0nv989v862tefp0b67.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RjicEc5V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5q0nv989v862tefp0b67.png" alt="Image description" width="800" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can replace this example with your own diagram using Mermaid's extensive syntax.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preview your Markdown locally ✨
&lt;/h2&gt;

&lt;p&gt;Enable the Mermaid Markdown preview in your editor and visualize how the diagram renders alongside your Markdown content. This allows you to make any necessary adjustments before committing the changes to your repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commit and push your changes to GitHub 🚀
&lt;/h2&gt;

&lt;p&gt;Once you're happy with your Mermaid Markdown diagram, commit your changes and push them to GitHub. Your diagrams will be rendered on your repository's GitHub page, dynamically enhancing your documentation and making it more engaging for readers.&lt;/p&gt;

&lt;p&gt;Conclusion 📝&lt;/p&gt;

&lt;p&gt;Mermaid Markdown empowers engineers at all levels to add interactivity and visual creativity to their Markdown files, elevating the quality and comprehensibility of technical documentation. By integrating Mermaid Markdown into your GitHub repositories, you can effectively showcase system architectures, visualize data flows, and create captivating diagrams.&lt;/p&gt;

&lt;p&gt;Don't let the simplicity of Markdown restrict your documentation's potential. Embrace Mermaid Markdown today and give your diagrams the spotlight they deserve! 🎉&lt;/p&gt;

&lt;p&gt;🔗 Additional reading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mermaid Markdown Project: &lt;a href="https://mermaid-js.github.io/mermaid/#/mermaidAPI"&gt;https://mermaid-js.github.io/mermaid/#/mermaidAPI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Mermaid Documentation: &lt;a href="https://mermaid-js.github.io/mermaid"&gt;https://mermaid-js.github.io/mermaid&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Markdown diagramming! 🚀🎨📄&lt;/p&gt;

</description>
      <category>documentation</category>
      <category>beginners</category>
      <category>markdown</category>
      <category>coding</category>
    </item>
    <item>
      <title>Kafka Simplified with kcat (kafka cat) 🚀</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Tue, 12 Sep 2023 04:37:32 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/kafka-simplified-with-kcat-kafka-cat-1gn7</link>
      <guid>https://dev.to/sergiomarcial/kafka-simplified-with-kcat-kafka-cat-1gn7</guid>
      <description>&lt;p&gt;During the continuos travels to demystify Kafka there are multiple tools that can help us better understand the powerful event streaming platform; &lt;/p&gt;

&lt;p&gt;Say hello to &lt;strong&gt;kcat&lt;/strong&gt;, your trusty companion in the world of Apache Kafka! Whether you're just starting your journey or you're a seasoned pro looking to level up your Kafka skills, this guide might be able to provide you with a new tool for your toolbox starting with the installation of kcat on Unix, macOS, and Windows, some basic examples. Plus, we'll explore advanced examples, including custom authentication with SASL and keystore, to help you become a Kafka wizard. Buckle up, and let's dive into the world of Kafka with kcat! 🌟&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing kcat
&lt;/h2&gt;

&lt;p&gt;Before we delve into the installation and usage, let's get to know &lt;strong&gt;kcat&lt;/strong&gt;. It's a command-line utility that's part of the &lt;strong&gt;Confluent&lt;/strong&gt; ecosystem, designed to simplify Kafka interactions. With kcat, you can consume, produce, and interact with Kafka topics seamlessly, making it an essential tool for software engineers working with real-time data streams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Unix and macOS
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Option 1: Package Manager (Recommended)
&lt;/h4&gt;

&lt;p&gt;Unix-based systems, including macOS, offer the convenience of package managers for kcat installation. If you're on a system with APT (e.g., Debian/Ubuntu), run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;kcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For systems using YUM (e.g., CentOS/Red Hat), use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;kcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're using macOS with Homebrew, installation is as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;kcat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Option 2: Manual Installation
&lt;/h4&gt;

&lt;p&gt;For those who prefer manual installation, visit the official Confluent Hub (&lt;a href="https://docs.confluent.io/current/clients/confluent-kafka-python/html/index.html"&gt;https://docs.confluent.io/current/clients/confluent-kafka-python/html/index.html&lt;/a&gt;) to download the appropriate binary for your system. After downloading, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make the binary executable:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x kcat &lt;span class="c"&gt;# Replace with the actual filename for your system&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Move it to a directory in your PATH (e.g., &lt;code&gt;/usr/local/bin/&lt;/code&gt;):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mv &lt;/span&gt;kcat /usr/local/bin/ &lt;span class="c"&gt;# Replace with the actual filename for your system&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;

&lt;p&gt;Windows users can also enjoy the power of kcat by downloading the Windows binary from the official Confluent Hub (&lt;a href="https://docs.confluent.io/current/clients/confluent-kafka-python/html/index.html"&gt;https://docs.confluent.io/current/clients/confluent-kafka-python/html/index.html&lt;/a&gt;) and following these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download the Windows binary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rename the binary to &lt;code&gt;kcat.exe&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the directory containing &lt;code&gt;kcat.exe&lt;/code&gt; to your system's PATH.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that you have kcat installed, let's explore its features with practical examples! 🛠️&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Kafka Message Consumption
&lt;/h3&gt;

&lt;p&gt;Let's start with the basics by consuming messages from a Kafka topic. Suppose you have a Kafka topic named &lt;code&gt;my_topic&lt;/code&gt;, and your Kafka broker is running at &lt;code&gt;kafka_broker_address&lt;/code&gt;. You can use kcat to consume and display messages in real-time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kcat &lt;span class="nt"&gt;-b&lt;/span&gt; kafka_broker_address &lt;span class="nt"&gt;-t&lt;/span&gt; my_topic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;kafka_broker_address&lt;/code&gt; with the address of your Kafka broker. kcat will continuously display messages from &lt;code&gt;my_topic&lt;/code&gt; as they arrive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Producing Kafka Messages
&lt;/h3&gt;

&lt;p&gt;Producing messages to Kafka is just as straightforward. To send a message to a Kafka topic, you can use kcat like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello, Kafka!"&lt;/span&gt; | kcat &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="nt"&gt;-b&lt;/span&gt; kafka_broker_address &lt;span class="nt"&gt;-t&lt;/span&gt; my_topic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command sends the message "Hello, Kafka!" to &lt;code&gt;my_topic&lt;/code&gt;. The &lt;code&gt;-P&lt;/code&gt; flag indicates that we're producing a message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Custom Consumer Groups
&lt;/h3&gt;

&lt;p&gt;Kafka supports consumer groups for parallel message consumption. You can specify a custom consumer group with kcat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kcat &lt;span class="nt"&gt;-b&lt;/span&gt; kafka_broker_address &lt;span class="nt"&gt;-t&lt;/span&gt; my_topic &lt;span class="nt"&gt;-g&lt;/span&gt; my_consumer_group
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;my_consumer_group&lt;/code&gt; with the name of your custom consumer group. kcat handles group coordination for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consuming and Writing to a File
&lt;/h3&gt;

&lt;p&gt;Often, you may want to consume messages from a Kafka topic and save them to a file for later analysis. You can achieve this with kcat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kcat &lt;span class="nt"&gt;-b&lt;/span&gt; kafka_broker_address &lt;span class="nt"&gt;-t&lt;/span&gt; my_topic &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; output.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command continuously consumes messages from &lt;code&gt;my_topic&lt;/code&gt; and appends them to &lt;code&gt;output.txt&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Filtering and Transforming Messages
&lt;/h3&gt;

&lt;p&gt;kcat allows you to apply filtering and transformations to consumed messages using a simple pipe (&lt;code&gt;|&lt;/code&gt;) syntax. For instance, you can filter messages containing the word "error" like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kcat &lt;span class="nt"&gt;-b&lt;/span&gt; kafka_broker_address &lt;span class="nt"&gt;-t&lt;/span&gt; my_topic | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"error"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command displays only the messages containing "error," making it easier to focus on specific events.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kafka Header Support
&lt;/h3&gt;

&lt;p&gt;Kafka message headers provide additional metadata. kcat supports header manipulation. To send a message with a custom header, you can use the &lt;code&gt;-H&lt;/code&gt; option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Important message"&lt;/span&gt; | kcat &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="nt"&gt;-b&lt;/span&gt; kafka_broker_address &lt;span class="nt"&gt;-t&lt;/span&gt; my_topic &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"header_key=header_value"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sends a message with a custom header to &lt;code&gt;my_topic&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Authentication
&lt;/h3&gt;

&lt;p&gt;Kafka often requires custom authentication mechanisms for secure communication. If your Kafka cluster uses SASL (Simple Authentication and Security Layer) and truststore/keystore certs, you can use kcat with the following options:&lt;/p&gt;

&lt;p&gt;SASL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kcat &lt;span class="nt"&gt;-b&lt;/span&gt; kafka_broker_address &lt;span class="nt"&gt;-t&lt;/span&gt; my_topic &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; security.protocol&lt;span class="o"&gt;=&lt;/span&gt;SASL_SSL &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; sasl.mechanisms&lt;span class="o"&gt;=&lt;/span&gt;PLAIN 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Truststore/Keystore&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kcat &lt;span class="nt"&gt;-b&lt;/span&gt; kafka_broker_address &lt;span class="nt"&gt;-t&lt;/span&gt; my_topic &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; ssl.ca.location&lt;span class="o"&gt;=&lt;/span&gt;/path/to/ca.crt &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; ssl.truststore.location&lt;span class="o"&gt;=&lt;/span&gt;/path/to/client.truststore &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; ssl.truststore.password&lt;span class="o"&gt;=&lt;/span&gt;my_truststore_password
  &lt;span class="nt"&gt;-X&lt;/span&gt; ssl.keystore.location&lt;span class="o"&gt;=&lt;/span&gt;/path/to/client.keystore &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-X&lt;/span&gt; ssl.keystore.password&lt;span class="o"&gt;=&lt;/span&gt;my_keystore_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the placeholders with your specific configurations and paths. kcat will handle the secure communication with SASL and SSL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supercharge Kafka with kcat and jq
&lt;/h2&gt;

&lt;p&gt;Now, let's take it up a notch! Combine kcat with &lt;strong&gt;jq&lt;/strong&gt;, a powerful JSON processor, to work with Kafka messages efficiently. Suppose you have JSON messages in your Kafka topic. You can consume, process, and display them using jq like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kcat &lt;span class="nt"&gt;-b&lt;/span&gt; kafka_broker_address &lt;span class="nt"&gt;-t&lt;/span&gt; my_json_topic &lt;span class="nt"&gt;-q&lt;/span&gt; | jq &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-q&lt;/code&gt; flag makes kcat output only the message payloads. We pipe this output to jq to pretty-print JSON messages.&lt;/p&gt;

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

&lt;p&gt;With kcat in your arsenal, you're well-equipped to conquer Kafka's intricacies. Whether you're debugging, monitoring, or building real-time data processing pipelines, kcat is your Swiss Army knife for Kafka tasks. Start exploring its capabilities, install kcat on your system, and embark on your Kafka journey with confidence. Happy streaming! 🌊🪄✨&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>programming</category>
      <category>beginners</category>
      <category>linux</category>
    </item>
    <item>
      <title>Mastering jq: A Quick Guide to get you started</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Tue, 12 Sep 2023 04:11:19 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/mastering-jq-a-quick-guide-to-get-you-started-4mm6</link>
      <guid>https://dev.to/sergiomarcial/mastering-jq-a-quick-guide-to-get-you-started-4mm6</guid>
      <description>&lt;p&gt;Are you tired of wrestling with messy JSON data in your daily work as a software engineer? Do you find yourself spending too much time parsing, filtering, and transforming JSON data to fit your needs? Look no further! In this article, we will explore jq, a versatile command-line tool designed to make working with JSON data a breeze. 🌪️&lt;/p&gt;

&lt;p&gt;Let's dive in! 💪&lt;/p&gt;

&lt;h2&gt;
  
  
  What is jq?
&lt;/h2&gt;

&lt;p&gt;Before we jump into installation and usage, let's briefly introduce jq. In a nutshell, &lt;strong&gt;jq&lt;/strong&gt; is a lightweight and powerful command-line tool that allows you to manipulate and transform JSON data effortlessly. It provides a range of functions for querying, filtering, formatting, and modifying JSON documents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Unix and macOS
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Option 1: Package Manager (Recommended)
&lt;/h4&gt;

&lt;p&gt;If you're using a Unix-based system like Linux or macOS, the easiest way to install jq is through a package manager. For example, on systems with APT (Debian/Ubuntu), you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On systems with YUM (CentOS/Red Hat), you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For macOS users with Homebrew, it's as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Option 2: Manual Installation
&lt;/h4&gt;

&lt;p&gt;If you prefer to install jq manually, visit the official website (&lt;a href="https://stedolan.github.io/jq/download/"&gt;https://stedolan.github.io/jq/download/&lt;/a&gt;) and download the appropriate binary for your system. Then, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download the binary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make it executable:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Move it to a directory in your PATH (e.g., &lt;code&gt;/usr/local/bin/&lt;/code&gt;):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mv &lt;/span&gt;jq /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;

&lt;p&gt;Windows users can also enjoy the benefits of jq by downloading the executable from the official website (&lt;a href="https://stedolan.github.io/jq/download/"&gt;https://stedolan.github.io/jq/download/&lt;/a&gt;) and following these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download the Windows binary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rename the binary to &lt;code&gt;jq.exe&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the directory containing &lt;code&gt;jq.exe&lt;/code&gt; to your system's PATH.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that you've successfully installed jq, let's explore its capabilities with some practical examples! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Querying JSON Data
&lt;/h3&gt;

&lt;p&gt;Let's start with a simple JSON document as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"New York"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose you want to extract the "name" field. You can use jq like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "John Doe", "age": 30, "city": "New York"}'&lt;/span&gt; | jq &lt;span class="s1"&gt;'.name'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Filtering JSON Arrays
&lt;/h3&gt;

&lt;p&gt;jq is also great for working with JSON arrays. Suppose you have an array of products:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Laptop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Smartphone"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;599&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tablet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;349&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To filter this array to only include products with a price less than $500, you can use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'[{"name": "Laptop", "price": 999}, {"name": "Smartphone", "price": 599}, {"name": "Tablet", "price": 349}]'&lt;/span&gt; | jq &lt;span class="s1"&gt;'.[] | select(.price &amp;lt; 500)'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tablet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;349&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Formatting JSON Output
&lt;/h3&gt;

&lt;p&gt;jq can also help you format JSON output for better readability. To pretty-print JSON, simply use the &lt;code&gt;-r&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "John Doe", "age": 30, "city": "New York"}'&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be nicely formatted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"New York"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advanced Usage with curl
&lt;/h2&gt;

&lt;p&gt;As software engineers, we often need to interact with APIs that return JSON data. jq is an invaluable tool in these scenarios, allowing us to filter and process API responses seamlessly. Let's explore some examples using the &lt;code&gt;curl&lt;/code&gt; command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1: Retrieve and Filter GitHub Repositories
&lt;/h3&gt;

&lt;p&gt;Suppose you want to fetch a list of your GitHub repositories and extract only their names and star counts. You can achieve this with jq and &lt;code&gt;curl&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.github.com/users/your_username/repos | jq &lt;span class="s1"&gt;'.[] | {name: .name, stars: .stargazers_count}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command sends a GET request to the GitHub API, pipes the JSON response through jq, and extracts the desired fields. The result will be a list of objects containing repository names and star counts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 2: Fetch Weather Data
&lt;/h3&gt;

&lt;p&gt;Let's say you want to retrieve weather data from an API and display only the temperature. Here's how you can do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.openweathermap.org/data/2.5/weather?q&lt;span class="o"&gt;=&lt;/span&gt;your_city&amp;amp;appid&lt;span class="o"&gt;=&lt;/span&gt;your_api_key | jq &lt;span class="s1"&gt;'.main.temp'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;your_city&lt;/code&gt; with the desired location and &lt;code&gt;your_api_key&lt;/code&gt; with your API key. This command fetches weather data, extracts the temperature, and presents it neatly.&lt;/p&gt;

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

&lt;p&gt;jq is a powerful tool that every software engineer should have in their toolkit. With its simple yet expressive syntax, you can effortlessly manipulate JSON data, whether it's in a file, a command output, or an API response. By mastering jq, you'll boost your productivity and make JSON wrangling a breeze. 🌐&lt;/p&gt;

&lt;p&gt;So go ahead, install jq on your system, and start unleashing its potential today. Happy coding! 🎉&lt;/p&gt;

</description>
      <category>unix</category>
      <category>beginners</category>
      <category>linux</category>
      <category>shell</category>
    </item>
    <item>
      <title>🚀🧪Unlocking the Power of Approval Testing 🔥💻</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Mon, 11 Sep 2023 13:05:31 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/unlocking-the-power-of-approval-testing-a-comprehensive-guide-for-software-engineers-3o6f</link>
      <guid>https://dev.to/sergiomarcial/unlocking-the-power-of-approval-testing-a-comprehensive-guide-for-software-engineers-3o6f</guid>
      <description>&lt;p&gt;Testing is the backbone of software development, ensuring the reliability and quality of our code. But when it comes to testing complex and ever-evolving software, traditional methods often fall short. That's where Approval Testing steps in—a revolutionary (but not new) approach that simplifies complex scenarios, embraces change, and helps you write more robust software. In this guide, we'll dive into the world of Approval Testing, understanding its fundamentals, its niche in software engineering, and how it differs from other testing methodologies. With code examples in some languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What is Approval Testing?&lt;/li&gt;
&lt;li&gt;The Core Principles&lt;/li&gt;
&lt;li&gt;Practical Application&lt;/li&gt;
&lt;li&gt;The Niche Approval Testing Addresses&lt;/li&gt;
&lt;li&gt;Key Benefits&lt;/li&gt;
&lt;li&gt;Key Differences Between Approval Testing and Other Testing Methods&lt;/li&gt;
&lt;li&gt;Code Examples in Different Languages&lt;/li&gt;
&lt;li&gt;Real-World Use Cases&lt;/li&gt;
&lt;li&gt;Real-World Examples&lt;/li&gt;
&lt;li&gt;Choosing the Right Tool&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. What is Approval Testing?
&lt;/h3&gt;

&lt;p&gt;Approval Testing is a testing methodology that focuses on capturing the current output of a piece of code and then comparing it to a previously approved version. Instead of requiring developers to predict the exact output, Approval Testing encourages them to approve the current output as correct and uses it as a reference for future testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Core Principles
&lt;/h3&gt;

&lt;p&gt;To grasp the essence of Approval Testing, it's essential to understand its core principles:&lt;/p&gt;

&lt;p&gt;No Predictions: Unlike traditional unit tests that require developers to predict the exact output, Approval Testing captures and approves the current output. This makes it suitable for scenarios where predictions are challenging.&lt;/p&gt;

&lt;p&gt;Change Embrace: In agile development environments where change is constant, Approval Testing shines. It accommodates evolving codebases and minimizes the need for frequent test updates.&lt;/p&gt;

&lt;p&gt;Versatility: Approval Testing isn't limited to a specific type of output. It can be applied to databases, APIs, GUIs, and any scenario involving textual or binary output.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Practical Application
&lt;/h3&gt;

&lt;p&gt;Let's delve into a practical example to see how Approval Testing works in action. Suppose we have a function calculate_total_price that calculates the total price of items in a shopping cart:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_total_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;total_price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;'Total Price: $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;total_price&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Approval Testing, we capture the current output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;approvaltests.approvals&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt;

&lt;span class="n"&gt;cart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Item A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;10.99&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Item B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;7.50&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculate_total_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. The Niche Approval Testing Addresses
&lt;/h3&gt;

&lt;p&gt;Approval Testing is designed to tackle specific challenges encountered by software engineers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Complex Output&lt;/strong&gt;: In scenarios where the output is complex or includes non-deterministic elements (e.g., timestamps), predicting exact values for unit tests can be daunting. Approval Testing eliminates the need for such predictions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Evolving Codebases&lt;/strong&gt;: Agile development environments thrive on change. Frequent code updates can cause traditional unit tests to break. Approval Testing embraces evolving codebases and adapts seamlessly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Non-Visual Output&lt;/strong&gt;: Unlike some testing methods that are primarily visual, Approval Testing is versatile. It can be employed for databases, APIs, and any scenario where textual or binary output is involved.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Key Benefits
&lt;/h3&gt;

&lt;p&gt;Approval Testing offers several key benefits:&lt;/p&gt;

&lt;p&gt;Simplified Testing: Approval Testing simplifies complex testing scenarios, especially when predicting exact outputs is challenging.&lt;/p&gt;

&lt;p&gt;Adaptability: It adapts seamlessly to evolving codebases, reducing the need for frequent test updates.&lt;/p&gt;

&lt;p&gt;Accurate Documentation: The approved output serves as documentation, allowing developers to understand the expected behavior easily.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Key Differences Between Approval Testing and Other Testing Methods
&lt;/h3&gt;

&lt;p&gt;To appreciate Approval Testing fully, let's draw comparisons with other popular testing methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unit Testing&lt;/strong&gt;: Unit tests require developers to specify expected outcomes. Approval Testing, on the other hand, captures actual outcomes and uses them as references. This makes it especially effective for scenarios where predicting outcomes is challenging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integration Testing&lt;/strong&gt;: Integration tests focus on interactions between components. While Approval Testing is not a replacement for integration tests, it can complement them by validating non-deterministic behavior within the integration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Property-Based Testing&lt;/strong&gt;: Property-based testing generates a large number of inputs to test code. Approval Testing doesn't generate inputs; instead, it captures and verifies outputs. This makes it suitable for scenarios where you're concerned with the correctness of outputs rather than input generation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7. Code Examples in Different Languages
&lt;/h3&gt;

&lt;p&gt;Let's explore Approval Testing through practical code examples in three popular programming languages: Python, Java, and JavaScript.&lt;/p&gt;

&lt;h4&gt;
  
  
  Python Example:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;unittest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;approvaltests.approvals&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_numbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestAddition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_addition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;add_numbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Java Example:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.approvaltests.combinations.CombinationApprovals&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CombinationTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testCombination&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;CombinationApprovals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;verifyAllCombinations&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calculate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  JavaScript Example:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;verify&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;approvaltests&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;multiplyNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Multiplication Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;multiplyNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&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;h3&gt;
  
  
  8. Real-World Use Cases
&lt;/h3&gt;

&lt;p&gt;Approval Testing finds its application in a wide array of real-world scenarios. Some examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validating database migrations and ensuring schema compatibility.&lt;/li&gt;
&lt;li&gt;Testing APIs and confirming the correctness of responses.&lt;/li&gt;
&lt;li&gt;Verifying output in financial systems, where precision matters.&lt;/li&gt;
&lt;li&gt;Ensuring consistent behavior in game development, where randomness is a factor.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  9. Real-World Examples
&lt;/h3&gt;

&lt;p&gt;Approval Testing finds application in a wide range of real-world scenarios:&lt;/p&gt;

&lt;p&gt;Database Schema Validation: It ensures that database migrations maintain schema compatibility.&lt;/p&gt;

&lt;p&gt;API Testing: Approval Testing validates the correctness of API responses.&lt;/p&gt;

&lt;p&gt;Financial Systems: In financial systems where precision is crucial, Approval Testing guarantees accurate results.&lt;/p&gt;

&lt;p&gt;Game Development: It's used to ensure consistent behavior in games, especially when randomness is involved.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Choosing the Right Tool
&lt;/h3&gt;

&lt;p&gt;Selecting the right tool for Approval Testing is essential. Popular tools include ApprovalTests (for various languages), TextTest (for text-based approval), and others tailored to specific scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  11. Conclusion 💪
&lt;/h3&gt;

&lt;p&gt;Approval Testing is not just a testing methodology; it's a mindset shift. By embracing the power of Approval Testing, you can simplify testing scenarios, adapt to evolving codebases, and ensure the correctness of your software outputs. It's a versatile tool that can make your testing efforts more robust and resilient.&lt;/p&gt;

&lt;p&gt;As you embark on your testing journey, consider integrating Approval Testing into your testing suite. It's a valuable addition that can help you write better code, reduce bugs, and improve the overall quality of your software.&lt;/p&gt;

&lt;p&gt;Happy testing! 🚀🧪&lt;/p&gt;

</description>
      <category>testing</category>
      <category>approvaltesting</category>
      <category>coding</category>
      <category>qualityassurance</category>
    </item>
    <item>
      <title>🚀 Mastering Integration Testing in Rust with Testcontainers 🧪</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Wed, 06 Sep 2023 04:11:35 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/mastering-integration-testing-in-rust-with-testcontainers-3aml</link>
      <guid>https://dev.to/sergiomarcial/mastering-integration-testing-in-rust-with-testcontainers-3aml</guid>
      <description>&lt;p&gt;In the vast world of software engineering, testing plays an indispensable role in ensuring the reliability, stability, and performance of our applications. Among various testing types, integration testing stands out as a critical phase, verifying that different components of your system interact seamlessly. However, integration testing, especially when dealing with external dependencies like databases and message brokers, can be complex.&lt;/p&gt;

&lt;p&gt;In this article, we will embark on a journey to master integration testing in Rust using a powerful tool known as Testcontainers. This tool simplifies the process of spinning up Docker containers for your integration tests, allowing you to test against real external systems in a clean and isolated environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Getting Started: Installing Rust
&lt;/h2&gt;

&lt;p&gt;Before diving into integration testing with Testcontainers, let's ensure that your Rust development environment is set up correctly. Rust, known as "the language of systems," provides a robust foundation for building fast and reliable software.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Installing Rust on Windows&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Visit the official Rust website &lt;a href="https://rustup.rs/"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the Windows installer and run it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow the on-screen instructions to complete the installation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open Command Prompt or PowerShell and run the following command to verify the installation:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   rustc &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command should display the Rust version, confirming a successful installation.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Installing Rust on macOS&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open Terminal, which comes pre-installed on macOS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install Rust using Homebrew, a popular package manager for macOS, with this command:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   brew &lt;span class="nb"&gt;install &lt;/span&gt;rust
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;After the installation completes, verify Rust's installation by running:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   rustc &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the Rust version displayed in the terminal, confirming that Rust is now installed on your macOS system.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗️ Setting Up the Integration Testing Project
&lt;/h2&gt;

&lt;p&gt;Assuming you have a typical Rust project structure, which includes &lt;code&gt;src/main.rs&lt;/code&gt; for your application code and &lt;code&gt;tests/integration_test.rs&lt;/code&gt; for integration tests, we can proceed to set up our integration testing project.&lt;/p&gt;

&lt;p&gt;To get started, add the Testcontainers dependency to your &lt;code&gt;Cargo.toml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ cargo add testcontainers     
    Updating crates.io index
      Adding testcontainers v0.14.0 to dependencies.
             Features:
             - async-trait
             - bollard
             - conquer-once
             - experimental
             - signal-hook
             - tokio
             - watchdog
    Updating crates.io index
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;testcontainers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.14.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we're ready to dive into the specifics of integration testing with Testcontainers, using PostgreSQL as example.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌐 Setting Up the Integration Testing Project
&lt;/h3&gt;

&lt;p&gt;Assuming you have a typical Rust project structure, which looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my_rust_project/
|-- src/
|   |-- main.rs
|-- tests/
|   |-- integration_test.rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;src/main.rs&lt;/code&gt; contains your application code.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tests/integration_test.rs&lt;/code&gt; is where we'll write our integration tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🐳 Leveraging Testcontainers for Rust
&lt;/h2&gt;

&lt;p&gt;Testcontainers provides an intuitive way to manage Docker containers for your integration tests. Let's explore how to use it effectively in Rust.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Testing PostgreSQL Integration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;integration_test.rs&lt;/code&gt; file, you can set up and test a PostgreSQL container with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="nd"&gt;#[test]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;it_works&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;docker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;clients&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Cli&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Define a PostgreSQL container image&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;postgres_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Postgres&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;pg_container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="nf"&gt;.run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;postgres_image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;pg_container&lt;/span&gt;&lt;span class="nf"&gt;.start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nn"&gt;WaitFor&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Get the PostgreSQL port&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;pg_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pg_container&lt;/span&gt;&lt;span class="nf"&gt;.get_host_port_ipv4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5432&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Define the connection to the Postgress client&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&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;connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;tokio_postgres&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.host&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.port&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pg_port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.dbname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;tokio_postgres&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NoTls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Spawn connection&lt;/span&gt;
    &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;eprintln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connection error: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;
        &lt;span class="nf"&gt;.batch_execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"
        CREATE TABLE IF NOT EXISTS app_user (
            id              SERIAL PRIMARY KEY,
            username        VARCHAR UNIQUE NOT NULL,
            password        VARCHAR NOT NULL,
            email           VARCHAR UNIQUE NOT NULL
            )
    "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;
        &lt;span class="nf"&gt;.execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"INSERT INTO app_user (username, password, email) VALUES ($1, $2, $3)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="s"&gt;"user1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="s"&gt;"mypass"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="s"&gt;"user@test.com"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;
        &lt;span class="nf"&gt;.query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT id, username, password, email FROM app_user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.into_iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;User&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="nf"&gt;.first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="py"&gt;.username&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mypass"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="py"&gt;.password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user@test.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="py"&gt;.email&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;In this test, we:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Docker client.&lt;/li&gt;
&lt;li&gt;Define a PostgreSQL container image.&lt;/li&gt;
&lt;li&gt;Run the PostgreSQL container, expose its ports, and set  the user and password.&lt;/li&gt;
&lt;li&gt;Retrieve the PostgreSQL port and add it to the connection URL.&lt;/li&gt;
&lt;li&gt;Connect to the PostgresSQL DB using tokio_postgres&lt;/li&gt;
&lt;li&gt;We need to spawn a new connection&lt;/li&gt;
&lt;li&gt;Write your database integration test code using the &lt;code&gt;client&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🏃 Running the Integration Tests
&lt;/h2&gt;

&lt;p&gt;To run your integration tests, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ cargo &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--test&lt;/span&gt; integration_test
   Compiling testcontainer_example v0.1.0 &lt;span class="o"&gt;(&lt;/span&gt;/Users/sergiomarcial/Documents/Confidential/repositories/github/testcontainers-rust&lt;span class="o"&gt;)&lt;/span&gt;
    Finished &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;unoptimized + debuginfo] target&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in &lt;/span&gt;1.76s
     Running tests/integration_test.rs &lt;span class="o"&gt;(&lt;/span&gt;target/debug/deps/integration_test-ff1cb10ac2b24a1b&lt;span class="o"&gt;)&lt;/span&gt;

running 1 &lt;span class="nb"&gt;test
test &lt;/span&gt;it_works ... ok

&lt;span class="nb"&gt;test &lt;/span&gt;result: ok. 1 passed&lt;span class="p"&gt;;&lt;/span&gt; 0 failed&lt;span class="p"&gt;;&lt;/span&gt; 0 ignored&lt;span class="p"&gt;;&lt;/span&gt; 0 measured&lt;span class="p"&gt;;&lt;/span&gt; 0 filtered out&lt;span class="p"&gt;;&lt;/span&gt; finished &lt;span class="k"&gt;in &lt;/span&gt;2.11s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will execute all the tests in your &lt;code&gt;integration_test.rs&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code example
&lt;/h2&gt;

&lt;p&gt;For a complete example using &lt;code&gt;Rust&lt;/code&gt; and &lt;code&gt;Postgres&lt;/code&gt; testcontainers, check out my &lt;a href="https://github.com/sergiommarcial/testcontainers-rust"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 Exploring Alternatives and Considerations
&lt;/h2&gt;

&lt;p&gt;While Testcontainers simplifies integration testing, it's crucial to explore alternative approaches like mocking or using Docker Compose for more complex setups. Choose the approach that best aligns with your project's requirements.&lt;/p&gt;

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

&lt;p&gt;Integration testing in Rust can be made effortless and efficient with Testcontainers. You've learned how to set up your project, install dependencies, and write integration tests for PostgreSQL. This newfound knowledge empowers you to ensure that your Rust applications seamlessly interact with external dependencies, bolstering the robustness and reliability of your software. Happy testing!&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.rs/testcontainers/0.10.0/testcontainers/"&gt;Testcontainers Rust Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rust-lang.org/"&gt;Rust Programming Language&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Integration testing has never been this enjoyable! 🐳🦀&lt;/p&gt;

</description>
      <category>rust</category>
      <category>testing</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>🚀 Effortless Integration Tests with Testcontainers in Golang 🧪</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Mon, 04 Sep 2023 16:56:09 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/effortless-integration-testing-with-testcontainers-in-golang-44bp</link>
      <guid>https://dev.to/sergiomarcial/effortless-integration-testing-with-testcontainers-in-golang-44bp</guid>
      <description>&lt;p&gt;Testing is a vital part of software development, ensuring that your applications run as expected in real-world scenarios. However, writing effective integration and functional tests can be challenging, especially when dealing with databases, message brokers, and external services. In this article, we'll explore how to harness the power of Testcontainers to simplify testing in Golang. Whether you're a beginner or an experienced developer, you'll gain valuable insights into writing robust integration and functional tests using Testcontainers.&lt;/p&gt;

&lt;h3&gt;
  
  
  🏁 Setting Up Your Development Environment
&lt;/h3&gt;

&lt;p&gt;Before we dive into code examples, let's ensure your development environment is ready. We'll cover installing Golang on both Windows and macOS.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Installing Golang on Windows&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Download the Windows installer from the &lt;a href="https://golang.org/dl/"&gt;official Golang website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Run the installer and follow the on-screen instructions.&lt;/li&gt;
&lt;li&gt;Open Command Prompt and run &lt;code&gt;go version&lt;/code&gt; to verify the installation.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Installing Golang on macOS&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;There are 2 options to install Golang on macOs&lt;/p&gt;

&lt;p&gt;Follow wthe official documentation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the macOS installer from the &lt;a href="https://golang.org/dl/"&gt;official Golang website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Open the downloaded package and follow the installation instructions.&lt;/li&gt;
&lt;li&gt;Open Terminal and run &lt;code&gt;go version&lt;/code&gt; to verify the installation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Or use homebrew&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📦 Installing Testcontainers Go Package
&lt;/h3&gt;

&lt;p&gt;Now, let's install the Testcontainers Go package. Open your terminal/command prompt and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get github.com/testcontainers/testcontainers-go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🌐 Setting Up the Project
&lt;/h3&gt;

&lt;p&gt;Let's assume we're working on a Golang application that interacts with a PostgreSQL database and Kafka message broker. We want to write integration and functional tests for these components.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Project Structure&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Here's a typical project structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;myapp/
|-- main.go
|-- database/
|   |-- database.go
|   |-- database_test.go
|-- messaging/
|   |-- kafka.go
|   |-- kafka_test.go
|-- test/
|   |-- integration_test.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;main.go&lt;/code&gt; contains your application code.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;database/database.go&lt;/code&gt; handles database interactions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;database/database_test.go&lt;/code&gt; handles database unit testing (We are not interested there, for this article).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;messaging/kafka.go&lt;/code&gt; manages Kafka communication, creating kafka consumers and/or producer.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;messaging/kafka_test.go&lt;/code&gt; handles kafka unit testing (We are not interested there, for this article).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test/&lt;/code&gt; is where we'll write our integration tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📋 Writing the Test
&lt;/h3&gt;

&lt;p&gt;Let's create an integration test for the PostgreSQL database. In &lt;code&gt;integration_test.go&lt;/code&gt;, add the following code:&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;package&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"database/sql"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/testcontainers/testcontainers-go"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/testcontainers/testcontainers-go/wait"&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"github.com/lib/pq"&lt;/span&gt; &lt;span class="c"&gt;// Import the PostgreSQL driver&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestPostgreSQLIntegration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Define a PostgreSQL container&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;testcontainers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContainerRequest&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="s"&gt;"postgres:latest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ExposedPorts&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"5432/tcp"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;WaitingFor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"database system is ready to accept connections"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Create the container&lt;/span&gt;
    &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;testcontainers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenericContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;testcontainers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenericContainerRequest&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ContainerRequest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Started&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;          &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Terminate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Get the PostgreSQL port&lt;/span&gt;
    &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;dsn&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"user=postgres password=postgres dbname=postgres sslmode=disable host="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" port="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;

    &lt;span class="c"&gt;// Connect to the database&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dsn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Your database test code here&lt;/span&gt;

    &lt;span class="c"&gt;// Clean up&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Terminate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&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;In this test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We define a PostgreSQL container using Testcontainers.&lt;/li&gt;
&lt;li&gt;We start the container and retrieve the host and port for database connection.&lt;/li&gt;
&lt;li&gt;We connect to the database and perform our test operations.&lt;/li&gt;
&lt;li&gt;Finally, we clean up by terminating the container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that each test runs in an isolated PostgreSQL container.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 Testing Kafka
&lt;/h3&gt;

&lt;p&gt;Similarly, you can create integration tests for Kafka. In &lt;code&gt;integration_test.go&lt;/code&gt;, add the following code:&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;package&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/testcontainers/testcontainers-go"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/testcontainers/testcontainers-go/wait"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestKafkaIntegration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Define a Kafka container&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;testcontainers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContainerRequest&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="s"&gt;"confluentinc/cp-kafka:latest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ExposedPorts&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"9092/tcp"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;WaitingFor&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"listeners started on advertised listener"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Create the container&lt;/span&gt;
    &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;testcontainers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenericContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;testcontainers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenericContainerRequest&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ContainerRequest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Started&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;          &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Terminate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Your Kafka test code here&lt;/span&gt;

    &lt;span class="c"&gt;// Clean up&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Terminate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&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;h3&gt;
  
  
  🔄 Running the Tests
&lt;/h3&gt;

&lt;p&gt;You can run your tests using the &lt;code&gt;go test&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;test&lt;/span&gt; ./test/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a complete example using &lt;code&gt;Golang&lt;/code&gt; and &lt;code&gt;Postgres&lt;/code&gt; testcontainers, check out this &lt;a href="https://github.com/sergiommarcial/testcontainers-golang"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔄 Alternatives and Comparisons
&lt;/h3&gt;

&lt;p&gt;While Testcontainers is a powerful tool, it's essential to know about alternatives and when to use them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mocking&lt;/strong&gt;: For unit tests, you might opt for mocking libraries like &lt;code&gt;github.com/stretchr/testify/mock&lt;/code&gt; to simulate database and Kafka interactions. This approach is suitable for unit tests but lacks the realism of actual containers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Docker Compose&lt;/strong&gt;: If you prefer using Docker Compose for your tests, it provides more flexibility but requires additional setup and maintenance.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  💡 Conclusion
&lt;/h3&gt;

&lt;p&gt;Testcontainers in Golang opens the door to efficient integration and functional testing. It allows you to create and manage containers effortlessly, ensuring that your tests reflect real-world scenarios. With Testcontainers, you can write robust, reliable tests for your Golang applications.&lt;/p&gt;

&lt;p&gt;Happy testing! 🚀🐳&lt;/p&gt;

&lt;h3&gt;
  
  
  📚 Further Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/testcontainers/testcontainers-go"&gt;Testcontainers Go Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>testing</category>
      <category>testcontainers</category>
      <category>integrationtesting</category>
    </item>
    <item>
      <title>🚀 Level up Your Testing Game: Harness the Power of Testcontainers with Java and Spring Boot 🧪</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Mon, 04 Sep 2023 05:27:21 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/level-up-your-testing-game-harness-the-power-of-testcontainers-with-java-and-spring-boot-3pib</link>
      <guid>https://dev.to/sergiomarcial/level-up-your-testing-game-harness-the-power-of-testcontainers-with-java-and-spring-boot-3pib</guid>
      <description>&lt;p&gt;Introduction&lt;/p&gt;

&lt;p&gt;Testing is an integral part of software development. It ensures that our applications work as expected and guards against unexpected regressions. As engineers, it becomes crucial for us to explore reliable and efficient testing practices early in our careers. In this article, we will dive into integration and functional testing by implementing Testcontainers with Java and Spring Boot, unleashing the power of containerization in our testing workflow. Let's get started! 🎉&lt;/p&gt;

&lt;p&gt;What are Integration and Functional Testing?&lt;/p&gt;

&lt;p&gt;Integration testing involves validating the interaction between different components of an application, ensuring they work cohesively. On the other hand, functional testing verifies the functionality of individual units within the application. Both types of tests complement each other, providing comprehensive coverage to prevent potential bugs or issues in our software.&lt;/p&gt;

&lt;p&gt;Introducing Testcontainers 🐳&lt;/p&gt;

&lt;p&gt;Testcontainers is an open-source Java library that enables developers to seamlessly create, manage, and orchestrate Docker containers for isolated testing environments. By integrating Testcontainers with our testing framework, we can easily provision containers, such as databases or message brokers, while writing tests, ensuring accurate and efficient integration and functional testing.&lt;/p&gt;

&lt;p&gt;Setting Up Testcontainers with Maven and Gradle 📦&lt;/p&gt;

&lt;p&gt;To leverage the power of Testcontainers, we need to add the necessary dependencies in our build tool setups.&lt;/p&gt;

&lt;p&gt;Maven Example 🧩&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;pom.xml&lt;/code&gt; file, include the following dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.testcontainers&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;testcontainers&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.19.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.testcontainers&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit-jupiter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.19.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gradle Example 🧪&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;build.gradle&lt;/code&gt; file, add the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="s1"&gt;'org.testcontainers:testcontainers:1.19.0'&lt;/span&gt;
&lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="s1"&gt;'org.testcontainers:junit-jupiter:1.19.0'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your &lt;code&gt;build.gradle.kts&lt;/code&gt; file, add the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;testImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.testcontainers:testcontainers:1.19.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;testImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.testcontainers:junit-jupiter:1.19.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these dependencies in place, we are ready to explore the magic of Testcontainers! ✨&lt;/p&gt;

&lt;p&gt;Using Testcontainers with Spring Boot Example 💻&lt;/p&gt;

&lt;p&gt;Let's dive into a practical example of how to leverage Testcontainers with Spring Boot framework for integration testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.test.context.SpringBootTest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.test.context.TestPropertySource&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.testcontainers.containers.PostgreSQLContainer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.testcontainers.junit.jupiter.Container&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.testcontainers.junit.jupiter.Testcontainers&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Testcontainers&lt;/span&gt;
&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="nd"&gt;@TestPropertySource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"classpath:application-test.yaml"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyIntegrationTests&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Container&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;PostgreSQLContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;postgresContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PostgreSQLContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres:latest"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Your tests go here&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we have annotated our test class with &lt;code&gt;@Testcontainers&lt;/code&gt;, defining it as a test container-aware class. We also added &lt;code&gt;@SpringBootTest&lt;/code&gt; to enable Spring Boot-specific configuration and &lt;code&gt;@TestPropertySource&lt;/code&gt; to load specific test properties.&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;@Container&lt;/code&gt; annotation, we declare an instance of the PostgreSQL container. Testcontainers automatically starts and stops the container for each test execution. You can easily configure other containers such as MySQL or Redis, depending on your requirements.&lt;/p&gt;

&lt;p&gt;You can also include the spring boot dependency&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-testcontainers&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.1.3&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gradle Example 🧪&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;build.gradle&lt;/code&gt; file, add the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot:spring-boot-testcontainers:3.1.3'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your &lt;code&gt;build.gradle.kts&lt;/code&gt; file, add the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;testImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.springframework.boot:spring-boot-testcontainers:3.1.3"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using Testcontainers with Spring Boot Example containers as beans 💻&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.test.context.TestConfiguration&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.testcontainers.service.connection.ServiceConnection&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Bean&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.testcontainers.containers.PostgreSQLContainer&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.testcontainers.containers.wait.strategy.Wait&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.testcontainers.utility.DockerImageName&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.time.Duration&lt;/span&gt;

&lt;span class="nd"&gt;@TestConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proxyBeanMethods&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="nd"&gt;@ServiceConnection&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;postgresSqlContainer&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;PostgreSQLContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="nc"&gt;PostgreSQLContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;DockerImageName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres:latest"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;also&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setWaitStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nc"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defaultWaitStrategy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withStartupTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ofSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;this&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;This will allows to re use the container across multiple tests without the need to restart.&lt;/p&gt;

&lt;p&gt;For a complete example using &lt;code&gt;Kotlin&lt;/code&gt;, check out this &lt;a href="https://github.com/sergiommarcial/testcontainers-example"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Advantages and Alternatives 😎&lt;/p&gt;

&lt;p&gt;Testcontainers provide numerous benefits for integration and functional testing:&lt;/p&gt;

&lt;p&gt;✅ Isolation: Testcontainers create isolated environments for testing, avoiding interference with external dependencies or shared environments.&lt;/p&gt;

&lt;p&gt;✅ Reproducibility: Each test run starts with a clean environment, eliminating any issues caused by conflicting or stale state.&lt;/p&gt;

&lt;p&gt;✅ Ease of Use: Testcontainers seamlessly integrates with popular testing frameworks and reduces the complexity of setting up separate testing environments.&lt;/p&gt;

&lt;p&gt;While Testcontainers is an excellent choice for testing, there are alternative tools available too. Some significant alternatives include Docker Compose, Mountebank, and WireMock. Each has its unique advantages, so you should choose based on your specific needs.&lt;/p&gt;

&lt;p&gt;Conclusion 🔍&lt;/p&gt;

&lt;p&gt;By incorporating Testcontainers in your testing repertoire, you can achieve efficient and robust integration and functional testing with ease. Its seamless integration with Java and Spring Boot makes it a perfect choice for leveraging containerization in your test suites. Start your journey with Testcontainers today, and level up your testing game! 🚀&lt;/p&gt;

&lt;p&gt;Remember, investing time in learning reliable testing practices early in your career will pay dividends in the long run. Happy testing! 🧪&lt;/p&gt;

</description>
      <category>testing</category>
      <category>java</category>
      <category>springboot</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Breaking Up with @Autowired: Why Dependency Injection with Spring Boot Needs a Makeover! 💔</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Sun, 03 Sep 2023 23:10:28 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/breaking-up-with-autowired-why-dependency-injection-with-spring-boot-needs-a-makeover-39c5</link>
      <guid>https://dev.to/sergiomarcial/breaking-up-with-autowired-why-dependency-injection-with-spring-boot-needs-a-makeover-39c5</guid>
      <description>&lt;p&gt;Introduction:&lt;br&gt;
🎶 Love hurts, but sometimes love smokes your codebase! 🎶 let's talk about why the beloved @Autowired annotation in Spring Boot might not be the best match for your dependency injection needs. In this article, we'll explore the downsides of using @Autowired, discuss its impact on your codebase, and present alternative strategies to keep your codebase clean and healthy. Let's dive in! 🏊&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;😕 What's Wrong with @Autowired?&lt;br&gt;
First things first! The @Autowired annotation might initially seem like a match made in heaven, promising effortless dependency injection in your Spring Boot projects. However, relying excessively on @Autowired can lead to several issues, turning it into a coding smell. Let's break them down:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;⛈️ Tight Coupling Alert!&lt;br&gt;
One major drawback of @Autowired is that it tightly couples your components, creating a web of dependencies that are difficult to trace and maintain (not that other forms of dependency injection not, they are just easier to identify). As your codebase grows, determining where exactly a dependency is injected becomes a daunting task. Take the following example:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here, the ServiceA is directly dependent on the ServiceB, severely limiting the flexibility of your code. Changes to the ServiceB or adding alternative implementations can potentially lead to cascading changes throughout your codebase. 😱&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;🙊 Hidden Dependencies
When utilizing @Autowired, you might encounter instances where dependencies remain unclear or hidden. This creates a veil of uncertainty, making it harder for developers to understand the internal workings and requirements of components they are interacting with. Consider this example:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShoppingCartService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;PaymentService&lt;/span&gt; &lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Without explicitly declaring the requirement for a PaymentService in the constructor or through method parameters, new developers ramping up in your code might struggle to grasp the essential dependencies of the ShoppingCartService or miss them completely. 👀&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;🔒 Testing becomes a Nightmare
Writing test cases becomes increasingly complex when using @Autowired extensively. In order to effectively test a single component, you often end up dragging in multiple dependencies and configuring an elaborate setup. This makes test cases fragile and difficult to maintain. Take a look at this example:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CustomerServiceTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;CustomerService&lt;/span&gt; &lt;span class="n"&gt;customerService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="n"&gt;orderService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;PaymentService&lt;/span&gt; &lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this scenario, testing the CustomerService becomes tedious due to the cascading dependencies mocking required for the successful execution of tests. 😓&lt;/p&gt;
&lt;h2&gt;
  
  
  🛠️ A Clean &amp;amp; Healthy Alternative:
&lt;/h2&gt;

&lt;p&gt;Constructor Injection&lt;/p&gt;

&lt;p&gt;So, how can we overcome these challenges? 👉 Constructor Injection to the rescue! Constructor Injection promotes explicit declaration of dependencies and allows for clearer code comprehension. Let's see how the refactored examples look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServiceA&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ServiceA&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ServiceB&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;serviceB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceB&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShoppingCartService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;PaymentService&lt;/span&gt; &lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ShoppingCartService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentService&lt;/span&gt; &lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;paymentService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using constructor injection, we eliminate surprises and make dependencies explicit, leading to cleaner and more maintainable code. 🧹&lt;/p&gt;

&lt;p&gt;Conclusion:&lt;br&gt;
In this article, we mentioned some of the downsides of relying excessively on Spring Boot's @Autowired annotation for dependency injection. We explored the challenges it poses, such as tight coupling, hidden dependencies, and testing complexities. Fortunately, we present an elegant solution - constructor injection. Embrace constructor injection, and you'll foster codebases that are clean, comprehensible, and hassle-free to test! 🎉&lt;/p&gt;

&lt;p&gt;Remember, while it's okay to have a fling with @Autowired early on in your coding adventures, it's crucial to break up after the honeymoon phase ends to ensure a long-lasting, healthy relationship with your codebase. Happy coding! 💻🚀&lt;/p&gt;

</description>
      <category>springboot</category>
      <category>dependencyinjection</category>
      <category>coding</category>
      <category>java</category>
    </item>
    <item>
      <title>Comparing Ktor and Micronaut: Kotlin-Powered Application Servers 🔥💻</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Mon, 28 Aug 2023 05:05:09 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/comparing-ktor-and-micronaut-kotlin-powered-application-servers-5gp1</link>
      <guid>https://dev.to/sergiomarcial/comparing-ktor-and-micronaut-kotlin-powered-application-servers-5gp1</guid>
      <description>&lt;p&gt;👋 Hey there! Are you ready to explore the exciting world of Kotlin-powered application servers? Well, you're in for a treat today, as we dive into a head-to-head comparison between two popular frameworks - Ktor and Micronaut. 🚀&lt;/p&gt;

&lt;p&gt;📌 Introduction:&lt;br&gt;
Kotlin has become the go-to language for modern Android app development, thanks to its conciseness, expressiveness, and safety features. But did you know that Kotlin is also a top choice for creating server-side applications? Both Ktor and Micronaut leverage the power of Kotlin to provide developers with efficient and feature-rich application servers. 🌐&lt;/p&gt;

&lt;p&gt;So, let's embark on this comparison journey and discover which framework suits your project requirements the best! Let's begin with a brief overview of both frameworks.&lt;/p&gt;

&lt;p&gt;🔍 Ktor:&lt;br&gt;
Ktor is a lightweight web framework built by JetBrains specifically for Kotlin developers. It harnesses Kotlin's DSL capabilities to offer flexibility, simplicity, and extensibility for creating robust and scalable server-side applications. 😎&lt;/p&gt;

&lt;p&gt;Here's a code snippet that showcases the simplicity and elegance of Ktor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.ktor.application.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.ktor.routing.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.ktor.server.engine.embeddedServer&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.ktor.server.netty.Netty&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;module&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;routing&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respondText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, Ktor!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;embeddedServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Netty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;module&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wait&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&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;🔍 Micronaut:&lt;br&gt;
Micronaut, on the other hand, is a modern and lightweight framework designed for building microservices and serverless applications. It provides dependency injection, AOP, and other advanced features out of the box to boost developer productivity. 🤩&lt;/p&gt;

&lt;p&gt;Behold a simple Micronaut example filled with Micronaut's magic ✨:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.micronaut.http.annotation.Controller&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.micronaut.http.annotation.Get&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.micronaut.http.client.annotation.Client&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.micronaut.http.client.annotation.Client&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.micronaut.runtime.Micronaut&lt;/span&gt;

&lt;span class="nd"&gt;@Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/hello"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HelloController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello, Micronaut!"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Micronaut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HelloController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&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;📊 Comparison:&lt;br&gt;
Now that we've seen the opening acts from both Ktor and Micronaut let's dive into the various aspects that may influence your decision:&lt;/p&gt;

&lt;p&gt;💨 Performance:&lt;br&gt;
When it comes to raw performance, both frameworks shine. However, Ktor gains an edge due to its lightweight nature and minimal overhead.&lt;/p&gt;

&lt;p&gt;📐 Architecture:&lt;br&gt;
Micronaut embraces a more opinionated approach with convention-over-configuration, making it an excellent choice for rapid development. Ktor, on the other hand, allows developers to have full control over their application's architecture and design.&lt;/p&gt;

&lt;p&gt;🔌 Integration:&lt;br&gt;
Micronaut's extensive dependency injection capabilities make it seamless to integrate with existing frameworks and libraries. While Ktor offers decent integration possibilities, it is more suitable for small to mid-sized projects.&lt;/p&gt;

&lt;p&gt;🔧 Tooling &amp;amp; Community Support:&lt;br&gt;
Both frameworks have an active and growing community with reliable documentation and excellent tooling support.&lt;/p&gt;

&lt;p&gt;🏁 Conclusion:&lt;br&gt;
Ultimately, selecting between Ktor and Micronaut depends on the specific needs of your project. If you prioritize simplicity and control, Ktor may be ideal for you. On the other hand, if you aim for rapid development and seamless integrations, Micronaut should be your go-to. 💡&lt;/p&gt;

&lt;p&gt;Whichever framework you choose, you can unleash the power of Kotlin to build high-performance and scalable server-side applications. 🚀&lt;/p&gt;

&lt;p&gt;And that's a wrap! We hope this comparison provided clarity for your next venture into Kotlin-powered application servers. Happy coding, and may the Kotlin force be with you! 🌟✨&lt;/p&gt;

&lt;p&gt;Got any questions or experiences to share? Drop a comment below and let's discuss! 👇&lt;/p&gt;

&lt;p&gt;Until next time, happy coding! 😄&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>webdev</category>
      <category>serversideframeworks</category>
      <category>ktorvsmicronaut</category>
    </item>
    <item>
      <title>📢 Strong Consistency: The Backbone of Reliable Data 💪</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Mon, 28 Aug 2023 05:00:38 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/strong-consistency-the-backbone-of-reliable-data-3o82</link>
      <guid>https://dev.to/sergiomarcial/strong-consistency-the-backbone-of-reliable-data-3o82</guid>
      <description>&lt;p&gt;Do you ever wonder how applications handle data updates and ensure they remain consistent across various systems? As a beginner engineer, understanding strong consistency is essential for building reliable and robust software. Let's dive into what strong consistency is, why it's crucial, real-world applications, and when it's discouraged. 😎&lt;/p&gt;

&lt;p&gt;🔍 What is Strong Consistency?&lt;br&gt;
Strong consistency is a property of distributed systems, ensuring that each read operation receives the most recent write operation's result. In simpler terms, it guarantees that every client or node accessing data sees the same view of the data at any given time. This approach provides clarity, predictability, and maintains data integrity across the system.&lt;/p&gt;

&lt;p&gt;🏆 Why is Strong Consistency Important?&lt;br&gt;
Imagine a banking application that allows simultaneous transfers from the same account to multiple destinations. Without strong consistency, different nodes could read different values, leading to discrepancies or even financial losses. Strong consistency solves this problem by making sure that all transactions reflect the most recent updates, preventing conflicts and preserving data integrity. It brings order to the chaos of concurrent modifications! 🎉&lt;/p&gt;

&lt;p&gt;🌎 Real-World Applications:&lt;br&gt;
Strong consistency finds application in numerous real-world scenarios. Let's explore a couple of them with examples and code snippets.&lt;/p&gt;

&lt;p&gt;1️⃣ Shopping Cart Checkout:&lt;br&gt;
Consider an e-commerce platform with thousands of users simultaneously adding items to their shopping carts. By employing strong consistency, each user will always see the latest added items, ensuring an accurate and consistent shopping experience. Here's a simplified code snippet showcasing strong consistency while updating the cart:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;addItemToCart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;itemId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Retrieves the user's current cart&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;itemId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// Adds the selected item to the cart&lt;/span&gt;
  &lt;span class="nx"&gt;saveUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                &lt;span class="c1"&gt;// Persists the updated cart&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2️⃣ Collaborative Document Editing:&lt;br&gt;
In collaborative editing tools like Google Docs, multiple users can edit the same document simultaneously. Strong consistency guarantees that all collaborators see the same document, avoiding contradictory changes. Here's a brief code example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;editDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;docId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newText&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# Retrieves the document
&lt;/span&gt;  &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;# Adds the new text to the document
&lt;/span&gt;  &lt;span class="n"&gt;saveDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;              &lt;span class="c1"&gt;# Persists the updated document
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🚫 When is Strong Consistency Discouraged?&lt;br&gt;
While strong consistency is powerful, it may not be suitable for every use case due to performance limitations or network latency. For example, social media platforms prioritize low latency and availability over strong consistency. In these cases, eventual consistency or weaker consistency models may be preferred. Let's explore a scenario where strong consistency could lead to undesired results:&lt;/p&gt;

&lt;p&gt;3️⃣ Ticket Booking System:&lt;br&gt;
Imagine a ticket booking system where multiple users can reserve seats for the same event. If strong consistency is enforced, it might lead to overselling or inconsistent seat availability. In this situation, a loosely consistent model allows better performance and avoids conflicts. Here's an illustration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bookTicket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eventId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seatNumber&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;isSeatAvailable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seatNumber&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;reserveSeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seatNumber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# Reserve the seat for the user&lt;/span&gt;
    &lt;span class="n"&gt;chargeUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="c1"&gt;# Charge the user for the ticket&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📚 Conclusion:&lt;br&gt;
Understanding strong consistency is vital for building robust distributed systems. Its ability to maintain data integrity, predictable behavior, and consistent user experiences make it a valuable tool for engineers. Remember, strong consistency is not always the go-to solution due to performance trade-offs, making it crucial to evaluate the specific needs of your application before implementation. 🌟&lt;/p&gt;

&lt;p&gt;Thanks for joining me in this journey exploring strong consistency! I hope you found this article helpful! Feel free to leave any comments or questions below! 👇&lt;/p&gt;

&lt;p&gt;🔖 Tags: #beginner #distributedsystems #strongconsistency #reliability&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🔥 Decoding Eventual Consistency 🔥</title>
      <dc:creator>Sergio Marcial</dc:creator>
      <pubDate>Mon, 28 Aug 2023 04:59:16 +0000</pubDate>
      <link>https://dev.to/sergiomarcial/decoding-eventual-consistency-561m</link>
      <guid>https://dev.to/sergiomarcial/decoding-eventual-consistency-561m</guid>
      <description>&lt;p&gt;🏆 Hey there, fellow engineers! 👋 Are you curious about the term "eventual consistency"? 🤔 Well, you've come to the right place. In this article, we'll demystify what eventual consistency is, why it's important, how it applies in real-world scenarios (especially within event-driven architectures), and even when it's discouraged. So, brace yourselves for an enlightening journey through the realms of eventual consistency! 🚀&lt;/p&gt;

&lt;p&gt;🤔 What is Eventual Consistency? 🌟&lt;/p&gt;

&lt;p&gt;Eventual consistency is a concept that plays a key role in distributed systems. It describes the state where, after a period of a distributed system returning various responses during concurrent updates, all replicas will eventually converge to a consistent state. In simpler terms, it means that even if different instances of a system have temporary inconsistencies, they will eventually synchronize to the same outcome. 🌈&lt;/p&gt;

&lt;p&gt;⚡️ Why is Eventual Consistency Important? ⚡️&lt;/p&gt;

&lt;p&gt;Since distributed systems often span across numerous servers, each having its own copy of data, ensuring immediate consistency across all replicas can be challenging. Eventual consistency allows systems to make progress even when certain replicas are unreachable or experiencing network issues. This resilience is crucial for systems with high scalability, availability, and performance requirements. By choosing eventual consistency over immediate consistency, engineers can design systems that remain operational even during failures or periods of high demand. 😎&lt;/p&gt;

&lt;p&gt;💡 Applying Eventual Consistency in the Real World 💼&lt;/p&gt;

&lt;p&gt;Let's dive into the world of event-driven architectures where eventual consistency shines 🌟 Check out two common use cases for eventual consistency:&lt;/p&gt;

&lt;p&gt;1️⃣ Social Media platforms: Imagine posting a tweet on a popular social media platform. Immediately after hitting that tweet button 💥, you expect your followers to see your message. Behind the scenes, though, the platform leverages eventual consistency to handle the vast number of followers in an efficient, scalable manner. Instead of waiting for each follower's timeline to be updated simultaneously, the platform initially updates only a subset of timelines, ensuring better performance and responsiveness. Over time, remaining timelines catch up, delivering a consistent experience to all users. 🦜&lt;/p&gt;

&lt;p&gt;2️⃣ Online Shopping: Picture yourself in the realm of e-commerce. When you place an order, the system needs to ensure inventory is available. In this case, eventual consistency allows the system to temporarily show an item as "in stock" even if it might be running low. This ensures a smooth shopping experience while avoiding out-of-stock errors. The system periodically updates stock levels and adjusts the status accordingly, ensuring consistency in the long run. By using eventual consistency in this scenario, the system can handle surges in traffic without negatively impacting the user experience. 🛒&lt;/p&gt;

&lt;p&gt;✨ Examples &amp;amp; Code Snippets 📝&lt;/p&gt;

&lt;p&gt;Let's deep-dive into some code snippets in a simplified event-driven architecture to bring clarity to how eventual consistency looks in practice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;event_bus&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;EventBus&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_order_confirmation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="c1"&gt;# Process order confirmation logic
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"Order #&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; confirmed!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;event_bus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EventBus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;event_bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"order_placed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;send_order_confirmation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;place_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="c1"&gt;# Place order logic
&lt;/span&gt;  &lt;span class="n"&gt;event_bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"order_placed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"Order #&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; placed!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, when an order is placed, a message is published on the event bus with the event name "order_placed" and the corresponding order as a payload. The function &lt;code&gt;send_order_confirmation&lt;/code&gt; is subscribed to the "order_placed" event and executes the necessary confirmations asynchronously. This event-driven architecture harnesses eventual consistency by processing events as they arrive, allowing for asynchronous and parallel processing. 🎉&lt;/p&gt;

&lt;p&gt;🚫 When to Avoid Eventual Consistency 🚫&lt;/p&gt;

&lt;p&gt;While eventual consistency offers numerous benefits, there are scenarios where it should be used with caution:&lt;/p&gt;

&lt;p&gt;1️⃣ Banking Transactions: In cases where immediate consistency is crucial, like financial systems, eventual consistency might not provide the desired level of confidence. Ensuring that each transaction is committed consistently across all replicas minimizes risks and guarantees integrity.&lt;/p&gt;

&lt;p&gt;2️⃣ Real-Time Collaborative Editors: In collaborative editing tools like Google Docs, immediate consistency is essential to ensure that all participants see the same content concurrently. Waiting for eventual consistency to update changes could lead to significant conflicts and inconsistencies.&lt;/p&gt;

&lt;p&gt;📚 Further Reading 📚&lt;/p&gt;

&lt;p&gt;If you're eager to dive deeper into eventual consistency, here are some resources to feed your curiosity:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"Designing Data-Intensive Applications" by Martin Kleppmann&lt;/li&gt;
&lt;li&gt;"Eventuate" by Chris Richardson&lt;/li&gt;
&lt;li&gt;"Eventual Consistency" - Wikipedia&lt;/li&gt;
&lt;li&gt;"Understanding and Using Eventual Consistency" - Microsoft Research&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;💡 Wrapping Up 💡&lt;/p&gt;

&lt;p&gt;Congratulations, my fellow engineers! 🎉 You've successfully unraveled the mystery of eventual consistency, understanding its significance in distributed systems, real-world applications, code snippets, and even scenarios where it's discouraged. Remember, eventual consistency is an invaluable tool for designing scalable and resilient systems. So, dive into this event-driven world, embrace eventual consistency, and architect systems that can conquer any challenge! 🌟 Happy coding! 💻&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
