<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: burak</title>
    <description>The latest articles on Forem by burak (@burrock).</description>
    <link>https://forem.com/burrock</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%2F519266%2Fb155a979-4d61-40d2-846f-50d061800c8c.JPG</url>
      <title>Forem: burak</title>
      <link>https://forem.com/burrock</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/burrock"/>
    <language>en</language>
    <item>
      <title>Pipelink</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Mon, 28 Apr 2025 09:38:59 +0000</pubDate>
      <link>https://forem.com/burrock/pipelink-29p0</link>
      <guid>https://forem.com/burrock/pipelink-29p0</guid>
      <description>&lt;p&gt;Hello everyone, I will be sharing my experiences with Vibe Coding, which has recently become popular. By practicing Vibe Coding, you can increase your development speed and even build products in areas you are not familiar with. In the .NET world, the MediatR library, which has maintained its popularity for a long time, announced that it will become a paid product in the future. You can see the details on this site: &lt;a href="https://www.reddit.com/r/dotnet/comments/1jul7yy/mediatr_and_masstransit_going_commercial_what_are/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/dotnet/comments/1jul7yy/mediatr_and_masstransit_going_commercial_what_are/&lt;/a&gt;. After hearing about this, I asked myself, 'Why don't I develop my own library?' After providing ChatGPT with some details about the project and having a Q&amp;amp;A session about what the project name could be, the name 'Pipelink' emerged."&lt;/p&gt;

&lt;p&gt;While creating the Pipelink NuGet package, I started by giving the first prompt about the foundational structure of the project. After that, I specified that the project should primarily use CQRS design patterns. In general, I also prepared prompts asking for both unit tests and integration tests to be written for the generated code, and for the tests to be executed to verify the outputs.&lt;/p&gt;

&lt;p&gt;After these steps, my first task was to create an account on the NuGet server and generate an API Key from that account. Using this API Key, I created .nuspec files with the help of Cursor AI and pushed the package versions to NuGet. However, the NuGet package didn't have a logo. To solve this, I used ChatGPT to iterate 2-3 times and finally generated a logo.&lt;/p&gt;

&lt;p&gt;I made the project code and the package available for free. If you would like to check it out, you can find it here: &lt;a href="https://github.com/bburaksseyhan/pipelink/tree/production" rel="noopener noreferrer"&gt;https://github.com/bburaksseyhan/pipelink/tree/production&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After completing these steps, I used Cursor AI to generate the README.md files for both the library and the integration tests. Additionally, I created all the code comments within the library using JetBrains AI. Thanks to this approach, I was able to produce the usage guide within minutes.&lt;/p&gt;

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

&lt;p&gt;After completing these steps, I focused a bit on performance by generating prompts related to optimization and repeatedly running tests. I compared the results I obtained with MediatR. Whenever I identified areas where the performance was slower, I created new prompts and specifically updated the code around reflection usage. I repeated this cycle at least five times. With this post, I am now running one final round of benchmarks.&lt;/p&gt;

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

&lt;p&gt;To briefly summarize the steps I completed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Designed the project infrastructure
&lt;/li&gt;
&lt;li&gt;Developed the entire project code
&lt;/li&gt;
&lt;li&gt;Added comments and documentation to methods
&lt;/li&gt;
&lt;li&gt;Created and deployed the NuGet package
&lt;/li&gt;
&lt;li&gt;Wrote unit and integration tests
&lt;/li&gt;
&lt;li&gt;Performed performance optimizations
&lt;/li&gt;
&lt;li&gt;Designed a logo
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I developed the Pipelink package in a total of 6–8 hours of work. I believe this amount of effort would normally take considerably longer for a developer. My goal was not to create competition, but rather to explore what I could build, how well, and how quickly by applying the Vibe Coding approach. As .NET developers, you can freely download and use the Pipelink package in your projects. I'll discuss second project that is call Pipelink.Outbox but still avaiable.&lt;/p&gt;

&lt;p&gt;Nuget : &lt;a href="https://www.nuget.org/packages?q=Pipelink" rel="noopener noreferrer"&gt;Pipelink&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy coding...&lt;/p&gt;

</description>
      <category>ai</category>
      <category>cursor</category>
      <category>csharp</category>
      <category>vibecoding</category>
    </item>
    <item>
      <title>Design interservice communication for microservice</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Mon, 04 Dec 2023 13:09:01 +0000</pubDate>
      <link>https://forem.com/burrock/design-interservice-communication-for-microservice-40n1</link>
      <guid>https://forem.com/burrock/design-interservice-communication-for-microservice-40n1</guid>
      <description>&lt;h2&gt;
  
  
  What Are Microservices?
&lt;/h2&gt;

&lt;p&gt;Microservices are independently deployable services modeled around a business domain. They communicate with each other via networks, and as an architecture choice offer many options for solving the problems you may face. They are a type of service-oriented architecture, albeit one that is opinionated about how service boundaries should be drawn and that independent deployability is key. From a technology viewpoint, microservices expose the business capabilities that they encapsulate via one or more network endpoints. They also encapsulate data storage and retrieval, exposing data, via well-defined interfaces.&lt;/p&gt;

&lt;p&gt;Communication between microservices must be efficient and robust. With lots of small services interacting to complete a single business activity, this can be a challenge. Speaking about difficulty, I would like to write about microservice patterns that I'm gonna write publisher subscriptions. These days I find have time to develop technically. While watching a training video on Linkedin, I remembered the work I had done at the company. I said why didn't you write a short article? Today's content is a pattern that we know publisher-subscriber. The reason is we need multiple subscribers. You will find them in this article.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Details of pattern&lt;/li&gt;
&lt;li&gt;Definition of Entities&lt;/li&gt;
&lt;li&gt;Cross-Account Integration with Amazon SNS&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;"Pub/Sub" stands for "Publish/Subscribe," and it's a messaging pattern used in distributed systems and event-driven architectures. In a Pub/Sub system, the communication between different components (or services) is facilitated through the concept of channels or topics. The publisher-subscriber design architecture is below.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;What are the use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple tasks&lt;/li&gt;
&lt;li&gt;Multiple responders&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Publishers:&lt;/strong&gt; Entities that generate and send messages without knowing who or what might be listening. Publishers "publish" messages to specific channels or topics.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Subscribers:&lt;/strong&gt; Entities that express interest in receiving messages on specific channels or topics. Subscribers "subscribe" to these channels and receive any messages published to those channels.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Broker (Message Queue or Middleware):&lt;/strong&gt; This is an intermediary component that manages the distribution of messages. It takes care of routing messages from publishers to subscribers based on the channels or topics to which they are subscribed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The key idea is that publishers and subscribers are decoupled. Publishers don't need to know anything about the subscribers, and vice versa. This decoupling allows for a more flexible and scalable system, where components can be added or removed without affecting the others.&lt;/p&gt;

&lt;p&gt;I needed to pub&amp;amp;sub implementation in the last 2 companies that I worked for. Specifically, it was Tiko. Before the business changed at Tiko, my team was responsible for web scraping and web crawling. The main area is collecting, storing, and sharing data with cross domains. The challenge is one crawl operation collects an average of 5 million data and needs to be shared as fast and without losing data. Each team represents a different AWS account. The problem is how to send a message to an SQS in a different account. In the following section, I will describe how to develop steps and explain the subscription access policy rule. In 2023 AWS released the Document db streaming which means every CRUD operation can be a trigger event. I used the streaming process because it is fully managed, with no downtime, and is consistent, and reliable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up the document db streaming settings.&lt;/li&gt;
&lt;li&gt;Create a new Serverless application&lt;/li&gt;
&lt;li&gt;Create an SQS with the name of the router queue&lt;/li&gt;
&lt;li&gt;Add trigger Serverless to SQS&lt;/li&gt;
&lt;li&gt;Create 3 SNS Topics for listing separation by country code (use filter policy).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The topics have already subscribed to the router-service lambda application. That architecture works as event-driven when listing data and writing the database that throws the event.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1j6e6rz1vcrruiiyyht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1j6e6rz1vcrruiiyyht.png" alt="Cross Account Architecture" width="800" height="393"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Version": "2008-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__default_statement_ID",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "SNS:GetTopicAttributes",
        "SNS:SetTopicAttributes",
        "SNS:AddPermission",
        "SNS:RemovePermission",
        "SNS:DeleteTopic",
        "SNS:Subscribe",
        "SNS:ListSubscriptionsByTopic",
        "SNS:Publish"
      ],
      "Resource": "arn:aws:sns:eu-central-1:owner-account-id:distributer-topic",
      "Condition": {
        "StringEquals": {
          "AWS:SourceOwner": "owner-account-id"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::team-1:root",
          "arn:aws:iam::team-2:root"
        ]
      },
      "Action": [
        "SNS:Subscribe",
        "SNS:Publish"
      ],
      "Resource": "arn:aws:sns:eu-central-1:owner-account-id:distributer-topic"
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Loose Coupling:&lt;/strong&gt; Publishers and subscribers are independent of each other, promoting a more modular and maintainable architecture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; New subscribers or publishers can be added easily without affecting the existing components.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous Communication:&lt;/strong&gt; Pub/Sub systems often enable asynchronous communication, allowing components to operate independently and potentially improving system responsiveness.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Last words&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every team manages own applications which means no dependency&lt;/li&gt;
&lt;li&gt;Almost fully managed and event-driven system that was created.&lt;/li&gt;
&lt;li&gt;Manage the data send speed with lambda concurrency.&lt;/li&gt;
&lt;li&gt;Any team subscribes to any Topic. That provides more flexibility&lt;/li&gt;
&lt;li&gt;Every team works own SQS and SQS DLQ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reference: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/sns/latest/dg/sns-send-message-to-sqs-cross-account.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/sns/latest/dg/sns-send-message-to-sqs-cross-account.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/with-documentdb.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/lambda/latest/dg/with-documentdb.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/architecture/microservices/design/interservice-communication" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/azure/architecture/microservices/design/interservice-communication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Monolith to Microservices(Sam Newman)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>microservices</category>
      <category>aws</category>
      <category>pubsub</category>
      <category>designpatterns</category>
    </item>
    <item>
      <title>How to use Go With MongoDB</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Wed, 01 Dec 2021 11:36:02 +0000</pubDate>
      <link>https://forem.com/burrock/how-to-use-go-with-mongodb-3e8d</link>
      <guid>https://forem.com/burrock/how-to-use-go-with-mongodb-3e8d</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/yemeksepeti-teknoloji/how-to-use-go-with-mongodb-72963c8cebbc" rel="noopener noreferrer"&gt;https://medium.com/yemeksepeti-teknoloji/how-to-use-go-with-mongodb-72963c8cebbc&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Working MongoDB with Golang</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Thu, 11 Nov 2021 14:23:47 +0000</pubDate>
      <link>https://forem.com/burrock/working-mongodb-with-golang-2g76</link>
      <guid>https://forem.com/burrock/working-mongodb-with-golang-2g76</guid>
      <description>&lt;p&gt;Every tutorial has a story. In that tutorial you'll find out different contents that is related to MongoDB, GoLang and working with mock data and deployment. Here is my content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project structure
&lt;/h2&gt;

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

&lt;p&gt;PS: Here is the one different folder that name is dummy_api. That folder has own main file. What does it mean? When I run the main.go file before I'll add mock data. If you didn't catch up &lt;a href="https://dev.to/bseyhan/hey-marshal-1134"&gt;Working with the marshal and unmarshal&lt;/a&gt; tutorial you should read it. Another important topics is "context". &lt;a href="https://www.programming-books.io/essential/go/context.todo-vs.context.background-d5224e27ff724a33a79cb4e03a5eb333.html" rel="noopener noreferrer"&gt;Essential Go&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;context.TODO()&lt;br&gt;
&lt;strong&gt;TODO returns a non-nil, empty Context.&lt;/strong&gt; Code should use context.TODO when it’s unclear which Context to use or it is not yet available (because the surrounding function has not yet been extended to accept a Context parameter). TODO is recognized by static analysis tools that determine whether Contexts are propagated correctly in a program.&lt;/p&gt;

&lt;p&gt;context.Background()&lt;br&gt;
Background returns a non-nil, empty Context. &lt;strong&gt;It is never canceled&lt;/strong&gt;, has no values, and has no deadline. It is typically used by the main function, initialization, and tests, and as the top-level Context for incoming requests.&lt;/p&gt;
&lt;/blockquote&gt;

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

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

&lt;p&gt;Another different package is about MongoDb Client however I'll talk about below.&lt;br&gt;
&lt;/p&gt;

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

import (
    "context"
    "encoding/json"
    "io/ioutil"
    "os"

    "github.com/bburaksseyhan/contact-api/src/pkg/client/mongodb"
    "github.com/bburaksseyhan/contact-api/src/pkg/model"
    "github.com/sirupsen/logrus"
)

func main() {

    contactsJson, err := os.Open("contacts.json")

    if err != nil {
        logrus.Error("contact.json an error occurred", err)
    }

    defer contactsJson.Close()

    var contacts []model.Contact

    byteValue, _ := ioutil.ReadAll(contactsJson)

    //unmarshall data
    if err := json.Unmarshal(byteValue, &amp;amp;contacts); err != nil {
        logrus.Error("unmarshall an error occurred", err)
    }

    logrus.Info("Data\n", len(contacts))

    //import mongo client
    client := mongodb.ConnectMongoDb("mongodb://localhost:27017")
    logrus.Info(client)

    defer client.Disconnect(context.TODO())

    collection := client.Database("ContactDb").Collection("contacts")

    logrus.Warn("Total data count:", &amp;amp;contacts)

    for _, item := range contacts {
        collection.InsertOne(context.TODO(), item)
    }

    logrus.Info("Data import finished...")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Firstly let's open the terminal and goes to dummy_api directory. Another important thing, is database running? Let's have look. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker compose up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker container ls&lt;/code&gt;&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Working with mock data
&lt;/h2&gt;

&lt;p&gt;I was creating mock data from &lt;a href="https://www.mockaroo.com/" rel="noopener noreferrer"&gt;Mockaroo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with MongoDB queries
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker exec -it ad2d44477f28 mongo //connect to mongodb cli

help

show dbs // return all database names

use ContactDb 

show collections // return collection name

db.contacts.find() //return all collections

db.contacts.find({}).count() // return row count

db.contacts.find({}).pretty({}) // return rows with a format

db.contacts.find({"email":""})
db.dropDatabase() // remove database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

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

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

&lt;h2&gt;
  
  
  Using packages
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;"go get -u go.mongodb.org/mongo-driver/bson"&lt;/li&gt;
&lt;li&gt;"go get -u go.mongodb.org/mongo-driver/mongo"&lt;/li&gt;
&lt;li&gt;"go get -u go.mongodb.org/mongo-driver/mongo/options"&lt;/li&gt;
&lt;li&gt;"go get -u github.com/gin-gonic/gin"&lt;/li&gt;
&lt;li&gt;"go get -u github.com/sirupsen/logrus"&lt;/li&gt;
&lt;li&gt;"go get -u github.com/spf13/viper"&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  main.go file
&lt;/h3&gt;

&lt;p&gt;That file read config.yml or .env file after that call the Init function.&lt;br&gt;
&lt;/p&gt;

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

import (
    "os"

    "github.com/bburaksseyhan/contact-api/src/cmd/utils"
    "github.com/bburaksseyhan/contact-api/src/pkg/server"
    log "github.com/sirupsen/logrus"
    "github.com/spf13/viper"
)

func main() {

    config := read()
    log.Info("Config.yml", config.Database.Url)

    mongoUri := os.Getenv("MONGODB_URL")

    if mongoUri != "" {
        config.Database.Url = mongoUri
    }

    log.Info("MONGODB_URL", mongoUri)

    server.Init(config.Database.Url)
}

func read() utils.Configuration {
    //Set the file name of the configurations file
    viper.SetConfigName("config")

    // Set the path to look for the configurations file
    viper.AddConfigPath(".")

    // Enable VIPER to read Environment Variables
    viper.AutomaticEnv()

    viper.SetConfigType("yml")
    var config utils.Configuration

    if err := viper.ReadInConfig(); err != nil {
        log.Error("Error reading config file, %s", err)
    }

    err := viper.Unmarshal(&amp;amp;config)
    if err != nil {
        log.Error("Unable to decode into struct, %v", err)
    }

    return config
}

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

&lt;/div&gt;



&lt;p&gt;ConnectMongoDb function takes the MongoDB URL parameter so this function opens the connection and check the status. &lt;a href="https://www.mongodb.com/blog/post/mongodb-go-driver-tutorial" rel="noopener noreferrer"&gt;Related Documentation&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

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

import (
    "context"

    log "github.com/sirupsen/logrus"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func ConnectMongoDb(url string) *mongo.Client {

    clientOptions := options.Client().ApplyURI(url)

    // Connect to MongoDB
    client, err := mongo.Connect(context.TODO(), clientOptions)

    if err != nil {
        log.Fatal(err)
    }

    // Check the connection
    err = client.Ping(context.TODO(), nil)

    if err != nil {
        log.Fatal(err)
    }

    log.Info("MongoClient connected")

    return client
}


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

&lt;/div&gt;



&lt;p&gt;unfinished contact_handler.go file. HealthCheck function is not only health check. That function checks the MongoDb database status with a timeout. If any cancellation comes from the server, context will be triggered and response will be un-health. Let's think the opposite result will be pong.&lt;br&gt;
&lt;/p&gt;

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

import (
    "context"
    "net/http"
    "time"

    "github.com/gin-gonic/gin"
    "github.com/sirupsen/logrus"
    "go.mongodb.org/mongo-driver/mongo"
)

type ContactHandler interface {
    GetAllContacts(*gin.Context)
    GetContactByCity(*gin.Context)
    HealthCheck(*gin.Context)
}

type contactHandler struct {
    client *mongo.Client
}

func NewContactHandler(client *mongo.Client) ContactHandler {
    return &amp;amp;contactHandler{client: client}
}

func (ch *contactHandler) GetAllContacts(c *gin.Context) {
    _, ctxErr := context.WithTimeout(c.Request.Context(), 30*time.Second)
    defer ctxErr()

    //request on repository

    c.JSON(http.StatusOK, gin.H{"contacts": "pong"})
}

func (ch *contactHandler) GetContactByCity(c *gin.Context) {
    _, ctxErr := context.WithTimeout(c.Request.Context(), 30*time.Second)
    defer ctxErr()

    //request on repository

    c.JSON(http.StatusOK, gin.H{"contacts": "pong"})
}

func (ch *contactHandler) HealthCheck(c *gin.Context) {

    ctx, ctxErr := context.WithTimeout(c.Request.Context(), 30*time.Second)
    defer ctxErr()

    if ctxErr != nil {
        logrus.Error("somethig wrong!!!", ctxErr)
    }

    if err := ch.client.Ping(ctx, nil); err != nil {
        c.JSON(http.StatusOK, gin.H{"status": "unhealty"})
    }

    c.JSON(http.StatusOK, gin.H{"status": "pong"})
}

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

&lt;/div&gt;



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

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

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

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

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

&lt;h1&gt;
  
  
  Completed codes
&lt;/h1&gt;

&lt;h2&gt;
  
  
  main
&lt;/h2&gt;



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

import (
    "os"

    "github.com/bburaksseyhan/contact-api/src/cmd/utils"
    "github.com/bburaksseyhan/contact-api/src/pkg/server"
    log "github.com/sirupsen/logrus"
    "github.com/spf13/viper"
)

func main() {

    config := read()
    log.Info("Config.yml", config.Database.Url)

    mongoUri := os.Getenv("MONGODB_URL")
    serverPort := os.Getenv("SERVER_PORT")
    dbName := os.Getenv("DBNAME")
    collection := os.Getenv("COLLECTION")

    if mongoUri != "" {
        config.Database.Url = mongoUri
        config.Server.Port = serverPort
        config.Database.DbName = dbName
        config.Database.Collection = collection
    }

    log.Info("MONGODB_URL", mongoUri)

    server.Init(config)
}

func read() utils.Configuration {
    //Set the file name of the configurations file
    viper.SetConfigName("config")

    // Set the path to look for the configurations file
    viper.AddConfigPath(".")

    // Enable VIPER to read Environment Variables
    viper.AutomaticEnv()

    viper.SetConfigType("yml")
    var config utils.Configuration

    if err := viper.ReadInConfig(); err != nil {
        log.Error("Error reading config file, %s", err)
    }

    err := viper.Unmarshal(&amp;amp;config)
    if err != nil {
        log.Error("Unable to decode into struct, %v", err)
    }

    return config
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  config
&lt;/h2&gt;



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

type Configuration struct {
    Database DatabaseSetting
    Server   ServerSettings
}

type DatabaseSetting struct {
    Url        string
    DbName     string
    Collection string
}

type ServerSettings struct {
    Port string
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  server
&lt;/h2&gt;



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

import (
    "github.com/bburaksseyhan/contact-api/src/cmd/utils"
    "github.com/bburaksseyhan/contact-api/src/pkg/client/mongodb"
    "github.com/bburaksseyhan/contact-api/src/pkg/handler"
    repository "github.com/bburaksseyhan/contact-api/src/pkg/repository/mongodb"

    "github.com/gin-gonic/gin"
    log "github.com/sirupsen/logrus"
)

func Init(config utils.Configuration) {

    // Creates a gin router with default middleware:
    // logger and recovery (crash-free) middleware
    router := gin.Default()

    client := mongodb.ConnectMongoDb(config.Database.Url)

    repo := repository.NewContactRepository(&amp;amp;config, client)
    handler := handler.NewContactHandler(client, repo)

    router.GET("/", handler.GetAllContacts)
    router.GET("/contacts/:email", handler.GetContactByEmail)
    router.POST("/contact/delete/:id", handler.DeleteContact)

    router.GET("/health", handler.HealthCheck)

    log.Info("port is :8080\n", config.Database.Url)

    // PORT environment variable was defined.
    router.Run(":" + config.Server.Port + "")
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  handler
&lt;/h2&gt;



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

import (
    "context"
    "net/http"
    "strconv"
    "time"

    "github.com/bburaksseyhan/contact-api/src/pkg/model"
    db "github.com/bburaksseyhan/contact-api/src/pkg/repository/mongodb"

    "github.com/gin-gonic/gin"
    "github.com/sirupsen/logrus"
    "go.mongodb.org/mongo-driver/mongo"
)

type ContactHandler interface {
    GetAllContacts(*gin.Context)
    GetContactByEmail(*gin.Context)
    DeleteContact(*gin.Context)

    HealthCheck(*gin.Context)
}

type contactHandler struct {
    client     *mongo.Client
    repository db.ContactRepository
}

func NewContactHandler(client *mongo.Client, repo db.ContactRepository) ContactHandler {
    return &amp;amp;contactHandler{client: client, repository: repo}
}

func (ch *contactHandler) GetAllContacts(c *gin.Context) {

    ctx, ctxErr := context.WithTimeout(c.Request.Context(), 30*time.Second)
    defer ctxErr()

    var contactList []*model.Contact

    //request on repository
    if result, err := ch.repository.Get(ctx); err != nil {
        logrus.Error(err)
    } else {
        contactList = result
    }

    c.JSON(http.StatusOK, gin.H{"contacts": &amp;amp;contactList})
}

func (ch *contactHandler) GetContactByEmail(c *gin.Context) {

    ctx, ctxErr := context.WithTimeout(c.Request.Context(), 30*time.Second)
    defer ctxErr()

    var contactList *model.Contact

    //get parameter
    email := c.Param("email")

    //request on repository
    if result, err := ch.repository.GetContactByEmail(email, ctx); err != nil {
        logrus.Error(err)
    } else {
        contactList = result
    }

    c.JSON(http.StatusOK, gin.H{"contacts": contactList})
}

func (ch *contactHandler) HealthCheck(c *gin.Context) {

    ctx, ctxErr := context.WithTimeout(c.Request.Context(), 30*time.Second)
    defer ctxErr()

    if ctxErr != nil {
        logrus.Error("somethig wrong!!!", ctxErr)
    }

    if err := ch.client.Ping(ctx, nil); err != nil {
        c.JSON(http.StatusOK, gin.H{"status": "unhealty"})
    }

    c.JSON(http.StatusOK, gin.H{"status": "pong"})
}

func (ch *contactHandler) DeleteContact(c *gin.Context) {

    ctx, ctxErr := context.WithTimeout(c.Request.Context(), 30*time.Second)
    defer ctxErr()

    //get parameter
    id, err := strconv.Atoi(c.Param("id"))
    if err != nil {
        logrus.Error("Can not convert to id", err)
    }

    //request on repository
    result, err := ch.repository.Delete(id, ctx)
    if err != nil {
        logrus.Error(err)
    }

    c.JSON(http.StatusOK, gin.H{"deleteResult.DeletedCount": result})
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  repository
&lt;/h2&gt;



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

import (
    "context"

    "github.com/bburaksseyhan/contact-api/src/cmd/utils"
    "github.com/bburaksseyhan/contact-api/src/pkg/model"
    "github.com/sirupsen/logrus"
    log "github.com/sirupsen/logrus"
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/bson/primitive"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type ContactRepository interface {
    Get(ctx context.Context) ([]*model.Contact, error)
    GetContactByEmail(email string, ctx context.Context) (*model.Contact, error)
    Delete(id int, ctx context.Context) (int64, error)
}

type contactRepository struct {
    client *mongo.Client
    config *utils.Configuration
}

func NewContactRepository(config *utils.Configuration, client *mongo.Client) ContactRepository {
    return &amp;amp;contactRepository{config: config, client: client}
}

func (c *contactRepository) Get(ctx context.Context) ([]*model.Contact, error) {

    findOptions := options.Find()
    findOptions.SetLimit(100)

    var contacts []*model.Contact

    collection := c.client.Database(c.config.Database.DbName).Collection(c.config.Database.Collection)

    // Passing bson.D{{}} as the filter matches all documents in the collection
    cur, err := collection.Find(ctx, bson.D{{}}, findOptions)
    if err != nil {
        log.Fatal(err)
        return nil, err
    }

    // Finding multiple documents returns a cursor
    // Iterating through the cursor allows us to decode documents one at a time
    for cur.Next(context.TODO()) {
        // create a value into which the single document can be decoded
        var elem model.Contact
        if err := cur.Decode(&amp;amp;elem); err != nil {
            log.Fatal(err)
            return nil, err
        }

        contacts = append(contacts, &amp;amp;elem)
    }

    cur.Close(ctx)

    return contacts, nil
}

func (c *contactRepository) GetContactByEmail(email string, ctx context.Context) (*model.Contact, error) {

    findOptions := options.Find()
    findOptions.SetLimit(100)

    var contacts *model.Contact

    collection := c.client.Database(c.config.Database.DbName).Collection(c.config.Database.Collection)

    filter := bson.D{primitive.E{Key: "email", Value: email}}

    logrus.Info("Filter", filter)

    collection.FindOne(ctx, filter).Decode(&amp;amp;contacts)

    return contacts, nil
}

func (c *contactRepository) Delete(id int, ctx context.Context) (int64, error) {

    collection := c.client.Database(c.config.Database.DbName).Collection(c.config.Database.Collection)

    filter := bson.D{primitive.E{Key: "id", Value: id}}

    deleteResult, err := collection.DeleteOne(ctx, filter)
    if err != nil {
        log.Fatal(err)

        return 0, err
    }

    return deleteResult.DeletedCount, nil
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;docker compose up&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/bburaksseyhan/contact-api.git" rel="noopener noreferrer"&gt;Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you,&lt;/p&gt;

</description>
      <category>go</category>
      <category>mongodb</category>
      <category>programming</category>
      <category>database</category>
    </item>
    <item>
      <title>Cassandra &amp; GoLang</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Tue, 09 Nov 2021 12:43:40 +0000</pubDate>
      <link>https://forem.com/burrock/cassandra-golang-551a</link>
      <guid>https://forem.com/burrock/cassandra-golang-551a</guid>
      <description>&lt;p&gt;Hi there,&lt;/p&gt;

&lt;p&gt;Did you read my latest implementation of PostgreSQL with GoLang? &lt;a href="https://dev.to/bseyhan/golang-with-database-operations-3jl0"&gt;PostgresWithGo&lt;/a&gt; If you said of course :) go head... Do you know have any knowledge about Cassandra? Don't worry neither am I've not. I like to share about the subjects I work on. So be relax. Are you curious about NOSQl and GoLang? In this post I'll share my Cassandra Db and GoLang knowledge. You'll ask these questions ask yourself, What is Cassandra Db then how to install Cassandra DB to your local machine, which package should I use for it. All of these are in here.  &lt;/p&gt;

&lt;p&gt;Step 1 : What is Cassandra DB&lt;br&gt;
Step 2 : How to install it&lt;br&gt;
Step 3 : Important commands &lt;br&gt;
Step 4 : Connect to database&lt;br&gt;
Step 5 : Implementation&lt;br&gt;
Step 6 : Postman Tests&lt;/p&gt;

&lt;p&gt;Let's go to work and I hope you'll enjoy it.&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 1: What is Cassandra DB
&lt;/h1&gt;

&lt;p&gt;NoSQL databases are called “Not Only SQL” or “Non-relational” databases. NoSQL databases store and retrieve data other than tabular relations such as relation databases.&lt;/p&gt;

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

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

&lt;p&gt;Elastic scalability − Cassandra is highly scalable; it allows to add more hardware to accommodate more customers and more data as per requirement.&lt;/p&gt;

&lt;p&gt;Always on architecture − Cassandra has no single point of failure and it is continuously available for business-critical applications that cannot afford a failure.&lt;/p&gt;

&lt;p&gt;Fast linear-scale performance − Cassandra is linearly scalable, i.e., it increases your throughput as you increase the number of nodes in the cluster. Therefore it maintains a quick response time.&lt;/p&gt;

&lt;p&gt;Flexible data storage − Cassandra accommodates all possible data formats including: structured, semi-structured, and unstructured. It can dynamically accommodate changes to your data structures according to your need.&lt;/p&gt;

&lt;p&gt;Easy data distribution − Cassandra provides the flexibility to distribute data where you need by replicating data across multiple data centers.&lt;/p&gt;

&lt;p&gt;Transaction support − Cassandra supports properties like Atomicity, Consistency, Isolation, and Durability (ACID).&lt;/p&gt;

&lt;p&gt;Fast writes − Cassandra was designed to run on cheap commodity hardware. It performs blazingly fast writes and can store hundreds of terabytes of data, without sacrificing the read efficiency.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data Types
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Firiicx2zds0e5iasyobk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Firiicx2zds0e5iasyobk.png" alt="Image description" width="800" height="741"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 2: How to install
&lt;/h1&gt;

&lt;p&gt;I'm using mac os. I've already installed Docker application on my machine. So may be you want to install only docker container. &lt;a href="https://docs.docker.com/get-docker/" rel="noopener noreferrer"&gt;Install Docker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker pull cassandra&lt;/code&gt;&lt;br&gt;
&lt;code&gt;docker run -d --name cassandra -p 9042:9042 cassandra&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;In this repository I created docker-compose.yml file that file contains with required images.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  cassandra:
    image: cassandra:latest
    container_name: cassandra
    ports: 
      - 7000:7000
      - 7001:7001
      - 7199:7199
      - 9042:9042
      - 9160:9160
    restart: always
    environment:
       - CASSANDRA_BROADCAST_ADDRESS=host.docker.internal
       - CASSANDRA_SEEDS=host.docker.internal 
    volumes:
        - ./out/cassandra_data:/var/lib/cassandra
    healthcheck:
        test: ["CMD", "cqlsh", "-u cassandra", "-p cassandra" ,"-e describe keyspaces"]
        interval: 15s
        timeout: 10s
        retries: 10

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;7199 - JMX (was 8080 pre Cassandra 0.8.xx)&lt;/li&gt;
&lt;li&gt;7000 - Internode communication (not used if TLS enabled)&lt;/li&gt;
&lt;li&gt;7001 - TLS Internode communication (used if TLS enabled)&lt;/li&gt;
&lt;li&gt;9160 - Thrift client API&lt;/li&gt;
&lt;li&gt;9042 - CQL native transport port&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 3: Important Commands&lt;/p&gt;

&lt;p&gt;After the installation since I want to create a database, I have to run this command. What is cqlsh? It is the interface. cqlsh is a command-line interface for interacting with Cassandra using CQL (the Cassandra Query Language). &lt;a href="https://cassandra.apache.org/doc/latest/cassandra/tools/cqlsh.html" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker exec -it cassandra cqlsh&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;Let's create a todo table.&lt;/p&gt;

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

&lt;p&gt;Step 4: Connect to database &lt;/p&gt;

&lt;p&gt;Install the VSCode extension for Cassandra.&lt;/p&gt;

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

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

&lt;p&gt;Step 5 : Implementation&lt;/p&gt;

&lt;p&gt;Project structure:&lt;/p&gt;

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

&lt;p&gt;--&amp;gt; cmd &lt;br&gt;
  --&amp;gt; api(main.go) this file deal with read config.yml file &lt;br&gt;
  --&amp;gt; util(config.go &amp;amp; errors.go) config.go is related with application configurations, errors.go is a custom response implementation.&lt;/p&gt;

&lt;p&gt;--&amp;gt; pkg&lt;br&gt;
  --&amp;gt; api (api.go) this file integrated to initialize&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
func Initialize(config utils.Configuration) {

    // Creates a gin router with default middleware:
    router := gin.Default()

    fmt.Printf("%+v\n", config)

    //register database ,repositories and handlers
    session := cassandra.ConnectDatabase(config.Database.Url, config.Database.Keyspace)

    repository := db.NewTodoRepository(session)
    orderHandler := handler.NewTodoHandler(&amp;amp;repository)

    router.GET("/ping", orderHandler.HealthCheck)

    router.POST("/", orderHandler.CreateTodo)
    router.GET("api/v1/todo/:id", orderHandler.GetTodoById)

    //run the server :8080
    router.Run(":8080")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;--&amp;gt; client/cassandra &lt;/p&gt;

&lt;p&gt;The ConnectDatabase function take 2 parameters from api.go file. After creation that function response session. This session&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func ConnectDatabase(url string, keyspace string) *gocql.Session {

    cluster := gocql.NewCluster(url)
    cluster.Keyspace = keyspace
    cluster.Consistency = gocql.Quorum

    session, _ := cluster.CreateSession()

    return session
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click fn+12 CreateSession&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// CreateSession initializes the cluster based on this config and returns a
// session object that can be used to interact with the database.
func (cfg *ClusterConfig) CreateSession() (*Session, error) {
    return NewSession(*cfg)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;--&amp;gt;handler&lt;br&gt;
TodoHandler related with request database and response JSON data also error handling is done for that level. All function take c *gin.Context parameter also these functions has receiver function (t *todoHandler) which means that you can access the repository with t.Save or t.GetById.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (t *todoHandler) CreateTodo(c *gin.Context) {
    var todo model.Todo

    c.BindJSON(&amp;amp;todo)

    todo.Id = uuid.New().String()
    log.Info("Data is ", todo)
    data, err := t.repo.Save(todo)

    if err != nil {
        c.JSON(http.StatusBadRequest, utils.BadRequestError("insert operation failed!", err))
    }

    c.JSON(http.StatusCreated, gin.H{"todo": data})
}

func (t *todoHandler) GetTodoById(c *gin.Context) {

    id := c.Param("id")

    todo, err := t.repo.GetById(id)
    if err != nil {
        c.JSON(http.StatusBadRequest, utils.BadRequestError("todo not found", err))
    }

    c.JSON(http.StatusOK, gin.H{"todo": todo})
}

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

&lt;/div&gt;



&lt;p&gt;GIN : c.JSON(http.StatusOK, gin.H{"todo": todo}) &lt;br&gt;
Echo: return c.JSON(http.StatusOK, data)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// JSON serializes the given struct as JSON into the response body.
// It also sets the Content-Type as "application/json".
func (c *Context) JSON(code int, obj interface{}) {
    c.Render(code, render.JSON{Data: obj})
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Binding JSON data in GIN&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// BindJSON is a shortcut for c.MustBindWith(obj, binding.JSON).
func (c *Context) BindJSON(obj interface{}) error {
    return c.MustBindWith(obj, binding.JSON)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In repository layer has "github.com/gocql/gocql" package that's is related the queries and executions. Cassandra DB queries similar to PostgreSQL, MsSQL or MySQL queries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (t *todoRepository) Save(todo model.Todo) (*model.Todo, error) {

    var query string = "INSERT INTO todo(id,title,content) VALUES(?,?,?)"

    if err := t.session.Query(query, todo.Id, todo.Title, todo.Content).Exec(); err != nil {
        return nil, err
    }

    return &amp;amp;todo, nil
}

func (t *todoRepository) GetById(id string) (*model.Todo, error) {

    var todo model.Todo

    var query string = `SELECT id,title,content FROM todo where id=?`

    if err := t.session.Query(query, id).Scan(&amp;amp;todo.Id, &amp;amp;todo.Title, &amp;amp;todo.Content); err != nil {

        if err == gocql.ErrNotFound {
            return nil, err
        }

        return nil, err
    }

    return &amp;amp;todo, nil
}

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

&lt;/div&gt;



&lt;p&gt;Now Let's run the docker-compose file. Cassandra DB has own health check configuration. &lt;br&gt;
&lt;code&gt;docker-compose up&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    healthcheck:
        test: ["CMD", "cqlsh", "-u cassandra", "-p cassandra" ,"-e describe keyspaces"]
        interval: 15s
        timeout: 10s
        retries: 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When database is running you can see the status is health&lt;/p&gt;

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

&lt;p&gt;Step 6: Postman Test&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run the program
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ljevv4onefwpdh6bria.png" alt="Image description" width="800" height="167"&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

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

&lt;h4&gt;
  
  
  References
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://www.tutorialspoint.com/cassandra/cassandra_introduction.htm" rel="noopener noreferrer"&gt;TutorialPoint&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.guru99.com/cassandra-tutorial.html" rel="noopener noreferrer"&gt;Guru99&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bburaksseyhan/todo-api" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>go</category>
      <category>cassandra</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Hey Marshal</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Mon, 01 Nov 2021 12:59:38 +0000</pubDate>
      <link>https://forem.com/burrock/hey-marshal-1134</link>
      <guid>https://forem.com/burrock/hey-marshal-1134</guid>
      <description>&lt;p&gt;Hi everyone,&lt;/p&gt;

&lt;p&gt;Before creating a project, let's simply talk about other issue. What is Json, Struct, Marshall &amp;amp; UnMarshall. In this document, I'll introduce Json to Struct and apposite of it. How to make a request and how to convert it. What are these required packages? A struct is a user-defined type that represent a collection of field. If you write C# code before you might remember it. Well let's start. First in first how to define a simple struct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Users struct{}

type Customers struct{}

type Students struct{
    FirstName string
    LastName  string
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a new GoLang project and run it.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Create Student Struct
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Student struct{
    FirstName string 
    LastName  string
}

type Company struct{
    Name string `json:"name"`
    Address  string `json:"address"`
}

//initialize
student := Student{FirstName:"Burak", LastName:"Seyhan"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your application has already it. You don't run go get -u command.&lt;/p&gt;

&lt;h1&gt;
  
  
  Marshal()
&lt;/h1&gt;

&lt;p&gt;Converting Go objects into JSON is called Marshal() in GoLang. As the JSON is a language-independent data format.&lt;br&gt;
&lt;/p&gt;

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

import (
    "fmt"
    "encoding/json"
)

type Student struct{
    FirstName string
    LastName  string
}

func main()  {
    fmt.Println("Welcome to Json and Struct Implementation")

    //initialize
    student := Student{FirstName:"Burak", LastName:"Seyhan"}

    data, err := json.Marshal(student)
    if(err != nil){
        fmt.Println(err)
    }

    fmt.Println(data) // data is byteArray
    fmt.Println(string(data)) convert to byteArray to string
}   

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

&lt;/div&gt;



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

&lt;h1&gt;
  
  
  UnMarshal()
&lt;/h1&gt;

&lt;p&gt;Unmarshalling just opposite of Marshal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var unmarshalStudent Student
unmarshal := json.Unmarshal([]byte(data), &amp;amp;unmarshalStudent)

if(unmarshal != nil){
    fmt.Println(unmarshal)
}

fmt.Printf("%v+\n", data)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Full code&lt;br&gt;
&lt;/p&gt;

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

import (
    "fmt"
    "encoding/json"
)

type Student struct{
    FirstName string `json:"firtname"`
    LastName  string `json:"lastnamename"`
}


func main()  {
    fmt.Println("Welcome to Json and Struct Implementation")


    //initialize
    student := Student{FirstName:"Burak", LastName:"Seyhan"}

    data, err := json.Marshal(student)
    if(err != nil){
        fmt.Println(err)
    }

    fmt.Println(data)
    fmt.Println(string(data))


    var unmarshalStudent Student
    unmarshal := json.Unmarshal([]byte(data), &amp;amp;unmarshalStudent)
    if(unmarshal != nil){
        fmt.Println(unmarshal)
    }
    fmt.Printf("%v+\n", data)

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Real world example
&lt;/h1&gt;

&lt;p&gt;In this example I'll request a public Web API. &lt;a href="https://jsonplaceholder.typicode.com/users" rel="noopener noreferrer"&gt;PublicAPI&lt;/a&gt; This end point related with some user informations. At the beginning I'm gonna create a Struct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Users struct{
    Id int `json:"id"`
    Name  string `json:"name"`
    UserName  string `json:"username"`
    Email  string `json:"email"`
    Address  Address `json:"address"`
    Phone  string `json:"phone"`
    Website  string `json:"website"`
    Company  Company `json:"company"`
}

type Address struct{
    Street  string `json:"street"`
    Suite  string `json:"suite"`
    City  string `json:"city"`
    Zipcode  string `json:"zipcode"`
}

type Company struct{
    Name  string `json:"name"`
    CatchPhrase  string `json:"catchPhrase"`
    Bs  string `json:"bs"`
}

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

&lt;/div&gt;



&lt;p&gt;Next step is creating a web request. &lt;a href="https://pkg.go.dev/net/http" rel="noopener noreferrer"&gt;About net/http&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    //endpoint
    url := "https://jsonplaceholder.typicode.com/users"

    //create a client
    client := http.Client{
        Timeout: time.Second * 2, // Timeout after 2 seconds
    }

    //prepera new request s
    req, err := http.NewRequest(http.MethodGet, url, nil)
    if(err != nil){
        fmt.Println(err)
    }

    result , getErr:= client.Do(req)
    if(getErr != nil){
        fmt.Println(getErr)
    }
    fmt.Println(result)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The defer keyword which executes result.Body.Close() at the end of the function is used to close the response body.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(result.Body != nil){
        defer result.Body.Close()
    }

    body, _ := ioutil.ReadAll(result.Body)

    users := []Users{} // declare array cause Json data is array

    jsonErr := json.Unmarshal(body, &amp;amp;users)

    if(jsonErr != nil){
        fmt.Println(jsonErr)
    }

    for _, data := range users{
        fmt.Println(data)
    }

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

&lt;/div&gt;



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

&lt;h3&gt;
  
  
  packages
&lt;/h3&gt;

&lt;p&gt;These packages are loaded by default you don't need a go get command&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"fmt"&lt;/li&gt;
&lt;li&gt;"net/http"&lt;/li&gt;
&lt;li&gt;"time"&lt;/li&gt;
&lt;li&gt;"io/ioutil"&lt;/li&gt;
&lt;li&gt;"encoding/json"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;"fmt" package using for display some information or get any inputs from client but if you don't wanna use "fmt" code is Println("") because GoLang come with default packages. "net/http" packages is Web Request packages same as "fmt" package. "time" packages related to time information like DateTime. In this example doesn't need to this. You don't have to set Timeout actually it depends on. To get the response we are interested in, we have to access the Body property why we use "io/ioutil" packages. "encoding/json" packages related with marshal and unmarshal functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Another usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;url := "https://jsonplaceholder.typicode.com/users"

resp, err := http.Get(url)
if err != nil {
   fmt.Println(err)
}

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
    fmt.Println(err)
}

fmt.Println(string(body))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run &lt;code&gt;go run main.go&lt;/code&gt; see results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "username": "Antonette",
    "email": "Shanna@melissa.tv",
    "address": {
      "street": "Victor Plains",
      "suite": "Suite 879",
      "city": "Wisokyburgh",
      "zipcode": "90566-7771",
      "geo": {
        "lat": "-43.9509",
        "lng": "-34.4618"
      }
    },
    "phone": "010-692-6593 x09125",
    "website": "anastasia.net",
    "company": {
      "name": "Deckow-Crist",
      "catchPhrase": "Proactive didactic contingency",
      "bs": "synergize scalable supply-chains"
    }
  },
  {
    "id": 3,
    "name": "Clementine Bauch",
    "username": "Samantha",
    "email": "Nathan@yesenia.net",
    "address": {
      "street": "Douglas Extension",
      "suite": "Suite 847",
      "city": "McKenziehaven",
      "zipcode": "59590-4157",
      "geo": {
        "lat": "-68.6102",
        "lng": "-47.0653"
      }
    },
    "phone": "1-463-123-4447",
    "website": "ramiro.info",
    "company": {
      "name": "Romaguera-Jacobson",
      "catchPhrase": "Face to face bifurcated interface",
      "bs": "e-enable strategic applications"
    }
  },
  {
    "id": 4,
    "name": "Patricia Lebsack",
    "username": "Karianne",
    "email": "Julianne.OConner@kory.org",
    "address": {
      "street": "Hoeger Mall",
      "suite": "Apt. 692",
      "city": "South Elvis",
      "zipcode": "53919-4257",
      "geo": {
        "lat": "29.4572",
        "lng": "-164.2990"
      }
    },
    "phone": "493-170-9623 x156",
    "website": "kale.biz",
    "company": {
      "name": "Robel-Corkery",
      "catchPhrase": "Multi-tiered zero tolerance productivity",
      "bs": "transition cutting-edge web services"
    }
  },
  {
    "id": 5,
    "name": "Chelsey Dietrich",
    "username": "Kamren",
    "email": "Lucio_Hettinger@annie.ca",
    "address": {
      "street": "Skiles Walks",
      "suite": "Suite 351",
      "city": "Roscoeview",
      "zipcode": "33263",
      "geo": {
        "lat": "-31.8129",
        "lng": "62.5342"
      }
    },
    "phone": "(254)954-1289",
    "website": "demarco.info",
    "company": {
      "name": "Keebler LLC",
      "catchPhrase": "User-centric fault-tolerant solution",
      "bs": "revolutionize end-to-end systems"
    }
  },
  {
    "id": 6,
    "name": "Mrs. Dennis Schulist",
    "username": "Leopoldo_Corkery",
    "email": "Karley_Dach@jasper.info",
    "address": {
      "street": "Norberto Crossing",
      "suite": "Apt. 950",
      "city": "South Christy",
      "zipcode": "23505-1337",
      "geo": {
        "lat": "-71.4197",
        "lng": "71.7478"
      }
    },
    "phone": "1-477-935-8478 x6430",
    "website": "ola.org",
    "company": {
      "name": "Considine-Lockman",
      "catchPhrase": "Synchronised bottom-line interface",
      "bs": "e-enable innovative applications"
    }
  },
  {
    "id": 7,
    "name": "Kurtis Weissnat",
    "username": "Elwyn.Skiles",
    "email": "Telly.Hoeger@billy.biz",
    "address": {
      "street": "Rex Trail",
      "suite": "Suite 280",
      "city": "Howemouth",
      "zipcode": "58804-1099",
      "geo": {
        "lat": "24.8918",
        "lng": "21.8984"
      }
    },
    "phone": "210.067.6132",
    "website": "elvis.io",
    "company": {
      "name": "Johns Group",
      "catchPhrase": "Configurable multimedia task-force",
      "bs": "generate enterprise e-tailers"
    }
  },
  {
    "id": 8,
    "name": "Nicholas Runolfsdottir V",
    "username": "Maxime_Nienow",
    "email": "Sherwood@rosamond.me",
    "address": {
      "street": "Ellsworth Summit",
      "suite": "Suite 729",
      "city": "Aliyaview",
      "zipcode": "45169",
      "geo": {
        "lat": "-14.3990",
        "lng": "-120.7677"
      }
    },
    "phone": "586.493.6943 x140",
    "website": "jacynthe.com",
    "company": {
      "name": "Abernathy Group",
      "catchPhrase": "Implemented secondary concept",
      "bs": "e-enable extensible e-tailers"
    }
  },
  {
    "id": 9,
    "name": "Glenna Reichert",
    "username": "Delphine",
    "email": "Chaim_McDermott@dana.io",
    "address": {
      "street": "Dayna Park",
      "suite": "Suite 449",
      "city": "Bartholomebury",
      "zipcode": "76495-3109",
      "geo": {
        "lat": "24.6463",
        "lng": "-168.8889"
      }
    },
    "phone": "(775)976-6794 x41206",
    "website": "conrad.com",
    "company": {
      "name": "Yost and Sons",
      "catchPhrase": "Switchable contextually-based project",
      "bs": "aggregate real-time technologies"
    }
  },
  {
    "id": 10,
    "name": "Clementina DuBuque",
    "username": "Moriah.Stanton",
    "email": "Rey.Padberg@karina.biz",
    "address": {
      "street": "Kattie Turnpike",
      "suite": "Suite 198",
      "city": "Lebsackbury",
      "zipcode": "31428-2261",
      "geo": {
        "lat": "-38.2386",
        "lng": "57.2232"
      }
    },
    "phone": "024-648-3804",
    "website": "ambrose.net",
    "company": {
      "name": "Hoeger LLC",
      "catchPhrase": "Centralized empowering task-force",
      "bs": "target end-to-end models"
    }
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/bburaksseyhan/workingjson.git" rel="noopener noreferrer"&gt;Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>go</category>
      <category>tutorial</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Golang with database operations</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Sun, 31 Oct 2021 18:27:41 +0000</pubDate>
      <link>https://forem.com/burrock/golang-with-database-operations-3jl0</link>
      <guid>https://forem.com/burrock/golang-with-database-operations-3jl0</guid>
      <description>&lt;p&gt;Hi all,&lt;/p&gt;

&lt;p&gt;In this post I'm going to show you how to use PostgreSQL with GoLang. Briefly I'll introduce history of GoLang. Actually you can find more than one different document about history of GoLang however I found it on a nicely explained site. &lt;a href="https://www.geeksforgeeks.org/go-programming-language-introduction/" rel="noopener noreferrer"&gt;History&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've experienced .Net Core stack however I've been learning GoLang for 3 months. I believed that GoLang is very powerful and smooth language. I think we'll go head with steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1. &lt;a href="https://docs.docker.com/get-docker/" rel="noopener noreferrer"&gt;Install Docker&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Step 2. Run PostgreSQL container
&lt;/h3&gt;



&lt;p&gt;&lt;code&gt;docker run --name postgresql-container -p 5432:5432 -e POSTGRES_PASSWORD=Password! -d postgres;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Step 3. Run Database Script
&lt;/h3&gt;



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

-- DROP TABLE public.users;

CREATE TABLE public.users (
    firstname varchar NULL,
    lastname varchar NULL,
    id serial NOT NULL
);

Insert Into public.Users(firstname,lastname) values("FirstName-1","LastName-1")
Insert Into public.Users(firstname,lastname) values("FirstName-2","LastName-2")
Insert Into public.Users(firstname,lastname) values("FirstName-3","LastName-3")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4. Create new GoLang Solution
&lt;/h3&gt;

&lt;p&gt;There are different IDE's development code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VSCode&lt;/li&gt;
&lt;li&gt;Vim-go&lt;/li&gt;
&lt;li&gt;Atom&lt;/li&gt;
&lt;li&gt;Sublime&lt;/li&gt;
&lt;li&gt;LiteIDE
For more information &lt;a href="https://golang.org/doc/editors" rel="noopener noreferrer"&gt;GoLang Official&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;According to my habit, Visual Studio Code is quite suitable for me. Now Install the extension of GoLang. &lt;a href="https://code.visualstudio.com/docs/languages/go" rel="noopener noreferrer"&gt;Go Extension&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Packages:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Web framework: go get -u github.com/labstack/echo/v4&lt;/li&gt;
&lt;li&gt;Read Configuration file : go get -u github.com/spf13/viper&lt;/li&gt;
&lt;li&gt;Logging : go get -u github.com/sirupsen/logrus&lt;/li&gt;
&lt;li&gt;PostgreSQL : go get -u github.com/lib/pq&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Let's look at the project structure
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;cmd&amp;gt;api : include with config file and initialization like Startup.cs&lt;/li&gt;
&lt;li&gt;cmd&amp;gt;utils: configuration struct&lt;/li&gt;
&lt;li&gt;pkg&amp;gt;api : include with middleware and routing also register with handlers&lt;/li&gt;
&lt;li&gt;pkg&amp;gt;entities: database entities&lt;/li&gt;
&lt;li&gt;pkg&amp;gt;handlers: related with request&amp;amp;response type also interact with repository layer&lt;/li&gt;
&lt;li&gt;pkg&amp;gt;models : api response datas&lt;/li&gt;
&lt;li&gt;pkg&amp;gt;repository: related with database operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I run a &lt;code&gt;go run main.go&lt;/code&gt; this project starts with a cmd&amp;gt;api layer. This layer read a configuration parameters after that registered middleware and routings. &lt;/p&gt;

&lt;p&gt;Let's connect to database. This function take postgresCustomerRepository parameter and return *sql.DB pointer. This method related with Open connection and check the connection status with Ping command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func openDatabaseConn(r *postgresCustomerRepository) *sql.DB {
    db, err := sql.Open("postgres", r.conn)
    if err != nil {
        log.Error("Connection failed")
    }

    pingError := db.Ping()
    if pingError != nil {
        log.Error("Ping != pong")
    }

    log.Info("Postgres connection success!!!")

    return db
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add method
&lt;/h3&gt;

&lt;p&gt;$1 and $2 hold the argument of struct. In the older numeric approach, arguments are referenced using the syntax $n: $1 refers to the first input argument, $2 to the second, and so on. This will work whether or not the particular argument was declared with a name. [PostgreSQL][&lt;a href="https://www.postgresql.org/docs/9.5/xfunc-sql.html" rel="noopener noreferrer"&gt;https://www.postgresql.org/docs/9.5/xfunc-sql.html&lt;/a&gt;]&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    db := openDatabaseConn(r)
    defer db.Close()

    //add data
    query := "Insert into Users(FirstName, LastName) values($1,$2)"
    if _, err := db.ExecContext(ctx, query, customer.FirstName, customer.LastName); err != nil {
        return customer, err
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  List method
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    //connect database
    db := openDatabaseConn(r)
    defer db.Close()

    //read data from server
    rows, _ := db.QueryContext(ctx, "Select id,firstname,lastname from Users")
    defer rows.Close()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Delete method
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db := openDatabaseConn(r)
    defer db.Close()

    query := "Delete From Users Where Id=$1"
    affectedRow, err := db.ExecContext(ctx, query, id)
    if err != nil {
        return false, nil
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get one
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db := openDatabaseConn(r)
    defer db.Close()

    data := db.QueryRowContext(ctx, "Select id,firstname,lastname from Users Where Id=$1", id)

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

&lt;/div&gt;



&lt;p&gt;customerRepository.go file&lt;br&gt;
&lt;/p&gt;

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

import (
    "context"
    "database/sql"
    "fmt"
    "time"

    "github.com/bburaksseyhan/ctmapp/src/cmd/utils"
    "github.com/bburaksseyhan/ctmapp/src/pkg/entities"

    _ "github.com/lib/pq"
    log "github.com/sirupsen/logrus"
)

type CustomerRepository interface {
    List(cntxt context.Context, timeout int) ([]entities.CustomerEntity, error)
    Add(customer entities.CustomerEntity, cntxt context.Context, timeout int) (entities.CustomerEntity, error)
    Delete(id int, cntxt context.Context, timeout int) (bool, error)
    Get(id int, cntxt context.Context, timeout int) (entities.CustomerEntity, error)
}

type postgresCustomerRepository struct {
    dbSetting *utils.DbSettings
    conn      string
}

func NewPostgresCustomerRepository(dbSettings *utils.DbSettings) CustomerRepository {
    //initial log formatter
    log.SetFormatter(&amp;amp;log.JSONFormatter{})

    repo := &amp;amp;postgresCustomerRepository{
        dbSetting: dbSettings,
        conn: fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
            dbSettings.Host, dbSettings.Port, dbSettings.User, dbSettings.Password, dbSettings.DbName),
    }

    return repo
}

func (r *postgresCustomerRepository) List(cntxt context.Context, timeout int) ([]entities.CustomerEntity, error) {

    //context
    ctx, cancel := context.WithTimeout(cntxt, time.Duration(timeout)*time.Second)
    defer cancel()

    //connect database
    db := openDatabaseConn(r)
    defer db.Close()

    //read data from server
    rows, _ := db.QueryContext(ctx, "Select id,firstname,lastname from Users")
    defer rows.Close()

    //define slice for store customer information
    var customerEntity []entities.CustomerEntity

    //read data row by row
    for rows.Next() {
        var userId int
        var firstName string
        var lastName string

        _ = rows.Scan(&amp;amp;userId, &amp;amp;firstName, &amp;amp;lastName)

        customerEntity = append(customerEntity, entities.CustomerEntity{Id: userId, FirstName: firstName, LastName: lastName})
    }

    return customerEntity, nil
}

func (r *postgresCustomerRepository) Add(customer entities.CustomerEntity, cntxt context.Context, timeout int) (entities.CustomerEntity, error) {

    ctx, cancel := context.WithTimeout(cntxt, time.Duration(timeout)*time.Second)
    defer cancel()

    db := openDatabaseConn(r)
    defer db.Close()

    //add data
    query := "Insert into Users(FirstName, LastName) values($1,$2)"
    if _, err := db.ExecContext(ctx, query, customer.FirstName, customer.LastName); err != nil {
        return customer, err
    }

    return customer, nil
}

func (r *postgresCustomerRepository) Delete(id int, cntxt context.Context, timeout int) (bool, error) {

    ctx, cancel := context.WithTimeout(cntxt, time.Duration(timeout)*time.Second)
    defer cancel()

    db := openDatabaseConn(r)
    defer db.Close()

    query := "Delete From Users Where Id=$1"
    affectedRow, err := db.ExecContext(ctx, query, id)
    if err != nil {
        return false, nil
    }

    fmt.Println(affectedRow.LastInsertId())
    fmt.Println(affectedRow.RowsAffected())

    return true, nil
}

func (r *postgresCustomerRepository) Get(id int, cntxt context.Context, timeout int) (entities.CustomerEntity, error) {

    ctx, cancel := context.WithTimeout(cntxt, time.Duration(timeout)*time.Second)
    defer cancel()

    db := openDatabaseConn(r)
    defer db.Close()

    data := db.QueryRowContext(ctx, "Select id,firstname,lastname from Users Where Id=$1", id)

    var userId int
    var firstName string
    var lastName string

    _ = data.Scan(&amp;amp;userId, &amp;amp;firstName, &amp;amp;lastName)

    return entities.CustomerEntity{Id: userId, FirstName: firstName, LastName: lastName}, nil
}

func openDatabaseConn(r *postgresCustomerRepository) *sql.DB {
    db, err := sql.Open("postgres", r.conn)
    if err != nil {
        log.Error("Connection failed")
    }

    pingError := db.Ping()
    if pingError != nil {
        log.Error("Ping != pong")
    }

    log.Info("Postgres connection success!!!")

    return db
}

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Test
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;go run main.go&lt;/code&gt;&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Routings
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    e.GET("/health", customerHandler.Health)

    e.GET("/api/v1/customer", customerHandler.List)
    e.POST("/api/v1/customer", customerHandler.Add)
    e.DELETE("/api/v1/customer/:id", customerHandler.Delete)
    e.GET("api/v1/customer/:id", customerHandler.Get)

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create User
&lt;/h4&gt;

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

&lt;h4&gt;
  
  
  List Users
&lt;/h4&gt;

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

&lt;h4&gt;
  
  
  Get by id
&lt;/h4&gt;

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

&lt;h4&gt;
  
  
  Delete
&lt;/h4&gt;

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

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

&lt;p&gt;&lt;a href="https://github.com/bburaksseyhan/cmtapp.git" rel="noopener noreferrer"&gt;Repository&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

</description>
      <category>go</category>
      <category>postgres</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Pdf Converter</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Thu, 07 Jan 2021 19:08:36 +0000</pubDate>
      <link>https://forem.com/burrock/pdf-converter-3g8b</link>
      <guid>https://forem.com/burrock/pdf-converter-3g8b</guid>
      <description>&lt;p&gt;If you need a nice pdf convertor NuGet packages here is the good one. You can use with .net framework and .net core&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.nuget.org/packages/Select.HtmlToPdf.NetCore/" rel="noopener noreferrer"&gt;Select.HtmlToPdf.NetCore&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sample code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HtmlToPdf converter = new HtmlToPdf();
PdfDocument doc = converter.ConvertUrl(url);
doc.Save("Book" + "_" + page + ".pdf");
doc.Close();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Happy coding days  &lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>PostgreSQL with EF Part II</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Wed, 06 Jan 2021 17:24:49 +0000</pubDate>
      <link>https://forem.com/burrock/postgresql-with-ef-part-ii-5cf</link>
      <guid>https://forem.com/burrock/postgresql-with-ef-part-ii-5cf</guid>
      <description>&lt;p&gt;Before you read this article, I advise you to read the &lt;a href="https://dev.to/bseyhan/postgresql-with-ef-35fo"&gt;first part&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes some developer needs multiple contexts of our project. This is a little different than a single context. Multiple contexts mean multiple database context. That means is direct to the constructor. In this project, I need authentication and JWT token implementation. So I would like to use Microsoft Identity Server &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-5.0&amp;amp;tabs=netcore-cli" rel="noopener noreferrer"&gt;Document&lt;/a&gt; and I want to store a registered user in a database. Here is the problem I need a new context without CommunityContext. But how? At the same time, I ask myself what is the migration commands for every context. Let me explain.&lt;/p&gt;

&lt;p&gt;Create new context and call "AppIdentityDbContext". Every single context include own options like &lt;strong&gt;DbContextOptions&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;using Core.Entities.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace Infrastructure.Identity
{
    public class AppIdentityDbContext : IdentityDbContext&amp;lt;AppUser&amp;gt;
    {
        public AppIdentityDbContext(DbContextOptions&amp;lt;AppIdentityDbContext&amp;gt; options) :
            base(options)
        {
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AppUser.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public string DisplayName { get; set; }

public bool IsActive { get; set; } 

public bool IsWantToAuthor { get; set; }

public bool IsAuthor { get; set; }

public UserType UserType { get; set; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the second database context &lt;strong&gt;DbContextOptions options&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;using Core.Entities;
using Core.Entities.Identity;
using Microsoft.EntityFrameworkCore;

namespace Infrastructure
{
    public class CommunityContext : DbContext
    {
        public CommunityContext(DbContextOptions&amp;lt;CommunityContext&amp;gt; options) : base(options)
        {
        }

        public DbSet&amp;lt;Article&amp;gt; Articles { get; set; }

        public DbSet&amp;lt;Users&amp;gt; Users { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/ef/core/dbcontext-configuration/" rel="noopener noreferrer"&gt;DbContext&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unlike single context migration commands, multiple contexts command a little complicated. You have to specify the context name.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create Migration(example of CommunityContext)&lt;br&gt;
&lt;code&gt;dotnet ef migrations add Initial -p Infrastructure/ -s API -o Data/Migrations -c CommunityContext&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Migration(example of CommunityContext)&lt;br&gt;
&lt;code&gt;dotnet ef database update -p Infrastructure/ -s API -c CommunityContext&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnvvaar5k2qn198lqnkmo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnvvaar5k2qn198lqnkmo.png" alt="Screen Shot 2021-01-06 at 8.16.26 PM" width="800" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create Migration(example of AppIdentityDbContext)&lt;br&gt;
&lt;code&gt;dotnet ef migrations add IdentityInitial -p Infrastructure -s API -o Identity/Migrations -c AppIdentityDbContext&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Migration(example of AppIdentityDbContext)&lt;br&gt;
&lt;code&gt;dotnet ef database update -p Infrastructure -s API -c AppIdentityDbContext&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fisqng21yuwrdz2rat9s1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fisqng21yuwrdz2rat9s1.png" alt="Screen Shot 2021-01-06 at 8.20.23 PM" width="800" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open the query editor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fubdw0ycdp7vfel127wy4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fubdw0ycdp7vfel127wy4.png" alt="Screen Shot 2021-01-06 at 8.22.19 PM" width="267" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you 🧑🏻‍💻&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>entityframework</category>
    </item>
    <item>
      <title>PostgreSQL with EF</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Fri, 01 Jan 2021 18:10:04 +0000</pubDate>
      <link>https://forem.com/burrock/postgresql-with-ef-35fo</link>
      <guid>https://forem.com/burrock/postgresql-with-ef-35fo</guid>
      <description>&lt;p&gt;Happy new year ladies and gentlemen. Today is the first day of the 2021 year and vacation day. I prepare new study topics for myself every year and plan to write projects. In this post, you will learn how to use PostgreSQL with entity framework code first. Also, you will learn how to get docker image PostgreSQL and install it. At the same time, you'll learn Entity Framework migrations after that write some basic queries in Visual Studio Code. Let's start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important: Please install Visual Studio Code and .Net Core 3.1 or the latest version.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Create Project
&lt;/h1&gt;

&lt;p&gt;Let's create a new Web API project. Here is the project structure. Also please install these packages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fggttia99b18bbl53mlkn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fggttia99b18bbl53mlkn.png" alt="Screen Shot 2021-01-01 at 7.55.26 PM" width="428" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also here is the appsettings.Development.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "ConnectionStrings": {
    "Postgre": "UserID=postgres;Password=123;Server=localhost;Port=5432;Database=Community;Integrated Security=true;Pooling=true;"
  }
}

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Migrations
&lt;/h1&gt;

&lt;p&gt;Create Initial Migration.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet ef migrations add InitialCreate -p Infrastructure/ -s API -o Data/Migrations&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;API :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore.Design&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Infrastructure: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore.Design&lt;/li&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore&lt;/li&gt;
&lt;li&gt;Microsoft.EntityFrameworkCore.Tools&lt;/li&gt;
&lt;li&gt;Npqsql.EntityFrameworkCore.PostgreSQL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's update the database. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet ef database update -p Infrastructure/ -s API&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you want to remove migration you can use this command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet ef migrations remove -p Infrastructure -s API&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open the terminal go to the project location&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff16c4xi88v0ts9lvhxde.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff16c4xi88v0ts9lvhxde.png" alt="Screen Shot 2021-01-01 at 7.59.43 PM" width="800" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you do not install "Microsoft.EntityFrameworkCore.Design" package you'll get this error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3i5x9q26iu4oq9uuoo3c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3i5x9q26iu4oq9uuoo3c.png" alt="Screen Shot 2021-01-01 at 8.01.18 PM" width="800" height="50"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's migrate our entity&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjyzuluhdhu0247e2ms1d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjyzuluhdhu0247e2ms1d.png" alt="Screen Shot 2021-01-01 at 8.03.11 PM" width="800" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this command, InitialMigration will be created&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffh41xxigvz4z4y1y922h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffh41xxigvz4z4y1y922h.png" alt="Screen Shot 2021-01-01 at 8.21.41 PM" width="790" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;then update database &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3v3r5rg9vhtwbn7c6ip5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3v3r5rg9vhtwbn7c6ip5.png" alt="Screen Shot 2021-01-01 at 8.20.13 PM" width="800" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Pull Image
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;docker pull postgres&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run --name postgres -e POSTGRES_PASSWORD="123" -d -p 5432:5432 -v /var/lib/postgresql/data  postgres&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;check docker image status&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpi0m7atunm64igr2m2wc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpi0m7atunm64igr2m2wc.png" alt="Screen Shot 2021-01-01 at 8.26.55 PM" width="800" height="62"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Install Query Editor
&lt;/h1&gt;

&lt;p&gt;I found a very useful tool for PostgreSQL&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ckolkman.vscode-postgres" rel="noopener noreferrer"&gt;Query Editor&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "label": "postgre",
  "host": "localhost",
  "user": "postgres",
  "port": 5432,
  "ssl": false,
  "database": "Community",
  "password": "123"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F80pm918jo6iek8hr6fpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F80pm918jo6iek8hr6fpc.png" alt="Screen Shot 2021-01-01 at 9.06.59 PM" width="544" height="1162"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Basic Queries
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;SELECT * FROM "Authors" LIMIT 1000;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk8u7mjyr0viazy7n40i9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk8u7mjyr0viazy7n40i9.png" alt="Screen Shot 2021-01-01 at 9.06.40 PM" width="800" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/bseyhan/postgresql-with-ef-part-ii-5cf"&gt;Part II&lt;/a&gt;&lt;br&gt;
Happy new year 🎄&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>docker</category>
    </item>
    <item>
      <title>The middleware</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Mon, 21 Dec 2020 19:30:36 +0000</pubDate>
      <link>https://forem.com/burrock/the-middleware-11e0</link>
      <guid>https://forem.com/burrock/the-middleware-11e0</guid>
      <description>&lt;p&gt;Hi everybody, &lt;/p&gt;

&lt;p&gt;I hope, you are feeling good today. Also, I'm good thanks. In this post, I'm gonna talk about the importance of system tracing. The main subject, I want to tell you in this post will be outside of the classical methods. Maybe you ask me what are you talking about? I'm talking about designing a custom log framework using different tech stacks. Today, I will create a new library, after that implemented a basic API. Here is the most important content is &lt;a href="https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures" rel="noopener noreferrer"&gt;meaning of architecture&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the I used technology stacks&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dotnet Core &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/introduction" rel="noopener noreferrer"&gt;More Information&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MediatR&lt;/li&gt;
&lt;li&gt;MassTransit &lt;/li&gt;
&lt;li&gt;RabbitMq&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why do we need tracing of the system?&lt;/p&gt;

&lt;p&gt;It does not make sense that I do say specific reasons. If we have domain size does not matter, we should trace them. I would like to specify, as the complexity of the domain increases, monitoring and interpreting the system decrease.&lt;/p&gt;

&lt;p&gt;I have seen that in small and medium-sized systems, logs are monitored without being written to databases and even kept in text files. It might seem to like normal but here is the biggest problem are it will be hard to identify the problem. Let's give an example. Just think about a domain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiq92a6z9fm0l48y3sy9l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiq92a6z9fm0l48y3sy9l.png" alt="Screen Shot 2020-12-21 at 2.31.18 PM" width="750" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This project about customer information. I created 2 API and 3 worker service. Each worker services applications provide a different service. Like register, login, notification, etc ...&lt;br&gt;
Also, each service has its own service log like warning, error, or information. Let's assume, every API and worker service write request and response logs write to disk. Any service stopped working after that I have to check the service logs. Firstly open the txt log files. After that search it with ctrl+f. This is a very bad situation. You do not have to spend a lot of effort. &lt;/p&gt;

&lt;p&gt;What should I do?&lt;/p&gt;

&lt;p&gt;Some companies buy software or some companies write their own solutions after that to implement. Let's give an example Nlog, Elmah, Graylog, SeriLog, DataDog.&lt;/p&gt;

&lt;p&gt;In this post, I would like to explain the following titles.&lt;/p&gt;
&lt;h1&gt;
  
  
  What is Middleware?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-5.0" rel="noopener noreferrer"&gt;More Information&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  What is MediatR?
&lt;/h1&gt;

&lt;p&gt;MediatR is an open-source project and an implementation of the mediator design pattern. The mediator design pattern controls how a set of objects communicate and helps to reduce the number of dependencies among these objects that you must manage. In the mediator design pattern, objects don’t communicate with one another directly, but through a mediator. This article presents a discussion of how we can use MediatR in ASP.Net Core applications.&lt;br&gt;
&lt;a href="https://www.infoworld.com/article/3393974/how-to-use-mediatr-in-aspnet-core.html" rel="noopener noreferrer"&gt;More Information&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  What is MassTransit?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://masstransit-project.com/" rel="noopener noreferrer"&gt;More Information&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's open Visual Studio after that let's write some code.&lt;/p&gt;
&lt;h1&gt;
  
  
  Project Design and Packages
&lt;/h1&gt;

&lt;p&gt;I would like to create a framework that name is 'RequestTracer'. I designed 2 layers. Here is the folder structure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9ue3ac1tok924szxv1ad.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9ue3ac1tok924szxv1ad.png" alt="Screen Shot 2020-12-21 at 3.14.18 PM" width="788" height="490"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h1&gt;
  
  
  RequestTracer.Core layer
&lt;/h1&gt;

&lt;p&gt;Install the below nugget packages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuftrtnrh770ackxe0mis.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuftrtnrh770ackxe0mis.png" alt="Screen Shot 2020-12-21 at 3.15.39 PM" width="788" height="596"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Let's examine the codes in the file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Commands: It's about the MediatR request parameter and the return type is bool.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using MediatR;
using RequestTracer.Core.Dtos;

namespace RequestTracer.Core.Commands
{
    public class LogCommand : IRequest&amp;lt;bool&amp;gt;
    {
        public LogDto LogDtos { get; set; }
    }
}

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Dtos: It's about request and response parameters. Referenced to Commands.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;

namespace RequestTracer.Core.Dtos
{
    public class LogDto
    {
        public Guid Id { get { return Guid.NewGuid(); } }

        public DateTime Date { get { return DateTime.UtcNow; } }

        public string ApplicationName { get; set; }

        public string Environment { get; set; }

        public LogDetail LogDetail { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace RequestTracer.Core.Dtos
{
    public class LogDetail
    {
        public string Host { get; set; }

        public string Method { get; set; }

        public string Protocol { get; set; }

        public string Schema { get; set; }

        public string Path { get; set; }

        public string QueryStringParameter { get; set; }

        public int StatusCode { get; set; }

        public string ContentType { get; set; }

        public long? ContentLength { get; set; }

        public string ExecutionTime { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Handlers: It's about the MediatR. Every command has a handler. Every environment creates its own exchange.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Threading;
using System.Threading.Tasks;
using MassTransit;
using MediatR;
using Microsoft.Extensions.Configuration;
using RequestTracer.Core.Commands;

namespace RequestTracer.Core.Handlers
{
    public class LogCommandHandler : IRequestHandler&amp;lt;LogCommand, bool&amp;gt;
    {
        private readonly IBus _bus;
        private readonly IConfiguration _configuration;
        private readonly ISendEndpoint _sendEndpoint;

        public LogCommandHandler(IBus bus, IConfiguration configuration)
        {
            _bus = bus;
            _configuration = configuration;

            var environment = Environment.GetEnvironmentVariables()["ASPNETCORE_ENVIRONMENT"].ToString();

            _sendEndpoint = _bus.GetSendEndpoint(
                new Uri($"{_configuration.GetSection("RabbitMqSettings:server").Value}/{configuration.GetSection("ApplicationName").Value}-{environment}-Logs")).GetAwaiter().GetResult();
        }

        public async Task&amp;lt;bool&amp;gt; Handle(LogCommand request, CancellationToken cancellationToken)
        {
            await _sendEndpoint.Send(request);

            return true;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Middlewares: It's about request and response custom pipeline. Every single request goes through here without errors cause I only trace information logs.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Diagnostics;
using System.Threading.Tasks;
using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace RequestTracer.Core.Middlewares
{
    public class LogMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IMediator _mediator;
        private readonly IConfiguration _configuration;
        private readonly ILogger&amp;lt;LogMiddleware&amp;gt; _logger;

        public LogMiddleware(RequestDelegate next,
                             IMediator mediator,
                             IConfiguration configuration,
                             ILogger&amp;lt;LogMiddleware&amp;gt; logger)
        {
            _next = next ?? throw new ArgumentNullException(nameof(next));
            _mediator = mediator ?? throw new ArgumentNullException(nameof(next));
            _configuration = configuration ?? throw new ArgumentNullException(nameof(_configuration));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        public async Task Invoke(HttpContext httpContext)
        {
            try
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                await _next(httpContext);
                stopwatch.Stop();

                await SendRequest(httpContext, stopwatch);
            }
            catch (Exception ex)
            {
                _logger.LogError($"LogMiddleware {ex}");

                if (httpContext.Response.HasStarted)
                {
                    _logger.LogWarning("The response has already started");
                    throw;
                }
            }
        }

        private async Task SendRequest(HttpContext httpContext,Stopwatch stopwatch)
        {
            var request = httpContext.Request;
            var response = httpContext.Response;

            await _mediator.Send(new Commands.LogCommand()
            {
                LogDtos = new Dtos.LogDto()
                {
                    ApplicationName = _configuration.GetSection("ApplicationName").Value,
                    Environment = Environment.GetEnvironmentVariables()["ASPNETCORE_ENVIRONMENT"].ToString(),
                    LogDetail = new Dtos.LogDetail()
                    {
                        Host = request.Host.HasValue ? request.Host.ToString() : string.Empty,
                        Method = request.Method,
                        Protocol = request.Protocol,
                        Schema = request.Scheme,
                        Path = request.Path,
                        QueryStringParameter = request.QueryString.HasValue == true ? request.QueryString.Value : string.Empty,
                        StatusCode = response.StatusCode,
                        ContentType = response.ContentType,
                        ContentLength = request.ContentLength,
                        ExecutionTime = $"Execution time of {stopwatch.ElapsedMilliseconds} ms"
                    }
                }
            });
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Another one is an extension class here is the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Builder;
using RequestTracer.Core.Middlewares;

namespace RequestTracer.Core
{
    public static class MiddlewareExtensions
    {
        public static IApplicationBuilder UseCustomMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware&amp;lt;LogMiddleware&amp;gt;();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  RequestTracer.Infrastructure.IoC:
&lt;/h1&gt;

&lt;p&gt;Install the below nugget packages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnbacqepks4dsicxjmvo7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnbacqepks4dsicxjmvo7.png" alt="Screen Shot 2020-12-21 at 3.16.13 PM" width="788" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  DependencyContainer.cs
&lt;/h1&gt;

&lt;p&gt;This class referenced to API. At the same time, this class related to setup information like dependency injections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using MassTransit;
using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using RequestTracer.Core.Commands;

namespace RequestTracer.Infrastructure.IoC
{
    public static class DependencyContainer
    {
        public static void RegisterService(IServiceCollection services, IConfiguration configuration)
        {
            #region IoC layer
            services.AddMediatR(typeof(LogCommand));

            //mass transit configuration
            services.AddMassTransit(x =&amp;gt;
            {
                x.AddBus(provider =&amp;gt; Bus.Factory.CreateUsingRabbitMq(config =&amp;gt;
                {
                    config.UseHealthCheck(provider);
                    config.Host(new Uri(configuration.GetSection("RabbitMqSettings:host").Value), "/",
                    h =&amp;gt;
                    {
                        h.Heartbeat(TimeSpan.FromSeconds(30));
                        h.Username(configuration.GetSection("RabbitMqSettings:username").Value);
                        h.Password(configuration.GetSection("RabbitMqSettings:password").Value);
                    });

                }));
            });

            services.AddMassTransitHostedService();

            #endregion

            #region Database Layer
            #endregion

            #region Application Layer
            #endregion
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  API configuration
&lt;/h1&gt;

&lt;p&gt;I designed a Web API that name is "Customer.API". The important is, settings must be defined in the API layer for RabbitMq to work. Be careful! We have 3 different worker services and 2 web API. Each service has its own log queue. The distinctive thing is the name of the apps. If you define worker1,worker2, and worker3, you have 3 different queues. Evert worker service has its own environment variables like development, pre-production, or production. It means a different exchange.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"ApplicationName" :  "Customer.Api",
  "RabbitMqSettings": {
    "host": "rabbitmq://localhost",
    "server": "rabbitmq://localhost:15672",
    "username": "burki",
    "password": "123"
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please reference all layers to CustomerAPI application then open the Startup.cs. Let's define configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddSwaggerGen(c =&amp;gt;
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "CustomerApi", Version = "v1" });
            });

            DependencyContainer.RegisterService(services, Configuration);
        }

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c =&amp;gt; c.SwaggerEndpoint("/swagger/v1/swagger.json", "MonitorApi.Demo v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            _ = app.UseCustomMiddleware(); 

            app.UseEndpoints(endpoints =&amp;gt;
            {
                endpoints.MapControllers();
            });
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Install RabbitMQ
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Run the command&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;docker run -d --hostname my-rabbit --name myrabbit -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=123456 -p 5672:5672 -p 15672:15672 rabbitmq:3-management&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fowhzkggukp77msgvm6jb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fowhzkggukp77msgvm6jb.png" alt="Screen Shot 2020-12-21 at 8.37.51 PM" width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that start the RabbitMQ docker file with this command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run imageid&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7ionhdl7xgyh7szr7tp5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7ionhdl7xgyh7szr7tp5.png" alt="Screen Shot 2020-12-21 at 8.39.40 PM" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check the status &lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker ps&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwz0kyddv8xzijspu6duq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwz0kyddv8xzijspu6duq.png" alt="Screen Shot 2020-12-21 at 8.42.58 PM" width="800" height="18"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the browser go to the &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="http://localhost:15672/" rel="noopener noreferrer"&gt;http://localhost:15672/&lt;/a&gt;&lt;br&gt;
username: admin&lt;br&gt;
password: 123456&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftt3ie2p7od9zrq52c3j1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftt3ie2p7od9zrq52c3j1.png" alt="Screen Shot 2020-12-21 at 8.44.42 PM" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would like to create a new account. I'll set up username: burki and password: 123 and give permission. For this information, please open the Admin tab. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fihaj5vqxmzq5h41v7b53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fihaj5vqxmzq5h41v7b53.png" alt="Screen Shot 2020-12-21 at 8.47.49 PM" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the config result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy4b7xiydfr5mt8d07fci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy4b7xiydfr5mt8d07fci.png" alt="Screen Shot 2020-12-21 at 9.10.13 PM" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PS: If you do not declare a virtual host you'll get &lt;strong&gt;The agent is stopped or has been stopped, no additional provocateurs can be created&lt;/strong&gt; error&lt;/p&gt;

&lt;p&gt;Looks good. Let's test it.&lt;/p&gt;

&lt;p&gt;First of all, open the run the CustomerAPI and make some requests. Here is my controller class code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CustomerApi;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace MonitorApi.Demo.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class CustomerController : ControllerBase
    {
        private readonly ILogger&amp;lt;CustomerController&amp;gt; _logger;

        public CustomerController(ILogger&amp;lt;CustomerController&amp;gt; logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable&amp;lt;Customer&amp;gt; GetCustomers()
        {
            var customers = new List&amp;lt;Customer&amp;gt;();
            customers.Add(new Customer()
            {
                Id = 1,
                FirsName = "Burak",
                LastName = "Seyhan",
                City = "Ankara",
                EmailAddress = "burakseyhan8@gmail.com",
                Fax = string.Empty,
                Phone = "444"
            });
            customers.Add(new Customer()
            {
                Id = 2,
                FirsName = "User_FirstName",
                LastName = "User_LastName",
                City = "User_City",
                EmailAddress = "user@gmail.com",
                Fax = string.Empty,
                Phone = "User_PhoneNumber"
            });

            return customers;
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;Did you see it? I do not care about RabbitMQ configurations or another thing. I just only created a Web API method. I only care about appsettings.Development.json file that's all.&lt;/p&gt;

&lt;p&gt;Run the CustomerAPI then request GetCustomers() method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F01tij22znfiss2jw2oru.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F01tij22znfiss2jw2oru.png" alt="Screen Shot 2020-12-21 at 9.15.27 PM" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you request any method, our middleware catches all information and connects with the RabbitMQ here is the connection status.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foo9lvv1n3vefw8qg08lj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foo9lvv1n3vefw8qg08lj.png" alt="Screen Shot 2020-12-21 at 9.16.58 PM" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks good go head 🤟🏻&lt;/p&gt;

&lt;p&gt;Please open the Exchange tab. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fygutp4a2fdpewzkanexc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fygutp4a2fdpewzkanexc.png" alt="Screen Shot 2020-12-21 at 9.17.58 PM" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the "Customer.Api-Development-Logs" then you'll see a new window after that I'll configure it to the binding so choose to queue but make sure the queue is defined. Open Queue tab then creates a new queue and I called 'Customer.Api-Development-Logs'. Here is my queue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffte42ost7o10v3qvy6if.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffte42ost7o10v3qvy6if.png" alt="Screen Shot 2020-12-21 at 9.31.16 PM" width="800" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that bind Exchange to Queue. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy78ciglpmuz4ibjsbwa5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fy78ciglpmuz4ibjsbwa5.png" alt="Screen Shot 2020-12-21 at 9.32.29 PM" width="800" height="112"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's make a new request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F730wcd2vjzs77vm9hk5f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F730wcd2vjzs77vm9hk5f.png" alt="Screen Shot 2020-12-21 at 9.34.35 PM" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My request was reflected here &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbma6fhn4x4qo0d994fu4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbma6fhn4x4qo0d994fu4.png" alt="Screen Shot 2020-12-21 at 9.33.28 PM" width="800" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I haven't written a consumer yet. So let's look at the output you want, made manually. Again open the Queue tab then click the Get Messages button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgyxzs0was2scg7vhm5d8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgyxzs0was2scg7vhm5d8.png" alt="Screen Shot 2020-12-21 at 9.37.28 PM" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add new Order API then configure the appsettings.Development.json file same with previous.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "ApplicationName": "Order.Api",
  "RabbitMqSettings": {
    "host": "rabbitmq://localhost",
    "server": "rabbitmq://localhost:15672",
    "username": "burki",
    "password": "123"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fguyyz0pgtwbuda2qf2qx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fguyyz0pgtwbuda2qf2qx.png" alt="Screen Shot 2020-12-21 at 10.16.03 PM" width="800" height="574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's get test it.&lt;/p&gt;

&lt;p&gt;When you make a request Order API exchange created.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcd1z91eub9tgmqjw1rab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcd1z91eub9tgmqjw1rab.png" alt="Screen Shot 2020-12-21 at 10.23.16 PM" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyes86cdyu6r49yj6u06e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyes86cdyu6r49yj6u06e.png" alt="Screen Shot 2020-12-21 at 10.04.06 PM" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then create a queue then bind it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Filrsdi8semutj54suekg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Filrsdi8semutj54suekg.png" alt="Screen Shot 2020-12-21 at 10.06.35 PM" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the payload.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe1wm80ij8fo31wii8tk8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe1wm80ij8fo31wii8tk8.png" alt="Screen Shot 2020-12-21 at 10.07.11 PM" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every service has its own middleware. So Every middleware creates a single exchange. If I run the all workers you can see the worker exchanges.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqxhjbans1pxfh4d528is.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqxhjbans1pxfh4d528is.png" alt="Screen Shot 2020-12-21 at 10.23.16 PM" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a result,&lt;/p&gt;

&lt;p&gt;Logging mechanisms are separated by the application-based queue. In this way, the metrics of the requests and responses of each service can be easily analyzed within itself. &lt;br&gt;
Consumer applications to be written in addition to these applications and payload information can be easily displayed on the web screen interface. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bburaksseyhan/themiddleware.git" rel="noopener noreferrer"&gt;Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>csharp</category>
      <category>docker</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Benchmark Strings</title>
      <dc:creator>burak</dc:creator>
      <pubDate>Wed, 09 Dec 2020 10:27:58 +0000</pubDate>
      <link>https://forem.com/burrock/benchmark-strings-4j6f</link>
      <guid>https://forem.com/burrock/benchmark-strings-4j6f</guid>
      <description>&lt;p&gt;How much do you know string?&lt;/p&gt;

&lt;p&gt;Since when I started day developing code, generally use the string data type. They always ask questions about strings in every job interview. Especially the first times. Today I'll talk about how much do you know strings?&lt;/p&gt;

&lt;p&gt;Microsoft says: a string is an object of type String whole value is text. 👉 &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#:~:text=String%20objects%20are%20immutable%3A%20they,in%20a%20new%20string%20object." rel="noopener noreferrer"&gt;Microsoft&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Microsoft says: the string keyword is an alias for System.String; 👉 &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#:~:text=String%20objects%20are%20immutable%3A%20they,in%20a%20new%20string%20object." rel="noopener noreferrer"&gt;Microsoft&lt;/a&gt; &lt;/p&gt;

&lt;h1&gt;
  
  
  Let's declare and initialize strings
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Declare without initializing.
string username;

// Initialize to null.
string username = null;

// Initialize as an empty string.
string username = System.String.Empty;

// Initialize as an empty string with ""
string username = "";

// Initialize with a regular string literal.
string oldPath = "c:\\documents";

// Initialize with a verbatim string literal.
string newPath = @"c:\documents;

// Use System.String if you prefer.
System.String email = "burakseyhan8@gmail.com";

//string concanate
var title = "Hi";
var body = "Thank" + "you";
body = $"{body} for read";

MessageBox.Show("body");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If I need text data I have to use String. Or I got the current date if I wanna store the current date in the database I'll use ToString().&lt;/p&gt;

&lt;p&gt;Strings objects are immutable: Strings are can not be changed after they have been created. So let's write basic code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string firstName = "burak";
string lastName = "seyhan";

firstName += lastName;

Console.WriteLine(firstName);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#string-escape-sequences" rel="noopener noreferrer"&gt;Escape Sequence Characters&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Benchmark
&lt;/h1&gt;

&lt;p&gt;Player 1 : + operator&lt;br&gt;
Player 2 : String.Concat()&lt;br&gt;
Player 3 : StringBuilder&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;+ operator :&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Concatenate using with + operator. With + operator create a new string. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;text =  "Burak" + i.ToString();&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;String.Concat() :&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;String.Concat() function also allows to concatenate strings. You can pass all strings as function parameters.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;StringBuilder :&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;StringBuilder is a class that is useful to represent a mutable string of characters and it is an object of System.Text namespace. Strings are immutable and StringBuilder is mutable. Mutable means once an instance of the class is created, then the same instance will be used to perform any operations. Although the StringBuilder is a dynamic object that allows you to expand the number of characters in the string that it encapsulates, you can specify a value for the maximum number of characters that it can hold. This value is called the capacity of the StringBuilder object. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Method and Definitions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;StringBuilder.Append: This method will append the given string value to the end of the current StringBuilder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;StringBuilder.AppendFormat: It will replace a format specifier passed in a string with formatted text.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;StringBuilder.Insert: It inserts a string at the specified index of the current StringBuilder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;StringBuilder.Remove: It removes a specified number of characters from the current StringBuilder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;StringBuilder.Replace: It replaces a specified character at a specified index.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;StringBuilder and String.Concat differs in one critical point. When the String.Concat function is used, all strings to concatenate must be given as parameters. By using the StringBuilder class, these values ​​can be added step by step by calling the add function. &lt;/p&gt;

&lt;p&gt;Here is the rule. I create 3 players. Every player has their own specific role. Here is the rule. I create 3 players. Every player has their own specific role. Every player iterates 100000 times then all player's results writes on the screen.  &lt;/p&gt;

&lt;p&gt;Let's write some code here 👨🏻‍💻&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Diagnostics;
using System.Text;

namespace StringvsStringBuilder
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var count = 100000;
            string text = string.Empty;

            var stopWatch = Stopwatch.StartNew();

            /*
            Console.WriteLine("+ operator");
            for (int i = 0; i &amp;lt;= count; i++)
            {
                text = "burak " + string.Empty + i.ToString();
                Console.WriteLine(text);
            }

            Console.WriteLine($"Content: {text} Execution Time Of : {stopWatch.Elapsed.TotalMilliseconds}");
            stopWatch.Stop();
            Console.WriteLine("*********************");
            */

            /*
            Console.WriteLine("String.Concat");

            for (int i = 0; i &amp;lt;= count; i++)
            {
                String.Concat("burak", string.Empty, "seyhan", i.ToString());
            }
            stopWatch.Stop();
            Console.WriteLine($"Content: {text} Execution Time Of : {stopWatch.Elapsed.TotalMilliseconds}");
            Console.WriteLine("*********************");
            */


            Console.WriteLine("String Builder");
            var builder = new StringBuilder();
            for (int i = 0; i &amp;lt;= count; i++)
            {
                builder.Append("burak");
                builder.Append("");
                builder.AppendLine("seyhan");
                builder.AppendLine(i.ToString());
            }

            stopWatch.Stop();
            Console.WriteLine($"Content: {text} Execution Time Of : {stopWatch.Elapsed.TotalMilliseconds}");
            Console.WriteLine("*********************");


            Console.ReadKey();
            Console.WriteLine("Program finished");
        }
    }
}

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

&lt;/div&gt;



&lt;p&gt;Results:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;ul&gt;
&lt;li&gt;operator
Content: burak 100000 Execution Time Of: 3307.8574&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;String Concat&lt;br&gt;
Content: Execution Time Of: 222.8163&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;string builder&lt;br&gt;
Content: Execution Time Of: 178.1494&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🥇 🍾 is &lt;strong&gt;string builder&lt;/strong&gt; 👏🏻 👏🏻 👏🏻 &lt;/p&gt;

&lt;p&gt;Thank you for reading 🧑🏻‍💻&lt;/p&gt;

</description>
      <category>benchmark</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
