<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Deeshath</title>
    <description>The latest articles on DEV Community by Deeshath (@deeshath).</description>
    <link>https://dev.to/deeshath</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%2F1105975%2F193258dc-2d65-4629-b26b-6ab0e2652647.png</url>
      <title>DEV Community: Deeshath</title>
      <link>https://dev.to/deeshath</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deeshath"/>
    <language>en</language>
    <item>
      <title>Stop Chatting With Claude. Start Orchestrating It.</title>
      <dc:creator>Deeshath</dc:creator>
      <pubDate>Mon, 06 Apr 2026 09:47:15 +0000</pubDate>
      <link>https://dev.to/deeshath/stop-chatting-with-claude-start-orchestrating-it-1d93</link>
      <guid>https://dev.to/deeshath/stop-chatting-with-claude-start-orchestrating-it-1d93</guid>
      <description>&lt;p&gt;Most developers are using Claude Code like an expensive autocomplete. I run 3 features in parallel with it. Here's the exact setup.&lt;/p&gt;

&lt;p&gt;When I first started using Claude Code, I was doing the obvious thing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ask → Wait → Review → Repeat&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One task. One agent. One thread. Me, waiting.&lt;/p&gt;

&lt;p&gt;That's basically hiring a genius and making them work one ticket at a time while you watch.&lt;/p&gt;

&lt;p&gt;Here's what I actually do now — and why it's a completely different category of tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                YOU (Lead / Orchestrator)
                         │
        ┌────────────────┼────────────────┐
        │                │                │
   project-1/       project-2/       project-3/
   (Agent A)        (Agent B)        (Agent C)
   Feature A        Feature B        Feature C

Each:
- Own repo copy/ worktrees
- Own Claude session
- Own branch + state

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Mental Model That Changed Everything
&lt;/h2&gt;

&lt;p&gt;Claude Code isn't a chat assistant. It has full access to my repo. It reads files, runs commands, writes code, runs tests.&lt;/p&gt;

&lt;p&gt;Most people use it like a smarter Stack Overflow. The actual unlock is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm not writing code anymore. I'm an engineering lead coordinating a team of AI developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You stop being the person at the keyboard and start being the person deciding what gets built and whether it's right. The keyboard work? Delegated.&lt;/p&gt;

&lt;p&gt;That sounds abstract. Let me make it concrete by walking through my actual workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Be Clear on What and Why Before Anything Else
&lt;/h2&gt;

&lt;p&gt;Before I touch anything, I get my intent straight.&lt;/p&gt;

&lt;p&gt;I used to jump straight to implementation, and Claude would confidently build the wrong thing. Fast, clean, wrong. Like a contractor who builds the exact wall you described — in the wrong room.&lt;/p&gt;

&lt;p&gt;Now: I tell Claude exactly &lt;strong&gt;what&lt;/strong&gt; I want to build and &lt;strong&gt;why&lt;/strong&gt; — the business reason, the constraint, the goal. Not a formal spec doc, not a design review process. Just clarity. What problem are we solving, what does done look like, what are the constraints.&lt;/p&gt;

&lt;p&gt;Then I go straight to planning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned the hard way:&lt;/strong&gt; "Simple" tasks are exactly where unexamined assumptions cause the most wasted work. Two sentences of context upfront saves an hour of fixing the wrong implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Write a Plan Before Writing Code
&lt;/h2&gt;

&lt;p&gt;The plan says &lt;em&gt;how&lt;/em&gt; — exact file paths, exact code changes, nothing left to interpretation.&lt;/p&gt;

&lt;p&gt;A good plan looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task 1: Add user notification feature

Files:
- Modify: src/services/notification_service
- Modify: src/models/user

Changes:
- notification_service: add send_notification method
  [exact diff of what gets added]
- user model: add notification_preferences field
  [exact diff of what changes]

Verify: run tests, confirm passing
Commit: "feat: add user notification"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every file path is exact. Every change is shown as a diff — not described, shown. No ambiguity about what the agent is supposed to do.&lt;/p&gt;

&lt;p&gt;Think of it as writing sheet music, not just saying "play something jazzy." The agent follows the score.&lt;/p&gt;

&lt;p&gt;The plan also gets saved to &lt;code&gt;.claude/plans/&amp;lt;feature-name&amp;gt;.md&lt;/code&gt; — so if a session gets interrupted (laptop dies, connection drops, you accidentally close the tab like I definitely haven't done), the next session picks up exactly where things left off.&lt;/p&gt;

&lt;p&gt;A reviewer subagent reads the plan before execution starts. Its only job: find gaps, missing steps, anything that would cause an agent to get stuck. Fix, re-review, proceed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Isolate — And Know Which Isolation Method to Use
&lt;/h2&gt;

&lt;p&gt;Here's where most people hit a wall they don't understand. Turns out "just run it in parallel" is not a plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Git Worktrees — for a single isolated feature
&lt;/h3&gt;

&lt;p&gt;When I'm working on one feature that needs its own branch and clean state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git worktree add .worktrees/feature-auth &lt;span class="nt"&gt;-b&lt;/span&gt; feature/auth-refactor
&lt;span class="nb"&gt;cd&lt;/span&gt; .worktrees/feature-auth
&lt;span class="c"&gt;# install deps, run tests to verify clean baseline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The worktree gets its own directory and branch. Claude can commit, test, and experiment without touching my main working state. Lightweight, clean, no drama.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separate repo copies — for working on multiple features in parallel
&lt;/h3&gt;

&lt;p&gt;Git worktrees have a hard limitation people don't talk about: &lt;strong&gt;you can't run two worktrees in parallel without them stepping on each other.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Worktrees share the underlying git objects. Depending on your stack, this causes conflicts — shared process state, directory locks, test runs fighting over the same resources. Two agents, one worktree setup, instant chaos.&lt;/p&gt;

&lt;p&gt;I tried. It was not a fun afternoon.&lt;/p&gt;

&lt;p&gt;The solution: &lt;strong&gt;full repo copies.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ~/project ~/project-1
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ~/project ~/project-2
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ~/project ~/project-3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each copy is a completely independent environment. One agent building feature A, another building feature B, a third on feature C — all simultaneously, each with their own branch, their own state, their own everything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project/   → my main working copy
project-1/ → Agent working on feature A
project-2/ → Agent working on feature B
project-3/ → Agent working on feature C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While one agent is deep in feature A, I'm reviewing feature B's output. Feature C is running in the background. I'm never waiting on a single thread — and neither is any agent.&lt;/p&gt;

&lt;p&gt;To kick one off — open Claude Code in that copy's directory, point it to the plan file, and it runs from there. Each copy is a fully independent Claude Code session.&lt;/p&gt;

&lt;p&gt;When an agent finishes, I pull the diff out and raise a PR from that copy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why not just worktrees for this too?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Worktrees isolate at the branch level. Copies isolate at the process level. For parallel agents actively building and running tests, you need process-level isolation. Worktrees can't give you that — copies can.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule of thumb:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One feature, one agent, sequential → git worktree&lt;/li&gt;
&lt;li&gt;Multiple features, multiple agents, parallel → separate repo copies&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 4: How Each Agent Actually Works Inside a Copy
&lt;/h2&gt;

&lt;p&gt;Each repo copy has one Claude agent. That agent owns its feature end to end. It's not a junior dev you have to babysit — it's a senior dev who happens to need very explicit instructions and will do exactly what you say, for better or worse.&lt;/p&gt;

&lt;p&gt;Inside each copy, the agent follows the plan task by task. For each task, I dispatch a &lt;strong&gt;fresh subagent&lt;/strong&gt; with exactly what it needs: the task, the relevant context, the constraints, what to return. Nothing else.&lt;/p&gt;

&lt;p&gt;Fresh subagent per task = no context bleed. The agent on task 3 doesn't carry confusion from task 1. Every task starts sharp.&lt;/p&gt;

&lt;p&gt;After each task, two review gates before moving on:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gate 1 — Requirement compliance&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does the code match what was asked? Nothing missing, nothing extra?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the agent added something clever that wasn't asked for — out. If it skipped something required — back in. "Close enough" fails this gate every time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gate 2 — Code quality&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is the implementation actually well-built?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gate 2 only runs after Gate 1 passes. No point stress-testing the quality of something that built the wrong thing.&lt;/p&gt;

&lt;p&gt;Both gates are fresh subagents. Issues found → implementer fixes → reviewer re-checks. Loop until both approve, then next task. No shortcuts.&lt;/p&gt;

&lt;p&gt;Meanwhile, &lt;code&gt;project-2&lt;/code&gt; is running the exact same flow for a different feature. And &lt;code&gt;project-3&lt;/code&gt;. All simultaneously. All operating from the same coding standards — because each copy carries the full Claude config.&lt;/p&gt;

&lt;p&gt;This is the actual parallel. Not just running tests faster. Entire feature tracks shipping at the same time.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Thing That Makes All of This Work: CLAUDE.md + Skills
&lt;/h2&gt;

&lt;p&gt;Every agent I dispatch — every subagent, every reviewer, every parallel agent in every repo copy — reads my &lt;code&gt;CLAUDE.md&lt;/code&gt; before touching anything.&lt;/p&gt;

&lt;p&gt;It's the employee handbook for my AI team. Except unlike most employee handbooks, people actually follow this one.&lt;/p&gt;

&lt;p&gt;Mine covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architecture conventions (where things live, how they're structured)&lt;/li&gt;
&lt;li&gt;What's forbidden (patterns I've banned and exactly why)&lt;/li&gt;
&lt;li&gt;Testing strategy (what to test, what not to mock, how tests are structured)&lt;/li&gt;
&lt;li&gt;Key commands (how to run tests, lint, build)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since each repo copy is a full copy of the repo, it carries the full Claude config — &lt;code&gt;CLAUDE.md&lt;/code&gt; and all the domain skills configured for that codebase. Skills are reusable instruction sets that auto-trigger based on what you're working on — think of them as specialised playbooks Claude loads when it detects you're touching a specific part of the system.&lt;/p&gt;

&lt;p&gt;Every agent in every copy automatically gets the same standards, the same workflows, the same constraints. No setup per copy. No drift between agents.&lt;/p&gt;

&lt;p&gt;This is what keeps multiple agents consistent without me managing each one individually. They're not just isolated from each other — they're all working from the same rulebook.&lt;/p&gt;

&lt;p&gt;The rules I include aren't just &lt;em&gt;what&lt;/em&gt; — they explain &lt;em&gt;why&lt;/em&gt;. If Claude understands the reasoning, it makes better calls in gray areas instead of picking the most literal interpretation of your instructions and running with it off a cliff.&lt;/p&gt;

&lt;p&gt;What I cut: anything where I'd answer "removing this won't cause Claude to make mistakes." Every unnecessary line dilutes the signal.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Still Review Myself
&lt;/h2&gt;

&lt;p&gt;Claude Code is fast. It's not a mind reader, and it's not infallible.&lt;/p&gt;

&lt;p&gt;Things I always personally review, regardless of what review gates say:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authorization logic — never skip, never assume it's right&lt;/li&gt;
&lt;li&gt;Anything touching shared state across users or accounts&lt;/li&gt;
&lt;li&gt;Core business logic with real edge cases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two hard rules I enforce on every agent, no exceptions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No auto-commit.&lt;/strong&gt; Agents stage changes, present the diff, and wait for my explicit sign-off before anything touches git. I've seen agents commit mid-task with half-finished work. Hard no.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cleanup before done.&lt;/strong&gt; Any code added during a session that got replaced or made redundant during iteration gets deleted before the task closes. Agents leave behind ghost methods from earlier attempts like forgotten tabs in a browser. The rule: review everything added in the session, delete anything no longer used.&lt;/p&gt;

&lt;p&gt;AI-generated code can be confidently wrong. "Approved" from a reviewer subagent doesn't replace my eyes on critical paths.&lt;/p&gt;




&lt;h2&gt;
  
  
  What You Actually Walk Away With
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Apply these today — regardless of where you are with Claude Code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start with intent, not implementation.&lt;/strong&gt; Two sentences of what + why before any prompt saves you an hour of wrong output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLAUDE.md is your team's shared brain.&lt;/strong&gt; Set it up once. Every agent reads it. The more precise it is, the less you babysit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No auto-commit. No exceptions.&lt;/strong&gt; Agents stage, you approve, then it goes to git. You're the last line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Worktrees for one feature, repo copies for parallel ones.&lt;/strong&gt; Don't fight the tool. Each has a job — and conflating them is a bad afternoon.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Once you're running parallel agents
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plan with exact diffs, not descriptions.&lt;/strong&gt; Vague plans produce vague code. The agent follows the score — write the score.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fresh subagent per task.&lt;/strong&gt; Context bleed is real. Every task starts clean, focused, without baggage from the one before it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two review gates, always in order.&lt;/strong&gt; Right requirements first, then quality. Reviewing quality on the wrong feature is just polishing a mistake.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Actually Changed
&lt;/h2&gt;

&lt;p&gt;I used to be the bottleneck. I'd write code, review it, test it, fix it — all sequential, all me. One thread. Very human. Very slow.&lt;/p&gt;

&lt;p&gt;Now I design, delegate, and validate. I'm often waiting on myself to review output, not waiting on Claude to finish. That's a good problem to have.&lt;/p&gt;

&lt;p&gt;The actual unlock isn't "Claude writes faster code."&lt;/p&gt;

&lt;p&gt;It's: &lt;strong&gt;I stopped being the execution bottleneck and became the decision-maker.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The engineers are faster. The leverage is real. The judgment still has to come from you — and honestly, that's the interesting part of the job anyway.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;All patterns in this post come from my actual Claude Code setup — workflows and conventions I run daily on a production codebase.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;What's your current Claude Code setup? Still single-threaded or already running parallel? Drop it in the comments — curious what workflows people have settled on.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Database Sharding: Simplifying Data Scalability</title>
      <dc:creator>Deeshath</dc:creator>
      <pubDate>Sat, 09 Nov 2024 18:30:37 +0000</pubDate>
      <link>https://dev.to/deeshath/database-sharding-simplifying-data-scalability-5680</link>
      <guid>https://dev.to/deeshath/database-sharding-simplifying-data-scalability-5680</guid>
      <description>&lt;p&gt;Managing data at scale can be a bit like managing a massive library. Imagine your library started with a handful of books, and over time, it grew—slowly at first, then faster and faster until you found yourself lost in the aisles, wondering where to find &lt;em&gt;just one book&lt;/em&gt;. Adding more shelves (or servers) helps, but eventually, even more shelves won’t solve the problem. What you really need is a way to organize the books into manageable sections.&lt;/p&gt;

&lt;p&gt;That’s essentially what &lt;strong&gt;database sharding&lt;/strong&gt; does. When your database grows too large for a single server to handle, sharding divides the data into smaller, more manageable &lt;strong&gt;shards&lt;/strong&gt;, and these shards are distributed across multiple servers. This makes your system more efficient, faster, and scalable—like organizing the library by genre, so you can find the book you need without wandering for hours.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll explore the ins and outs of sharding, its different types, and how you can use it to build a more scalable system. Along the way, we’ll keep things simple, and hopefully make a somewhat dry subject a bit more fun to digest.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Database Sharding?
&lt;/h2&gt;

&lt;p&gt;Let’s say you’re the head librarian in a library (your database), and everything was smooth sailing when you only had a few thousand books. But as the collection grew, you noticed things starting to slow down—finding the right book became a challenge. Just like the library’s shelves, a single server can only hold so much data before things grind to a halt.&lt;/p&gt;

&lt;p&gt;To solve this, you break the collection up into smaller sections—&lt;strong&gt;shards&lt;/strong&gt;—so that each section (or shard) is easier to manage. Instead of searching through the entire library, you only need to search through the relevant section.&lt;/p&gt;

&lt;p&gt;This is exactly what happens with database sharding. It’s the process of dividing a large database into smaller, more manageable pieces (shards), which are then distributed across multiple servers. So, instead of one giant server struggling to handle everything, each shard lives on its own server. The system knows exactly where to look when you make a request for data, just like how a well-organized library catalog can point you to the right section of the library.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Shard a Database?
&lt;/h2&gt;

&lt;p&gt;Sharding is helpful when your database becomes too large for a single server to handle. Here are a few signs that it might be time to consider sharding:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Scalability&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As your data grows, a single server can’t handle all the traffic. Sharding allows you to scale your database horizontally, by distributing the data across multiple servers. It’s like expanding your library by adding multiple branches, each with its own set of books.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Performance&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With sharding, queries can be processed in parallel. Since the data is distributed across servers, your queries are more efficient, and the load is better balanced. This makes retrieving data faster—like sending multiple librarians to search for a book in different sections, instead of just one librarian running back and forth.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Availability&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If one shard goes down, the other shards are still functional. It’s like your library remaining open even if one section is temporarily closed for renovation. You don’t lose access to the entire collection when one server fails.&lt;/p&gt;




&lt;h2&gt;
  
  
  Types of Database Sharding
&lt;/h2&gt;

&lt;p&gt;When it comes to sharding, there are several methods you can use, depending on your data structure and access patterns. Let’s break down the four main types of sharding with examples and a bit of humor to keep you from falling asleep.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. &lt;strong&gt;Horizontal Sharding (Row-Based Sharding)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In &lt;strong&gt;horizontal sharding&lt;/strong&gt;, data is split by rows. Each shard holds a subset of the rows, typically based on a range of data, like user IDs or geographic regions. This works well when your data is uniform and can be evenly distributed across servers.&lt;/p&gt;

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

&lt;p&gt;Imagine you’re running a huge e-commerce platform with millions of users. You might split the user base like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shard 1&lt;/strong&gt;: Users with IDs 1–100,000&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shard 2&lt;/strong&gt;: Users with IDs 100,001–200,000&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shard 3&lt;/strong&gt;: Users with IDs 200,001–300,000&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, when a request comes in for user data with ID 150,000, the system knows exactly which shard to query. It's like organizing your library by genre, so if you’re looking for sci-fi books, you know exactly which section to head to.&lt;/p&gt;

&lt;h4&gt;
  
  
  When to Use Horizontal Sharding:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Growing datasets&lt;/strong&gt;: When your data grows beyond what a single server can handle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Applications with uniform data&lt;/strong&gt;: For instance, social media apps or blogs where each user's data is similar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-traffic systems&lt;/strong&gt;: E-commerce sites or news websites that handle tons of requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Real-World Example:
&lt;/h4&gt;

&lt;p&gt;A social media platform might use horizontal sharding to manage user profiles. Each shard could hold a different range of user IDs, so as the platform grows, it can scale efficiently.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. &lt;strong&gt;Vertical Sharding (Column-Based Sharding)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In &lt;strong&gt;vertical sharding&lt;/strong&gt;, data is split by columns instead of rows. Each shard holds a subset of the columns, often based on how the data is accessed or updated. This approach is useful when certain parts of your data are more frequently accessed than others.&lt;/p&gt;

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

&lt;p&gt;Imagine an online banking system with user accounts and transactions. You might organize the data into different shards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shard 1&lt;/strong&gt;: Stores user details (name, address, email)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shard 2&lt;/strong&gt;: Stores account balances and transaction history&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shard 3&lt;/strong&gt;: Stores login activity (last login time, IP address, session data)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this setup, frequently accessed data, like user information, is separated from less frequently accessed data, like login history, making everything faster and more efficient.&lt;/p&gt;

&lt;h4&gt;
  
  
  When to Use Vertical Sharding:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Different access patterns&lt;/strong&gt;: Some columns are used more often than others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mixed data types&lt;/strong&gt;: For example, you might store user info separately from transaction info.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frequent updates&lt;/strong&gt;: If some columns change more often than others, you might want to isolate them for performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Real-World Example:
&lt;/h4&gt;

&lt;p&gt;An online retailer might separate product data (names, prices) from customer data (addresses, orders) to make product searches faster while keeping customer information updates isolated.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. &lt;strong&gt;Directory-Based Sharding&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With &lt;strong&gt;directory-based sharding&lt;/strong&gt;, a central directory keeps track of where each piece of data is stored. Instead of using ranges or hash functions, the directory maps data to a specific shard, offering more flexibility.&lt;/p&gt;

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

&lt;p&gt;Imagine you have a customer database. Instead of splitting data by user ID or region, you use a directory that maps each customer to a specific shard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Customer 12345&lt;/strong&gt; → Shard 1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customer 67890&lt;/strong&gt; → Shard 2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customer 11223&lt;/strong&gt; → Shard 3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The directory works like a &lt;em&gt;library catalog&lt;/em&gt;, helping you track down exactly where each book (or piece of data) is stored. So when you need something, you don’t have to guess—you go straight to the right section.&lt;/p&gt;

&lt;h4&gt;
  
  
  When to Use Directory-Based Sharding:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Custom distribution&lt;/strong&gt;: When you need fine-grained control over data placement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic rebalancing&lt;/strong&gt;: When your data changes and you need to move it around.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex access patterns&lt;/strong&gt;: When simple range-based or hash-based methods won’t work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Real-World Example:
&lt;/h4&gt;

&lt;p&gt;A streaming platform could use directory-based sharding to store content by region, knowing that North American content goes to one shard, and European content to another.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. &lt;strong&gt;Hash-Based Sharding&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In &lt;strong&gt;hash-based sharding&lt;/strong&gt;, a hash function is applied to a key (like a user ID or product ID), and the resulting value determines where the data is stored. This ensures that the data is evenly distributed across all shards.&lt;/p&gt;

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

&lt;p&gt;Let’s say you have a large number of users uploading photos. You could hash each user’s ID and distribute their photos across shards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hash(User ID 12345) → Shard 1&lt;/li&gt;
&lt;li&gt;Hash(User ID 67890) → Shard 2&lt;/li&gt;
&lt;li&gt;Hash(User ID 13579) → Shard 3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This method ensures that no shard gets overloaded with data, keeping things balanced. It’s like randomly assigning genres to different sections of the library, so one section doesn’t get all the heavy traffic.&lt;/p&gt;

&lt;h4&gt;
  
  
  When to Use Hash-Based Sharding:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Even data distribution&lt;/strong&gt;: When you want to ensure an even spread of data across shards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unpredictable access patterns&lt;/strong&gt;: If you can’t predict which data will be queried more frequently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoiding hot spots&lt;/strong&gt;: Hashing helps prevent some shards from becoming more heavily loaded than others.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Real-World Example:
&lt;/h4&gt;

&lt;p&gt;A photo-sharing platform might use hash-based sharding to ensure that user uploads are spread evenly across servers, preventing one shard from becoming overwhelmed by popular images.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pros and Cons of Sharding
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Pros&lt;/strong&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Improved performance&lt;/strong&gt;: Queries are processed faster because data is distributed across servers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: You can scale your database horizontally by adding more servers as your data grows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High availability&lt;/strong&gt;: If one shard goes down, the others keep functioning, ensuring your system stays operational.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Cons&lt;/strong&gt;:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Increased complexity&lt;/strong&gt;: Managing multiple shards can be tricky, especially around data consistency and backups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-shard queries&lt;/strong&gt;: Queries that need data from multiple shards can be slower and more complex.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data imbalance&lt;/strong&gt;: If your data isn’t evenly distributed, some shards might get overloaded while others are underutilized.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When Should You Use Sharding?
&lt;/h2&gt;

&lt;p&gt;Sharding is great when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to handle a large dataset that can’t fit on a single server.&lt;/li&gt;
&lt;li&gt;Your system needs to scale horizontally as your data grows.&lt;/li&gt;
&lt;li&gt;You want to distribute traffic more efficiently across multiple servers.&lt;/li&gt;
&lt;li&gt;You require high availability, so the system stays up even if part of it goes down.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Think of database sharding as your librarian’s solution to a growing library: splitting the books (data) into smaller, more organized sections (shards) so that you can find what you need quickly, even when the library (database) becomes massive. By choosing the right sharding strategy, you’ll ensure that your application scales smoothly and performs efficiently, no matter how much data you’re dealing with.&lt;/p&gt;

&lt;p&gt;So go ahead and start organizing your data—your future self will thank you for it! And remember, the only thing worse than a slow database is a slow librarian. 😉&lt;/p&gt;

&lt;p&gt;Happy sharding!&lt;/p&gt;

</description>
      <category>database</category>
      <category>sharding</category>
      <category>sql</category>
      <category>nosql</category>
    </item>
    <item>
      <title>Apache Kafka - KRaft Mode: Setup</title>
      <dc:creator>Deeshath</dc:creator>
      <pubDate>Mon, 16 Sep 2024 10:17:02 +0000</pubDate>
      <link>https://dev.to/deeshath/apache-kafka-kraft-mode-setup-5nj</link>
      <guid>https://dev.to/deeshath/apache-kafka-kraft-mode-setup-5nj</guid>
      <description>&lt;h1&gt;
  
  
  A Simple Guide to Apache Kafka: Setting It Up and Testing in KRaft Mode
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What is Apache Kafka?
&lt;/h2&gt;

&lt;p&gt;Let’s start simple. Imagine Kafka as a &lt;strong&gt;mailing system&lt;/strong&gt; for your data. Different parts of your system, or even different systems, can communicate with each other by sending and receiving data messages. If you have tons of data being created all the time, like user actions on a website, machine logs, or even weather sensor data, Kafka ensures that this data flows smoothly and quickly to wherever it needs to go.&lt;/p&gt;

&lt;p&gt;In essence, Kafka makes sure data gets from one place to another in a way that’s fast, reliable, and scalable. So, whether you’re running a small application or a massive enterprise, Kafka’s got you covered.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Should You Use Kafka?
&lt;/h3&gt;

&lt;p&gt;Here are a few good reasons why people use Kafka:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time Data Processing&lt;/strong&gt;: Data flows through Kafka almost instantly, making it perfect for live data streams.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliable and Scalable&lt;/strong&gt;: Kafka can handle millions of data messages every second, which makes it great for both small and large systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fault-Tolerant&lt;/strong&gt;: If something goes wrong, Kafka won’t lose your data – it’s designed to recover and keep things moving.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decouples Systems&lt;/strong&gt;: Kafka allows systems to send and receive data without needing to know too much about each other, which keeps everything flexible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Kafka Concepts
&lt;/h3&gt;

&lt;p&gt;Before we jump in, let’s break down some of the basic terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Producer&lt;/strong&gt;: This is the system or service that sends data to Kafka. Think of it like the sender in the mailing system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consumer&lt;/strong&gt;: This is the system that reads or takes the data from Kafka. It’s the recipient.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Topic&lt;/strong&gt;: A channel or folder where Kafka stores messages. Producers send data to topics, and consumers read data from topics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broker&lt;/strong&gt;: A Kafka server that holds and manages the messages within topics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partition&lt;/strong&gt;: Topics can be split into smaller pieces called partitions, which helps Kafka handle a large amount of data more efficiently.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Kafka in Zookeeper Mode vs. KRaft Mode
&lt;/h2&gt;

&lt;p&gt;Originally, Kafka used &lt;strong&gt;Zookeeper&lt;/strong&gt; to manage its data and operations. Zookeeper was like the manager that made sure everything stayed organized. However, managing Zookeeper and Kafka together could be a bit complex, especially as your system grows.&lt;/p&gt;

&lt;p&gt;That’s where &lt;strong&gt;KRaft Mode&lt;/strong&gt; comes in. KRaft Mode lets Kafka manage its own data without needing Zookeeper. This makes the entire setup simpler and more efficient because you’re only managing Kafka now, not both Kafka and Zookeeper.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do They Compare?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Zookeeper Mode&lt;/th&gt;
&lt;th&gt;KRaft Mode&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Metadata Management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Managed by Zookeeper&lt;/td&gt;
&lt;td&gt;Managed directly by Kafka&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consensus Protocol&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Uses Zookeeper's method&lt;/td&gt;
&lt;td&gt;Kafka uses its own Raft protocol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Needs a separate Zookeeper cluster&lt;/td&gt;
&lt;td&gt;No Zookeeper needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;More components to manage&lt;/td&gt;
&lt;td&gt;Simpler, one less system to worry about&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Setting Up Kafka in KRaft Mode Using Docker
&lt;/h2&gt;

&lt;p&gt;Now that we have a basic understanding, let’s set up Kafka in &lt;strong&gt;KRaft mode&lt;/strong&gt; using Docker. If you’re not familiar with Docker, don’t worry! It’s a tool that lets us run programs in containers, which are like isolated environments, without needing to install everything directly on our computer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt; and &lt;strong&gt;Docker Compose&lt;/strong&gt; installed on your machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Create the Docker Compose File
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a file&lt;/strong&gt; called &lt;code&gt;docker-compose.yml&lt;/code&gt; in your project directory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy and paste&lt;/strong&gt; the following into that file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;stream'&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;kafka&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;confluentinc/cp-kafka:latest&lt;/span&gt;
    &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kafka&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kafka&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9092:9092"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9093:9093"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_KRAFT_MODE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;  &lt;span class="c1"&gt;# This enables KRaft mode in Kafka.&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_PROCESS_ROLES&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;controller,broker&lt;/span&gt;  &lt;span class="c1"&gt;# Kafka acts as both broker and controller.&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_NODE_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="c1"&gt;# A unique ID for this Kafka instance.&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_CONTROLLER_QUORUM_VOTERS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1@localhost:9093"&lt;/span&gt;  &lt;span class="c1"&gt;# Defines the controller voters.&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_LISTENERS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_LISTENER_SECURITY_PROTOCOL_MAP&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_INTER_BROKER_LISTENER_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PLAINTEXT&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_CONTROLLER_LISTENER_NAMES&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CONTROLLER&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_ADVERTISED_LISTENERS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PLAINTEXT://localhost:9092&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_LOG_DIRS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/lib/kafka/data&lt;/span&gt;  &lt;span class="c1"&gt;# Where Kafka stores its logs.&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_AUTO_CREATE_TOPICS_ENABLE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;  &lt;span class="c1"&gt;# Kafka will automatically create topics if needed.&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="c1"&gt;# Since we’re running one broker, one replica is enough.&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_LOG_RETENTION_HOURS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;168&lt;/span&gt;  &lt;span class="c1"&gt;# Keep logs for 7 days.&lt;/span&gt;
      &lt;span class="na"&gt;KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;  &lt;span class="c1"&gt;# No delay for consumer rebalancing.&lt;/span&gt;
      &lt;span class="na"&gt;CLUSTER_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mk3OEYBSD34fcwNTJENDM2Qk"&lt;/span&gt;  &lt;span class="c1"&gt;# A unique ID for the Kafka cluster.&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data:/var/lib/kafka/data&lt;/span&gt;  &lt;span class="c1"&gt;# Store Kafka logs on your local machine.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Start Kafka
&lt;/h3&gt;

&lt;p&gt;Once the file is ready, open your terminal (or command line), go to the directory where you saved the &lt;code&gt;docker-compose.yml&lt;/code&gt; file, and run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will pull the Kafka image, set everything up, and run Kafka in &lt;strong&gt;KRaft mode&lt;/strong&gt;. Now you have Kafka running locally!&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing Kafka: Let’s See If It Works!
&lt;/h2&gt;

&lt;p&gt;Great! Now let’s test our Kafka setup to make sure everything is working as expected. We’ll create a topic, send some messages, and then read them back.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Access the Kafka Container
&lt;/h3&gt;

&lt;p&gt;To interact with Kafka, we need to get inside the Docker container where Kafka is running. Use this command to access the Kafka container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; kafka bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Create a Topic
&lt;/h3&gt;

&lt;p&gt;Now, let’s create a &lt;strong&gt;topic&lt;/strong&gt; in Kafka. A topic is where messages are stored. We’ll create one called &lt;code&gt;test-topic&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/usr/bin/kafka-topics &lt;span class="nt"&gt;--create&lt;/span&gt; &lt;span class="nt"&gt;--topic&lt;/span&gt; test-topic &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092 &lt;span class="nt"&gt;--partitions&lt;/span&gt; 1 &lt;span class="nt"&gt;--replication-factor&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Send Messages to Kafka (Producing)
&lt;/h3&gt;

&lt;p&gt;Next, we’ll send some messages to the &lt;code&gt;test-topic&lt;/code&gt;. We do this by starting a producer that sends messages to Kafka:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/usr/bin/kafka-console-producer &lt;span class="nt"&gt;--broker-list&lt;/span&gt; localhost:9092 &lt;span class="nt"&gt;--topic&lt;/span&gt; test-topic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type a few messages and press Enter after each one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Hello Kafka!
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; This is a &lt;span class="nb"&gt;test &lt;/span&gt;message.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Read Messages from Kafka (Consuming)
&lt;/h3&gt;

&lt;p&gt;Now, let’s see if we can read the messages we just sent. To do this, we’ll start a consumer that reads messages from &lt;code&gt;test-topic&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/usr/bin/kafka-console-consumer &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092 &lt;span class="nt"&gt;--topic&lt;/span&gt; test-topic &lt;span class="nt"&gt;--from-beginning&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the messages you sent earlier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Hello Kafka!
This is a &lt;span class="nb"&gt;test &lt;/span&gt;message.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Check All Topics
&lt;/h3&gt;

&lt;p&gt;If you want to see all the topics that exist in your Kafka setup, you can list them with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/usr/bin/kafka-topics &lt;span class="nt"&gt;--list&lt;/span&gt; &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Check Logs (Optional)
&lt;/h3&gt;

&lt;p&gt;If you want to check what’s happening behind the scenes, you can always check the Kafka logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs kafka
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Wrapping It Up
&lt;/h2&gt;

&lt;p&gt;Well done! 🎉 You’ve just set up Kafka in &lt;strong&gt;KRaft mode&lt;/strong&gt;, created a topic, sent messages, and consumed those messages. With KRaft mode, Kafka becomes simpler to manage, since you no longer need Zookeeper.&lt;/p&gt;

&lt;p&gt;Kafka is an amazing tool for handling real-time data, and now that you’ve got it running, you can start exploring its potential. Try experimenting with different topics, producing more data, or even connecting Kafka to your own applications to see how it handles real-world use cases.&lt;/p&gt;

&lt;p&gt;Good luck, and happy streaming!&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>docker</category>
      <category>kafkakraft</category>
      <category>confluent</category>
    </item>
    <item>
      <title>REST API using GO(gin) &amp; Mongo</title>
      <dc:creator>Deeshath</dc:creator>
      <pubDate>Tue, 27 Jun 2023 04:31:36 +0000</pubDate>
      <link>https://dev.to/deeshath/rest-api-using-gogin-mongo-33i3</link>
      <guid>https://dev.to/deeshath/rest-api-using-gogin-mongo-33i3</guid>
      <description>&lt;p&gt;In this blog, we will be building a RESTful API server with two endpoints. The example project will be a repository of data about books in a library.&lt;/p&gt;

&lt;p&gt;This includes the following sections:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Design API endpoints.&lt;/li&gt;
&lt;li&gt;Create a folder for code.&lt;/li&gt;
&lt;li&gt;Connect to MongoDB using qmgo&lt;/li&gt;
&lt;li&gt;Write handlers to

&lt;ul&gt;
&lt;li&gt;add a new book&lt;/li&gt;
&lt;li&gt;get all books&lt;/li&gt;
&lt;li&gt;get a specific book&lt;/li&gt;
&lt;li&gt;delete a specific book&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prerequisites:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An installation of Go 1.20 or later. For installation instructions, &lt;a href="https://go.dev/doc/install" rel="noopener noreferrer"&gt;visit&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;An installation of MongoDB 6.0 or later. For installation
instructions, &lt;a href="https://www.mongodb.com/docs/manual/installation/" rel="noopener noreferrer"&gt;visit&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Any text editor or IDE we have will work fine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Design API endpoints:
&lt;/h2&gt;

&lt;p&gt;We’ll build an API that provides access to the books in a library. So we’ll need to provide endpoints through which a client can get, add or delete books in a library.&lt;/p&gt;

&lt;p&gt;Here are the endpoints we’ll create in this tutorial.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/books&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;GET – Get a list of all books, returned as JSON.&lt;br&gt;
POST – Add a new book from the request data sent as JSON.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/books/:id&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;GET – Get a book by its ID, returning the book data as JSON.&lt;br&gt;
PATCH – Update a book by its ID, returning the book data as JSON.&lt;br&gt;
DELETE – Delete a book by its ID, returning the deletion status as JSON.&lt;/p&gt;
&lt;h2&gt;
  
  
  Create a folder for our code:
&lt;/h2&gt;

&lt;p&gt;To begin, we will create a project for the code we are about to write.&lt;/p&gt;

&lt;p&gt;Using the command prompt, create a folder for our code called books.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir books
$ cd books
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Create a module in which we can manage dependencies.&lt;/p&gt;

&lt;p&gt;Run the &lt;code&gt;go mod init&lt;/code&gt; command, giving it the path of the module our code will be in.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go mod init books
go: creating new go.mod: module books
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This command creates a go.mod file in which dependencies we add will be listed for tracking.&lt;/p&gt;
&lt;h1&gt;
  
  
  Code
&lt;/h1&gt;

&lt;p&gt;Using IDE/text editor, create a file called main.go in the books directory. We’ll write our Go code in this file.&lt;/p&gt;

&lt;p&gt;In main.go, at the top of the file, add the following package declaration and main function that will be called when we run the code since a standalone program (as opposed to a library) is always in package main.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To run the program use &lt;code&gt;go run .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Beneath the package declaration, let's start writing the code for Connecting to MongoDB.&lt;/p&gt;

&lt;p&gt;Install the qmgo using the below cmd&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go get github.com/gin-gonic/gin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;import the "github.com/qiniu/qmgo" package and declare the variable &lt;code&gt;database&lt;/code&gt; and &lt;code&gt;collection&lt;/code&gt; and initialize them in the main function so that it could be used later on to perform CRUD operations on Data in the Database.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;qmgo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;qmgo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collection&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;// create new Client&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;databaseURI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mongodb://localhost:27017"&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connecting to database"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;databaseURI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;qmgo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;qmgo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;databaseURI&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c"&gt;// creating Database connection&lt;/span&gt;
    &lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"books"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// get the collection&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Closing Connection to database"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;databaseURI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we proceed on to write the handlers and configuring the app to listen to a http port (in our case &lt;code&gt;8000&lt;/code&gt;) in the main function.&lt;/p&gt;

&lt;p&gt;install the gin using the below cmd&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go get github.com/gin-gonic/gin&lt;/code&gt;&lt;br&gt;
and import it in the main file&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// create router using gin&lt;/span&gt;

    &lt;span class="c"&gt;// register routes&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/books"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CreateBook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Service is up &amp;amp; running at localhost:8000"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8000"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// register router to port 8000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here we have registered a POST router let's go ahead and create the CreateBook function to handle the create request &lt;/p&gt;

&lt;p&gt;Create a new file books.go in which we will be writing the code for handling the requests&lt;/p&gt;
&lt;h2&gt;
  
  
  Create the request and response structure for the books:
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// form:"title" to map the JSON field name to the struct&lt;/span&gt;
&lt;span class="c"&gt;// binding:"required" to enforce the value is required&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;BookCreateUpdateRequest&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Title&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`form:"title" binding:"required"`&lt;/span&gt;
    &lt;span class="n"&gt;Author&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`form:"author"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// json:"id" to map the struct Name to its Json field name&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;BookResponse&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Id&lt;/span&gt;        &lt;span class="n"&gt;primitive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectID&lt;/span&gt; &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;
    &lt;span class="n"&gt;Title&lt;/span&gt;     &lt;span class="kt"&gt;string&lt;/span&gt;             &lt;span class="s"&gt;`json:"title"`&lt;/span&gt;
    &lt;span class="n"&gt;Author&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt;             &lt;span class="s"&gt;`json:"author"`&lt;/span&gt;
    &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;          &lt;span class="s"&gt;`json:"createdAt"`&lt;/span&gt;
    &lt;span class="n"&gt;UpdatedAt&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;          &lt;span class="s"&gt;`json:"updatedAt"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Create the Database model structure:
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultField&lt;/span&gt; &lt;span class="s"&gt;`bson:"inline"`&lt;/span&gt;
    &lt;span class="n"&gt;Title&lt;/span&gt;              &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`bson:"title" validate:"required"`&lt;/span&gt;
    &lt;span class="n"&gt;Author&lt;/span&gt;             &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`bson:"author"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let's create the CreateBookmethod to handle book creation requests.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;CreateBook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;newBook&lt;/span&gt; &lt;span class="n"&gt;BookCreateUpdateRequest&lt;/span&gt;

    &lt;span class="c"&gt;// to bind the received JSON to BookRequest to strip the unnecessary fields.&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShouldBind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Invalid Request"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// setting data to book model struct&lt;/span&gt;
    &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InsertOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;//Inserting the Book Data to database&lt;/span&gt;

    &lt;span class="c"&gt;// to send error response if any error occurs&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Something went wrong, Try again after sometime"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// to send success response on completion&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusCreated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GetBooksResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GetBooksResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bookResponse&lt;/span&gt; &lt;span class="n"&gt;BookResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// setting response for book&lt;/span&gt;
    &lt;span class="n"&gt;bookResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BookResponse&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultField&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;CreatedAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateAt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;UpdatedAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UpdateAt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the above code, we use GetBooksResponse method to set the response that we are to send (we will be using this for other API responses too).&lt;/p&gt;

&lt;p&gt;Below are the Handlers for Get, List, Update and Delete.&lt;/p&gt;
&lt;h2&gt;
  
  
  Get a book detail API:
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GetBook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;// to get and convert the received path variable to  desired type&lt;/span&gt;
    &lt;span class="n"&gt;bookId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;primitive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectIDFromHex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"bookId"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Invalid Request"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;//Getting the Book Data from database&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bookId&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;One&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// to send error response if any error occurs&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNotFound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Book Not Found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// to send success response on completion&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusOK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GetBooksResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the above code the &lt;code&gt;bson.M{"_id": bookId}&lt;/code&gt; is used to find the book by Id and One is used to bind the mongo Data to the book variable&lt;/p&gt;
&lt;h3&gt;
  
  
  Update a book API:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;UpdateBook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;// to get and convert the received path variable to  desired type&lt;/span&gt;
    &lt;span class="n"&gt;bookId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;primitive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectIDFromHex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"bookId"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Invalid Book ID"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;newBook&lt;/span&gt; &lt;span class="n"&gt;BookCreateUpdateRequest&lt;/span&gt;

    &lt;span class="c"&gt;// to bind the received JSON to BookRequest to strip the unnecessary fields.&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShouldBind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Invalid Request"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;//Getting the Book Data from database&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bookId&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;One&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// to send error response if any error occurs&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNotFound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Book Not Found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// set the updated value in the book&lt;/span&gt;
    &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;
    &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;

    &lt;span class="c"&gt;// update in database&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReplaceOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bookId&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Something went wrong, Try again after sometime"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// to send success response on completion&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusOK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GetBooksResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the above code block, &lt;code&gt;collection.ReplaceOne&lt;/code&gt; is used to replace the existing document based on the condition the ReplaceOne method also updates the default field UpdateAT in the database.&lt;/p&gt;
&lt;h2&gt;
  
  
  Delete Book Handler:
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;DeleteBook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;// to get and convert the received path variable to  desired type&lt;/span&gt;
    &lt;span class="n"&gt;bookId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;primitive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectIDFromHex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"bookId"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Invalid Request"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;//Getting the Book Data from database&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"_id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bookId&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;One&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// to send error response if any error occurs&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusNotFound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Book Not Found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Deleting the book&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RemoveId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bookId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// to send error response if any error occurs&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Something went wrong, Try again after sometime"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// to send success response on completion&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusOK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;In the above code block, &lt;code&gt;collection.RemoveId&lt;/code&gt; is used to remove the specific data based on the ID provided.&lt;/p&gt;
&lt;h2&gt;
  
  
  Books List Handler
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GetBooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;//Getting the Book Data to database&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;BookListResponse&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;All&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// to send error response if any error occurs&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Something went wrong, Try again after sometime"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// to send success response on completion&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusOK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here in the List handler, we have used BookListResponse which is used to limit the values read from the database since the id and the name of the book would suffice in the list API. Below is the BookListResponse type.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;BookListResponse&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Id&lt;/span&gt;    &lt;span class="n"&gt;primitive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectID&lt;/span&gt; &lt;span class="s"&gt;`json:"id" bson:"_id"`&lt;/span&gt; &lt;span class="c"&gt;// bson to map mongo _id to id&lt;/span&gt;
    &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;             &lt;span class="s"&gt;`json:"title"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;Here the &lt;code&gt;bson:"_id"&lt;/code&gt; is used to map the mongo _id to the ID attribute in the response.&lt;/p&gt;

&lt;p&gt;Now all the Handlers have been created let's register the Handlers in the router in main.go by adding the below code block after the router declaration.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/books"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GetBooks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/books/:bookId"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GetBook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PATCH&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/books/:bookId"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateBook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/books/:bookId"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DeleteBook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Congratulations!!! the CRUD REST API  for books in a library using Mongo and Go is successfully completed.&lt;/p&gt;

&lt;p&gt;You will be able to find the source code in the Github repo:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Deeshath" rel="noopener noreferrer"&gt;
        Deeshath
      &lt;/a&gt; / &lt;a href="https://github.com/Deeshath/books" rel="noopener noreferrer"&gt;
        books
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Books REST API using go and mongo
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Books&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;Books REST API using go and mongo&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Pre requisites:&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;An installation of Go 1.20 or later. For installation instructions, &lt;a href="https://go.dev/doc/install" rel="nofollow noopener noreferrer"&gt;visit&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;An installation of MongoDb 6.0 or later. For installationinstructions, &lt;a href="https://www.mongodb.com/docs/manual/installation/" rel="nofollow noopener noreferrer"&gt;visit&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To start thr REST API server use the cmd
&lt;code&gt;go run  .&lt;/code&gt;&lt;/p&gt;
&lt;/div&gt;



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


</description>
      <category>go</category>
      <category>mongodb</category>
      <category>rest</category>
      <category>api</category>
    </item>
  </channel>
</rss>
