<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Muhammad Dhiyaul Atha</title>
    <description>The latest articles on Forem by Muhammad Dhiyaul Atha (@bangkah).</description>
    <link>https://forem.com/bangkah</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%2F3665512%2Fdc6c5db5-91c9-4887-a5c6-33c8db391e07.jpeg</url>
      <title>Forem: Muhammad Dhiyaul Atha</title>
      <link>https://forem.com/bangkah</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bangkah"/>
    <language>en</language>
    <item>
      <title>I Built a Safety-First Workflow Layer for Pacman (ATHA)</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Tue, 31 Mar 2026 16:35:36 +0000</pubDate>
      <link>https://forem.com/bangkah/i-built-a-simple-pacman-aur-wrapper-for-arch-linux-atha-11bd</link>
      <guid>https://forem.com/bangkah/i-built-a-simple-pacman-aur-wrapper-for-arch-linux-atha-11bd</guid>
      <description>&lt;p&gt;Managing packages on Arch Linux is powerful, but sometimes it lacks visibility and safety.&lt;/p&gt;

&lt;p&gt;You run a command… and it just executes.&lt;/p&gt;

&lt;p&gt;No preview. No clear audit trail. No structured workflow.&lt;/p&gt;

&lt;p&gt;So I started building &lt;strong&gt;ATHA&lt;/strong&gt; — a safety-first workflow layer on top of pacman.&lt;/p&gt;

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

&lt;p&gt;ATHA is not a replacement for pacman.&lt;/p&gt;

&lt;p&gt;It tries to enhance it with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install planning (&lt;code&gt;--plan&lt;/code&gt;) before execution&lt;/li&gt;
&lt;li&gt;Dry-run support for safer operations&lt;/li&gt;
&lt;li&gt;Confirmation layers for critical actions&lt;/li&gt;
&lt;li&gt;Operation history with timeline view&lt;/li&gt;
&lt;li&gt;Built-in system diagnostics (&lt;code&gt;atha doctor&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make package operations more predictable, transparent, and auditable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Before installing a package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;atha &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--plan&lt;/span&gt; neovim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get a preview of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dependencies&lt;/li&gt;
&lt;li&gt;disk usage&lt;/li&gt;
&lt;li&gt;source (official repo or AUR)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I Built This
&lt;/h2&gt;

&lt;p&gt;Arch gives full control — but sometimes operations can feel a bit “blind”.&lt;/p&gt;

&lt;p&gt;ATHA is my attempt to improve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safety → reduce accidental changes&lt;/li&gt;
&lt;li&gt;Transparency → understand what will happen&lt;/li&gt;
&lt;li&gt;Auditability → keep track of what happened&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparison
&lt;/h2&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;pacman&lt;/th&gt;
&lt;th&gt;yay&lt;/th&gt;
&lt;th&gt;ATHA&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dry-run support&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install planning&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operation history&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workflow consistency&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yay &lt;span class="nt"&gt;-S&lt;/span&gt; atha
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/Bangkah/Atha" rel="noopener noreferrer"&gt;https://github.com/Bangkah/Atha&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AUR: &lt;a href="https://aur.archlinux.org/packages/atha" rel="noopener noreferrer"&gt;https://aur.archlinux.org/packages/atha&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💬 Feedback
&lt;/h2&gt;

&lt;p&gt;This project is still evolving and definitely not perfect.&lt;/p&gt;

&lt;p&gt;I’m sure there are things that can be improved — both in design and implementation.&lt;/p&gt;

&lt;p&gt;If you have feedback, criticism, or suggestions, I’d really appreciate hearing them.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>archlinux</category>
      <category>opensource</category>
      <category>cli</category>
    </item>
    <item>
      <title>My First Attempt at Building a Reasoning AI (ARC Prize 2026)</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Thu, 26 Mar 2026 07:28:57 +0000</pubDate>
      <link>https://forem.com/bangkah/my-first-attempt-at-building-a-reasoning-ai-arc-prize-2026-18dj</link>
      <guid>https://forem.com/bangkah/my-first-attempt-at-building-a-reasoning-ai-arc-prize-2026-18dj</guid>
      <description>&lt;p&gt;What if AI fails the moment the problem changes?&lt;/p&gt;

&lt;p&gt;Most AI systems today are great at recognizing patterns — but what happens when the problem itself is different from anything they’ve seen before?&lt;/p&gt;

&lt;p&gt;That’s exactly the challenge behind the ARC Prize 2026 on Kaggle.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;I recently joined the ARC-AGI-2 competition on Kaggle, which challenges participants to build AI systems capable of solving problems they’ve never seen before.&lt;/p&gt;

&lt;p&gt;Unlike typical machine learning tasks, ARC is not about training on massive datasets.&lt;/p&gt;

&lt;p&gt;Instead, it focuses on something closer to human intelligence:&lt;br&gt;
&lt;strong&gt;reasoning and generalization.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  My First Approach (Baseline)
&lt;/h2&gt;

&lt;p&gt;To get started, I built a very simple baseline model.&lt;/p&gt;

&lt;p&gt;The goal was not to solve the problem yet — but to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand the dataset structure&lt;/li&gt;
&lt;li&gt;Learn how submissions work&lt;/li&gt;
&lt;li&gt;Successfully make my first submission&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s the basic idea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read input grid&lt;/li&gt;
&lt;li&gt;Generate output grid with the same shape&lt;/li&gt;
&lt;li&gt;Fill it with zeros&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes — it's intentionally simple.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code &amp;amp; Repository
&lt;/h2&gt;

&lt;p&gt;You can check my first implementation here: &lt;a href="https://github.com/Bangkah/arc-agi-learning" rel="noopener noreferrer"&gt;https://github.com/Bangkah/arc-agi-learning&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This repository documents my learning journey as I explore reasoning-based AI.&lt;/p&gt;




&lt;h2&gt;
  
  
  First Submission (Kaggle)
&lt;/h2&gt;

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




&lt;h2&gt;
  
  
  Why Start Simple?
&lt;/h2&gt;

&lt;p&gt;Because ARC is not about jumping into complex models.&lt;/p&gt;

&lt;p&gt;It’s about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding transformations&lt;/li&gt;
&lt;li&gt;Identifying patterns&lt;/li&gt;
&lt;li&gt;Building logic step-by-step&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even advanced AI systems still struggle with ARC tasks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why ARC is Hard
&lt;/h2&gt;

&lt;p&gt;ARC tasks require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding abstract patterns&lt;/li&gt;
&lt;li&gt;Applying transformations&lt;/li&gt;
&lt;li&gt;Generalizing from very few examples&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike traditional machine learning, there is no training phase with millions of samples.&lt;/p&gt;

&lt;p&gt;Each problem is a completely new challenge.&lt;/p&gt;




&lt;h2&gt;
  
  
  First Submission Result
&lt;/h2&gt;

&lt;p&gt;My first submission didn’t perform well — and that’s expected.&lt;/p&gt;

&lt;p&gt;The real goal was:&lt;br&gt;
✔ Understanding the pipeline&lt;br&gt;
✔ Getting familiar with the problem&lt;br&gt;
✔ Starting the journey&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Insight
&lt;/h2&gt;

&lt;p&gt;ARC is fundamentally different from most AI challenges.&lt;/p&gt;

&lt;p&gt;It’s not about:&lt;br&gt;
❌ memorizing patterns&lt;/p&gt;

&lt;p&gt;It’s about:&lt;br&gt;
✔ discovering rules&lt;br&gt;
✔ applying logic&lt;br&gt;
✔ adapting to new problems&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;My next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solve ARC tasks manually&lt;/li&gt;
&lt;li&gt;Build rule-based solutions&lt;/li&gt;
&lt;li&gt;Improve generalization step-by-step&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;This is not just a competition — it’s a challenge to rethink how we approach AI.&lt;/p&gt;

&lt;p&gt;And I’m just getting started.&lt;/p&gt;




&lt;p&gt;Have you tried solving ARC tasks?&lt;/p&gt;

&lt;p&gt;I’d love to hear how others approach reasoning problems like this.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>kaggle</category>
      <category>programming</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Tue, 24 Mar 2026 04:53:53 +0000</pubDate>
      <link>https://forem.com/bangkah/-36mp</link>
      <guid>https://forem.com/bangkah/-36mp</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/bangkah/my-first-home-server-using-a-12-year-old-laptop-2eh7" class="crayons-story__hidden-navigation-link"&gt;My First Home Server Using a 12-Year-Old Laptop&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/bangkah" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3665512%2Fdc6c5db5-91c9-4887-a5c6-33c8db391e07.jpeg" alt="bangkah profile" class="crayons-avatar__image" width="800" height="599"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/bangkah" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Muhammad Dhiyaul Atha
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Muhammad Dhiyaul Atha
                
              
              &lt;div id="story-author-preview-content-3392551" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/bangkah" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3665512%2Fdc6c5db5-91c9-4887-a5c6-33c8db391e07.jpeg" class="crayons-avatar__image" alt="" width="800" height="599"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Muhammad Dhiyaul Atha&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/bangkah/my-first-home-server-using-a-12-year-old-laptop-2eh7" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 24&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/bangkah/my-first-home-server-using-a-12-year-old-laptop-2eh7" id="article-link-3392551"&gt;
          My First Home Server Using a 12-Year-Old Laptop
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/linux"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;linux&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/productivity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;productivity&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/homelab"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;homelab&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/bangkah/my-first-home-server-using-a-12-year-old-laptop-2eh7#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>linux</category>
      <category>devops</category>
      <category>productivity</category>
      <category>homelab</category>
    </item>
    <item>
      <title>My First Home Server Using a 12-Year-Old Laptop</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Tue, 24 Mar 2026 04:41:31 +0000</pubDate>
      <link>https://forem.com/bangkah/my-first-home-server-using-a-12-year-old-laptop-2eh7</link>
      <guid>https://forem.com/bangkah/my-first-home-server-using-a-12-year-old-laptop-2eh7</guid>
      <description>&lt;h1&gt;
  
  
  When an Old Laptop Finds Its New Purpose
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Turning a 2012 MacBook Pro into My First Personal Server
&lt;/h2&gt;

&lt;p&gt;There was a 2012 MacBook Pro sitting in front of me.&lt;/p&gt;

&lt;p&gt;Not my main machine anymore.&lt;br&gt;
Definitely not fast by today’s standards.&lt;/p&gt;

&lt;p&gt;But that’s exactly where a simple question came up:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“How far can this old laptop still be useful?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question led me to a small experiment —&lt;br&gt;
turning this old machine into a personal server and controlling it remotely via SSH from my main laptop.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why an Old Laptop?
&lt;/h2&gt;

&lt;p&gt;As a software engineering student, I started realizing something important:&lt;/p&gt;

&lt;p&gt;Learning about servers is not enough if it’s only theory.&lt;/p&gt;

&lt;p&gt;I can read documentation, watch tutorials, and follow guides —&lt;br&gt;
but there’s always a gap between &lt;em&gt;knowing&lt;/em&gt; and &lt;em&gt;actually experiencing it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;At the same time, I had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A 2012 MacBook Pro collecting dust&lt;/li&gt;
&lt;li&gt;A growing interest in Linux&lt;/li&gt;
&lt;li&gt;Curiosity about how servers actually work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of letting it sit unused, I turned it into a learning lab.&lt;/p&gt;


&lt;h2&gt;
  
  
  System Choice: Arch Linux on Old Hardware
&lt;/h2&gt;

&lt;p&gt;I chose &lt;strong&gt;Arch Linux&lt;/strong&gt; for this machine.&lt;/p&gt;

&lt;p&gt;Not because it’s easy — actually the opposite.&lt;/p&gt;

&lt;p&gt;But because I wanted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A lightweight system&lt;/li&gt;
&lt;li&gt;Full control over everything installed&lt;/li&gt;
&lt;li&gt;A raw, hands-on learning experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For my main laptop, I use an Acer Nitro V16 running Garuda Linux —&lt;br&gt;
this is where I control everything from.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Struggles: Nothing Worked Perfectly
&lt;/h2&gt;

&lt;p&gt;Of course, things didn’t go smoothly at first.&lt;/p&gt;

&lt;p&gt;Here are some challenges I faced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚠️ Old hardware limitations (heat, performance)&lt;/li&gt;
&lt;li&gt;⚠️ Arch Linux setup complexity&lt;/li&gt;
&lt;li&gt;⚠️ Networking confusion (IP, services, firewall)&lt;/li&gt;
&lt;li&gt;⚠️ SSH failing due to small misconfigurations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There were frustrating moments, especially when:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Why is SSH installed but I still can’t connect?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But those were the moments where real learning happened:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reading logs&lt;/li&gt;
&lt;li&gt;Understanding errors&lt;/li&gt;
&lt;li&gt;Not just copy-pasting commands&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  The Goal: More Than Just Remote Access
&lt;/h2&gt;

&lt;p&gt;My goal wasn’t just:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Connect via SSH from another laptop”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I wanted to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand how servers actually work&lt;/li&gt;
&lt;li&gt;Get comfortable working without a GUI&lt;/li&gt;
&lt;li&gt;Simulate a simple backend/DevOps workflow&lt;/li&gt;
&lt;li&gt;Build the habit of working remotely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This server became my personal lab —&lt;br&gt;
a safe place to break things and learn.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Breakthrough Moment
&lt;/h2&gt;

&lt;p&gt;The most satisfying moment?&lt;/p&gt;

&lt;p&gt;From my main laptop, I ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;ssh&lt;/span&gt; atha@192.xxx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then…&lt;/p&gt;

&lt;p&gt;The terminal of the 2012 MacBook appeared on my screen.&lt;/p&gt;

&lt;p&gt;No GUI.&lt;br&gt;
No mouse.&lt;br&gt;
Just a terminal.&lt;/p&gt;

&lt;p&gt;But it felt like opening a door to a completely new world.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Can Do Now
&lt;/h2&gt;

&lt;p&gt;Now I can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manage my server from my main laptop&lt;/li&gt;
&lt;li&gt;Install and configure services remotely&lt;/li&gt;
&lt;li&gt;Bring an old machine back to life&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this is just the beginning.&lt;/p&gt;

&lt;p&gt;Next, I plan to explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up a web server&lt;/li&gt;
&lt;li&gt;Building a simple API&lt;/li&gt;
&lt;li&gt;SSH hardening&lt;/li&gt;
&lt;li&gt;Small automation scripts&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;This experiment taught me something important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Learning servers doesn’t have to be expensive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes, an old laptop and curiosity are enough.&lt;/p&gt;

&lt;p&gt;That 2012 MacBook Pro that once felt outdated&lt;br&gt;
now has a new role.&lt;/p&gt;

&lt;p&gt;Not as my main machine —&lt;br&gt;
but as a silent teacher, helping me understand systems, patience, and real learning.&lt;/p&gt;

&lt;p&gt;And this journey…&lt;/p&gt;

&lt;p&gt;is just getting started 🚀&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What about you?&lt;/strong&gt;&lt;br&gt;
Have you ever repurposed old hardware into something useful?&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>productivity</category>
      <category>homelab</category>
    </item>
    <item>
      <title>Saya Membuat CLI Tool Jadwal Shalat dan Merilisnya ke Arch Linux AUR</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Wed, 18 Feb 2026 12:30:23 +0000</pubDate>
      <link>https://forem.com/bangkah/saya-membuat-cli-tool-jadwal-shalat-dan-merilisnya-ke-arch-linux-aur-352f</link>
      <guid>https://forem.com/bangkah/saya-membuat-cli-tool-jadwal-shalat-dan-merilisnya-ke-arch-linux-aur-352f</guid>
      <description>&lt;p&gt;Sebagai pengguna Linux dan seseorang yang sering bekerja di terminal, saya ingin bisa melihat jadwal shalat langsung dari CLI tanpa membuka browser atau aplikasi GUI.&lt;/p&gt;

&lt;p&gt;Dari kebutuhan sederhana itu, saya membuat sebuah tool bernama &lt;strong&gt;jadwal-shalat&lt;/strong&gt; — sebuah CLI tool profesional berbasis Python yang dapat menampilkan jadwal shalat secara otomatis berdasarkan lokasi pengguna.&lt;/p&gt;

&lt;p&gt;Sekarang tool ini sudah tersedia secara resmi di Arch Linux AUR.&lt;/p&gt;




&lt;h1&gt;
  
  
  Latar Belakang
&lt;/h1&gt;

&lt;p&gt;Banyak aplikasi jadwal shalat tersedia, tapi sebagian besar berbasis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mobile apps&lt;/li&gt;
&lt;li&gt;Website&lt;/li&gt;
&lt;li&gt;Aplikasi GUI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Masalahnya, bagi pengguna Linux yang sering bekerja di:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;terminal&lt;/li&gt;
&lt;li&gt;server&lt;/li&gt;
&lt;li&gt;SSH session&lt;/li&gt;
&lt;li&gt;environment minimal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;solusi tersebut tidak praktis.&lt;/p&gt;

&lt;p&gt;Saya ingin sesuatu yang:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ringan&lt;/li&gt;
&lt;li&gt;cepat&lt;/li&gt;
&lt;li&gt;otomatis&lt;/li&gt;
&lt;li&gt;dan native di terminal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Maka saya membuat CLI tool ini.&lt;/p&gt;




&lt;h1&gt;
  
  
  Apa Itu jadwal-shalat?
&lt;/h1&gt;

&lt;p&gt;jadwal-shalat adalah CLI tool Python yang dapat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mendeteksi lokasi otomatis dari IP publik&lt;/li&gt;
&lt;li&gt;menentukan timezone secara akurat&lt;/li&gt;
&lt;li&gt;mengambil jadwal shalat dari API Aladhan (method Kemenag Indonesia)&lt;/li&gt;
&lt;li&gt;menampilkan jadwal secara rapi di terminal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tool ini dirancang khusus untuk pengguna Indonesia.&lt;/p&gt;




&lt;h1&gt;
  
  
  Fitur Utama
&lt;/h1&gt;

&lt;p&gt;Beberapa fitur yang tersedia saat ini:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deteksi IP publik otomatis&lt;/li&gt;
&lt;li&gt;Deteksi lokasi otomatis (kota, negara, koordinat, timezone)&lt;/li&gt;
&lt;li&gt;Fallback API lokasi jika layanan utama gagal&lt;/li&gt;
&lt;li&gt;Menggunakan API Aladhan (method=20/Kemenag Indonesia)&lt;/li&gt;
&lt;li&gt;Jadwal shalat lengkap&lt;/li&gt;
&lt;li&gt;Menampilkan waktu shalat berikutnya + countdown&lt;/li&gt;
&lt;li&gt;Output terminal rapi dengan alignment yang baik&lt;/li&gt;
&lt;li&gt;Error handling lengkap&lt;/li&gt;
&lt;li&gt;Timeout protection untuk API&lt;/li&gt;
&lt;li&gt;Support timezone akurat&lt;/li&gt;
&lt;li&gt;Siap packaging AUR dengan auto update&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Contoh Output
&lt;/h1&gt;

&lt;p&gt;Contoh ketika dijalankan:&lt;/p&gt;

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

&lt;p&gt;Output difokuskan agar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mudah dibaca&lt;/li&gt;
&lt;li&gt;minimalis&lt;/li&gt;
&lt;li&gt;profesional&lt;/li&gt;
&lt;li&gt;cocok untuk penggunaan harian di terminal&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Instalasi via Arch Linux AUR
&lt;/h1&gt;

&lt;p&gt;Tool ini sekarang tersedia di AUR, sehingga instalasi sangat mudah:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yay -S jadwal-shalat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Atau manual:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://aur.archlinux.org/jadwal-shalat.git
cd jadwal-shalat
makepkg -si
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sebagai maintainer AUR, saya juga mengatur auto-update menggunakan GitHub Actions.&lt;/p&gt;




&lt;h1&gt;
  
  
  Instalasi Manual
&lt;/h1&gt;

&lt;p&gt;Jika tidak menggunakan Arch Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clone repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/Bangkah/jadwal-shalat.git
cd jadwal-shalat
chmod +x jadwal-shalat.py
./jadwal-shalat.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Atau:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python jadwal-shalat.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Cara Kerja Tool Ini
&lt;/h1&gt;

&lt;p&gt;Secara sederhana:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mengambil IP publik user&lt;/li&gt;
&lt;li&gt;Mengubah IP menjadi lokasi geografis&lt;/li&gt;
&lt;li&gt;Menentukan timezone&lt;/li&gt;
&lt;li&gt;Mengambil jadwal shalat dari API Aladhan&lt;/li&gt;
&lt;li&gt;Menampilkan jadwal dan countdown&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Semua proses dilakukan secara otomatis.&lt;/p&gt;




&lt;h1&gt;
  
  
  Fokus pada Reliability
&lt;/h1&gt;

&lt;p&gt;Beberapa hal yang saya implementasikan untuk memastikan tool stabil:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fallback API jika layanan lokasi gagal&lt;/li&gt;
&lt;li&gt;timeout protection&lt;/li&gt;
&lt;li&gt;error handling jaringan&lt;/li&gt;
&lt;li&gt;parsing timezone akurat&lt;/li&gt;
&lt;li&gt;output formatting konsisten&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ini penting agar tool tetap berfungsi bahkan dalam kondisi jaringan tidak stabil.&lt;/p&gt;




&lt;h1&gt;
  
  
  Integrasi dengan Arch Linux Packaging
&lt;/h1&gt;

&lt;p&gt;Salah satu milestone terbesar project ini adalah berhasil dipublish ke Arch Linux AUR.&lt;/p&gt;

&lt;p&gt;Ini berarti:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;user bisa install dengan yay&lt;/li&gt;
&lt;li&gt;update terdistribusi secara otomatis&lt;/li&gt;
&lt;li&gt;mengikuti standar packaging Linux&lt;/li&gt;
&lt;li&gt;tool menjadi lebih profesional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Saya juga mengintegrasikan GitHub Actions untuk membantu workflow update.&lt;/p&gt;




&lt;h1&gt;
  
  
  Roadmap ke Depan
&lt;/h1&gt;

&lt;p&gt;Beberapa fitur yang direncanakan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;input manual kota&lt;/li&gt;
&lt;li&gt;input manual koordinat&lt;/li&gt;
&lt;li&gt;output JSON&lt;/li&gt;
&lt;li&gt;notifikasi waktu shalat&lt;/li&gt;
&lt;li&gt;packaging PyPI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tujuannya adalah membuat tool ini semakin fleksibel.&lt;/p&gt;




&lt;h1&gt;
  
  
  Kenapa Saya Membuat Project Ini?
&lt;/h1&gt;

&lt;p&gt;Selain kebutuhan pribadi, project ini juga menjadi sarana belajar tentang:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CLI development dengan Python&lt;/li&gt;
&lt;li&gt;API integration&lt;/li&gt;
&lt;li&gt;timezone handling&lt;/li&gt;
&lt;li&gt;Linux packaging (PKGBUILD)&lt;/li&gt;
&lt;li&gt;AUR maintenance&lt;/li&gt;
&lt;li&gt;CI/CD dengan GitHub Actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Project kecil seperti ini sangat membantu meningkatkan skill sebagai developer.&lt;/p&gt;




&lt;h1&gt;
  
  
  Open Source dan Kontribusi
&lt;/h1&gt;

&lt;p&gt;Project ini open source dan tersedia di GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Bangkah/jadwal-shalat" rel="noopener noreferrer"&gt;https://github.com/Bangkah/jadwal-shalat&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kontribusi sangat diterima.&lt;/p&gt;




&lt;h1&gt;
  
  
  Penutup
&lt;/h1&gt;

&lt;p&gt;Linux memiliki ekosistem CLI yang sangat kuat, dan saya percaya tool kecil seperti ini bisa meningkatkan produktivitas pengguna terminal.&lt;/p&gt;

&lt;p&gt;Jika kamu pengguna Arch Linux atau Linux secara umum, kamu bisa mencoba tool ini dan memberikan feedback.&lt;/p&gt;

</description>
      <category>aur</category>
      <category>python</category>
      <category>cli</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building Sentinel AI: A Cybersecurity CLI Powered by Copilot</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Sat, 14 Feb 2026 17:30:38 +0000</pubDate>
      <link>https://forem.com/bangkah/building-sentinel-ai-a-cybersecurity-cli-powered-by-copilot-35fh</link>
      <guid>https://forem.com/bangkah/building-sentinel-ai-a-cybersecurity-cli-powered-by-copilot-35fh</guid>
      <description>&lt;h1&gt;
  
  
  From Copilot Experiment to Production-Ready CLI: Building Sentinel AI
&lt;/h1&gt;

&lt;p&gt;Cybersecurity is no longer optional — every connected system is exposed to potential threats. While there are many enterprise-grade tools available, I wanted to understand how such tools work internally.&lt;/p&gt;

&lt;p&gt;So I built my own.&lt;/p&gt;

&lt;p&gt;Sentinel AI started as a small experiment using GitHub Copilot CLI. But through iteration, debugging, and production hardening, it evolved into a fully functional, production-ready cybersecurity CLI tool for Linux.&lt;/p&gt;

&lt;p&gt;This article explains the journey — from idea to production.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Idea
&lt;/h1&gt;

&lt;p&gt;Modern systems constantly create network connections — many legitimate, some suspicious. Most users never see what is happening behind the scenes.&lt;/p&gt;

&lt;p&gt;I wanted a tool that could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Show active network connections&lt;/li&gt;
&lt;li&gt;Identify suspicious behavior&lt;/li&gt;
&lt;li&gt;Assign risk scores&lt;/li&gt;
&lt;li&gt;Provide actionable summaries&lt;/li&gt;
&lt;li&gt;Work directly from the terminal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It needed to be fast, simple, and transparent.&lt;/p&gt;

&lt;p&gt;That’s how Sentinel AI was born.&lt;/p&gt;




&lt;h1&gt;
  
  
  How GitHub Copilot Accelerated Development
&lt;/h1&gt;

&lt;p&gt;GitHub Copilot CLI significantly accelerated development by helping generate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modular Python code structure&lt;/li&gt;
&lt;li&gt;CLI argument parsing using argparse&lt;/li&gt;
&lt;li&gt;Risk classification logic&lt;/li&gt;
&lt;li&gt;Error handling and logging&lt;/li&gt;
&lt;li&gt;Clean and readable code patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of spending hours writing boilerplate, I could focus on architecture and functionality.&lt;/p&gt;

&lt;p&gt;Copilot acted as a coding assistant — not a replacement — helping me move faster while maintaining control over the system design.&lt;/p&gt;




&lt;h1&gt;
  
  
  Architecture Overview
&lt;/h1&gt;

&lt;p&gt;Sentinel AI is built using a modular architecture:&lt;/p&gt;

&lt;p&gt;Core components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network Scanner — collects active connections&lt;/li&gt;
&lt;li&gt;Analyzer — evaluates connections and assigns risk scores&lt;/li&gt;
&lt;li&gt;Reporting Engine — summarizes system risk level&lt;/li&gt;
&lt;li&gt;CLI Interface — provides user interaction&lt;/li&gt;
&lt;li&gt;Logging System — records activity and errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;psutil&lt;/li&gt;
&lt;li&gt;colorama&lt;/li&gt;
&lt;li&gt;argparse&lt;/li&gt;
&lt;li&gt;autopep8&lt;/li&gt;
&lt;li&gt;GitHub Actions (CI/CD)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This architecture ensures maintainability and extensibility.&lt;/p&gt;




&lt;h1&gt;
  
  
  Core Features
&lt;/h1&gt;

&lt;p&gt;Sentinel AI provides several security-focused capabilities:&lt;/p&gt;

&lt;h3&gt;
  
  
  Network Scanning
&lt;/h3&gt;

&lt;p&gt;Lists all active network connections with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Protocol&lt;/li&gt;
&lt;li&gt;Local address&lt;/li&gt;
&lt;li&gt;Remote address&lt;/li&gt;
&lt;li&gt;Process ID&lt;/li&gt;
&lt;li&gt;Process name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sentinel-ai scan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Intelligent Risk Analysis
&lt;/h3&gt;

&lt;p&gt;Each connection is analyzed and assigned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Numeric risk score (0–100)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Risk level classification:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LOW&lt;/li&gt;
&lt;li&gt;MEDIUM&lt;/li&gt;
&lt;li&gt;HIGH&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Explanation of the risk&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sentinel-ai analyze
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Proto  Local Address      Remote Address     PID   Process   Risk
TCP    192.168.1.10:54321 8.8.8.8:53        1234  python3   HIGH (87)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  System Risk Report
&lt;/h3&gt;

&lt;p&gt;Provides a system-level security overview:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sentinel-ai report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=== Sentinel AI CLI Security Report ===
Total connections: 12
External connections: 3
High risk: 1
Medium risk: 2
Low risk: 9
Overall system risk: HIGH (72/100)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows users to understand their system security posture instantly.&lt;/p&gt;




&lt;h3&gt;
  
  
  System Information
&lt;/h3&gt;

&lt;p&gt;Displays system-level information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sentinel-ai system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OS&lt;/li&gt;
&lt;li&gt;Kernel version&lt;/li&gt;
&lt;li&gt;CPU&lt;/li&gt;
&lt;li&gt;Memory&lt;/li&gt;
&lt;li&gt;Hostname&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Developer Utilities
&lt;/h3&gt;

&lt;p&gt;Sentinel AI also includes developer-focused tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sentinel-ai debug file.py
sentinel-ai explain-code file.py
sentinel-ai improve-code file.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These tools help developers analyze, debug, and improve Python code.&lt;/p&gt;




&lt;h1&gt;
  
  
  From Prototype to Production
&lt;/h1&gt;

&lt;p&gt;What started as a simple script evolved into a production-grade CLI tool.&lt;/p&gt;

&lt;p&gt;Key improvements included:&lt;/p&gt;

&lt;h3&gt;
  
  
  Modern Python Packaging
&lt;/h3&gt;

&lt;p&gt;Sentinel AI uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pyproject.toml&lt;/li&gt;
&lt;li&gt;Standardized project structure&lt;/li&gt;
&lt;li&gt;Proper dependency management&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  CI/CD Pipeline
&lt;/h3&gt;

&lt;p&gt;Using GitHub Actions, Sentinel AI now has automated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linting (PEP8 compliance)&lt;/li&gt;
&lt;li&gt;Build validation&lt;/li&gt;
&lt;li&gt;Test execution&lt;/li&gt;
&lt;li&gt;Release safety checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures every update maintains production quality.&lt;/p&gt;




&lt;h3&gt;
  
  
  Trusted Publishing to PyPI
&lt;/h3&gt;

&lt;p&gt;Sentinel AI uses secure Trusted Publishing, allowing automated and secure package releases.&lt;/p&gt;

&lt;p&gt;This eliminates manual credential handling and improves release security.&lt;/p&gt;




&lt;h1&gt;
  
  
  Installation
&lt;/h1&gt;

&lt;p&gt;Sentinel AI is available on PyPI.&lt;/p&gt;

&lt;p&gt;Install using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install sentinel-ai-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sentinel-ai report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And immediately see your system’s security overview.&lt;/p&gt;




&lt;h1&gt;
  
  
  Challenges and Lessons Learned
&lt;/h1&gt;

&lt;p&gt;Building Sentinel AI taught me several important engineering lessons:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. CI/CD Discipline
&lt;/h3&gt;

&lt;p&gt;Fixing lint errors, formatting issues, and pipeline failures helped reinforce professional development practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Production Packaging
&lt;/h3&gt;

&lt;p&gt;Using modern Python packaging standards improved maintainability and reliability.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. CLI Design Principles
&lt;/h3&gt;

&lt;p&gt;Designing a clean CLI interface requires careful planning to ensure usability and clarity.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Copilot as a Force Multiplier
&lt;/h3&gt;

&lt;p&gt;Copilot accelerated development — but debugging and refinement required human understanding.&lt;/p&gt;

&lt;p&gt;AI helped build faster, but engineering discipline made it production-ready.&lt;/p&gt;




&lt;h1&gt;
  
  
  Future Plans
&lt;/h1&gt;

&lt;p&gt;Planned improvements include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arch Linux (AUR) package&lt;/li&gt;
&lt;li&gt;Docker image&lt;/li&gt;
&lt;li&gt;Real-time monitoring mode&lt;/li&gt;
&lt;li&gt;Threat intelligence integration&lt;/li&gt;
&lt;li&gt;Plugin system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sentinel AI will continue evolving.&lt;/p&gt;




&lt;h1&gt;
  
  
  Open Source and Availability
&lt;/h1&gt;

&lt;p&gt;GitHub Repository:&lt;br&gt;
&lt;a href="https://github.com/Bangkah/sentinel" rel="noopener noreferrer"&gt;https://github.com/Bangkah/sentinel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PyPI Package:&lt;br&gt;
&lt;a href="https://pypi.org/project/sentinel-ai-cli/" rel="noopener noreferrer"&gt;https://pypi.org/project/sentinel-ai-cli/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sentinel AI is fully open source and contributions are welcome.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Sentinel AI began as a simple experiment with GitHub Copilot CLI.&lt;/p&gt;

&lt;p&gt;Through iteration, debugging, CI/CD integration, and proper packaging, it became a production-ready cybersecurity tool.&lt;/p&gt;

&lt;p&gt;This project demonstrates how modern AI-assisted development, combined with engineering discipline, can accelerate the creation of real-world tools.&lt;/p&gt;

&lt;p&gt;Sentinel AI is not just a project — it is a foundation for building more advanced security tools in the future.&lt;/p&gt;




&lt;h1&gt;
  
  
  Author
&lt;/h1&gt;

&lt;p&gt;Muhammad Dhiyaul Atha&lt;br&gt;
Computer Science Student &amp;amp; Open Source Developer&lt;/p&gt;

</description>
      <category>githubcopilot</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>devchallenge</category>
    </item>
    <item>
      <title>Saat Laptop Lama Menemukan Peran Barunya</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Fri, 30 Jan 2026 18:11:37 +0000</pubDate>
      <link>https://forem.com/bangkah/saat-laptop-lama-menemukan-peran-barunya-3pha</link>
      <guid>https://forem.com/bangkah/saat-laptop-lama-menemukan-peran-barunya-3pha</guid>
      <description>&lt;h1&gt;
  
  
  Mengubah MacBook Pro 2012 Menjadi Server Pribadi (Eksperimen Pertamaku)
&lt;/h1&gt;

&lt;p&gt;Ada satu MacBook Pro 2012 di hadapanku.&lt;br&gt;
Bukan laptop utama, performanya juga jelas sudah tertinggal jauh dibanding mesin-mesin modern. Tapi justru dari situ muncul satu pertanyaan sederhana:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Sejauh apa laptop lama ini masih bisa berguna?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pertanyaan itu akhirnya membawaku pada sebuah eksperimen kecil: &lt;strong&gt;mengubah MacBook Pro 2012 menjadi server pribadi&lt;/strong&gt;, lalu mengontrolnya dari laptop utamaku menggunakan &lt;strong&gt;SSH&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Latar Belakang: Kenapa Laptop Lama?
&lt;/h2&gt;

&lt;p&gt;Sebagai mahasiswa dan pembelajar di dunia software engineering, aku mulai sadar satu hal:&lt;br&gt;
&lt;strong&gt;belajar server tidak cukup hanya dari teori.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aku bisa membaca dokumentasi, menonton video, atau mengikuti tutorial, tapi tetap ada jarak antara “tahu” dan “pernah mengalami sendiri”.&lt;/p&gt;

&lt;p&gt;Di sisi lain, aku punya:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;MacBook Pro 2012&lt;/strong&gt; yang jarang dipakai&lt;/li&gt;
&lt;li&gt; ketertarikan besar pada Linux&lt;/li&gt;
&lt;li&gt; rasa penasaran tentang bagaimana server bekerja di dunia nyata&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Daripada membiarkannya berdebu, aku memutuskan menjadikannya &lt;strong&gt;server eksperimen&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Pilihan Sistem: Arch Linux di Mesin Tua
&lt;/h2&gt;

&lt;p&gt;Aku memilih &lt;strong&gt;Arch Linux&lt;/strong&gt; untuk MacBook Pro 2012 ini.&lt;/p&gt;

&lt;p&gt;Bukan karena paling mudah — justru sebaliknya.&lt;br&gt;
Tapi karena aku ingin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sistem yang ringan&lt;/li&gt;
&lt;li&gt;kontrol penuh terhadap apa saja yang terpasang&lt;/li&gt;
&lt;li&gt;dan pengalaman belajar yang “apa adanya”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Untuk laptop utamaku, aku menggunakan &lt;strong&gt;Acer Nitro V16 dengan Garuda Linux&lt;/strong&gt;. Dari sinilah semua kontrol dilakukan.&lt;/p&gt;


&lt;h2&gt;
  
  
  Kendala: Tidak Semua Berjalan Mulus
&lt;/h2&gt;

&lt;p&gt;Tentu saja, eksperimen ini tidak langsung berjalan mulus.&lt;/p&gt;

&lt;p&gt;Beberapa kendala yang aku temui:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚠️ &lt;strong&gt;Hardware lama&lt;/strong&gt;: kipas cepat panas, performa terbatas&lt;/li&gt;
&lt;li&gt;⚠️ Konfigurasi Arch Linux yang menuntut ketelitian&lt;/li&gt;
&lt;li&gt;⚠️ Networking yang awalnya membingungkan (IP, service, firewall)&lt;/li&gt;
&lt;li&gt;⚠️ SSH yang sempat gagal konek karena kesalahan kecil&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ada momen frustrasi, terutama saat:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Kenapa sudah install SSH tapi tetap tidak bisa diakses?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Namun justru di titik-titik inilah aku benar-benar belajar:&lt;br&gt;
membaca log, memahami error, dan tidak asal copy–paste perintah.&lt;/p&gt;


&lt;h2&gt;
  
  
  Tujuan: Bukan Sekadar Bisa Remote
&lt;/h2&gt;

&lt;p&gt;Tujuanku bukan hanya:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“bisa login SSH dari laptop lain”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lebih dari itu, aku ingin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;memahami &lt;strong&gt;konsep server secara nyata&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;membiasakan diri mengelola sistem tanpa GUI&lt;/li&gt;
&lt;li&gt;mensimulasikan workflow backend &amp;amp; DevOps sederhana&lt;/li&gt;
&lt;li&gt;dan melatih kebiasaan bekerja secara remote&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Server ini aku anggap sebagai &lt;strong&gt;laboratorium pribadi&lt;/strong&gt;, tempat aman untuk salah dan belajar.&lt;/p&gt;


&lt;h2&gt;
  
  
  Progres: Saat SSH Akhirnya Berhasil
&lt;/h2&gt;

&lt;p&gt;Momen paling memuaskan adalah saat dari Acer Nitro V16 aku menjalankan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh atha@192.xxxx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lalu…&lt;br&gt;
terminal MacBook Pro 2012 muncul di layarku.&lt;/p&gt;

&lt;p&gt;Tidak ada tampilan grafis.&lt;br&gt;
Tidak ada mouse.&lt;br&gt;
Hanya terminal — tapi rasanya seperti membuka pintu ke dunia baru.&lt;/p&gt;

&lt;p&gt;Sekarang aku bisa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mengelola server dari laptop utama&lt;/li&gt;
&lt;li&gt;install service tanpa menyentuh fisik server&lt;/li&gt;
&lt;li&gt;menjadikan MacBook lama sebagai mesin yang “hidup kembali”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dari sini, rencananya akan berlanjut ke:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;web server&lt;/li&gt;
&lt;li&gt;API sederhana&lt;/li&gt;
&lt;li&gt;hardening SSH&lt;/li&gt;
&lt;li&gt;dan mungkin automasi kecil-kecilan&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Penutup
&lt;/h2&gt;

&lt;p&gt;Eksperimen ini mengajarkanku satu hal penting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Belajar server tidak harus mahal.&lt;br&gt;
Kadang, laptop lama dan rasa penasaran sudah cukup.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;MacBook Pro 2012 yang dulu terasa usang, kini punya peran baru.&lt;br&gt;
Bukan sebagai mesin utama, tapi sebagai &lt;strong&gt;guru diam-diam&lt;/strong&gt; yang mengajarkanku tentang sistem, kesabaran, dan proses belajar yang sebenarnya.&lt;/p&gt;

&lt;p&gt;Dan perjalanan ini… baru saja dimulai.&lt;/p&gt;




</description>
      <category>devops</category>
      <category>linux</category>
      <category>learning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Membuat API CRUD di Laravel dengan Sanctum (Step by Step)</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Sun, 11 Jan 2026 15:00:37 +0000</pubDate>
      <link>https://forem.com/bangkah/membuat-api-crud-di-laravel-dengan-sanctum-step-by-step-id</link>
      <guid>https://forem.com/bangkah/membuat-api-crud-di-laravel-dengan-sanctum-step-by-step-id</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"Pernah nggak, frontend kamu butuh data dari backend Laravel, tapi API-nya belum aman? Di artikel ini, kamu akan belajar bikin API CRUD yang hanya bisa diakses user terautentikasi pakai Sanctum."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Kenapa Harus Pakai Sanctum untuk API CRUD?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Data lebih aman, hanya user login yang bisa akses&lt;/li&gt;
&lt;li&gt;Cocok untuk SPA, mobile app, dan aplikasi modern&lt;/li&gt;
&lt;li&gt;Mudah diintegrasikan dengan frontend (React, Vue, dsb)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Studi Kasus: API Artikel (CRUD + Auth)
&lt;/h2&gt;

&lt;p&gt;Kita akan membuat API CRUD Artikel yang hanya bisa diakses user yang sudah login menggunakan Laravel Sanctum.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Setup Project Laravel &amp;amp; Sanctum
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer create-project &lt;span class="nt"&gt;--prefer-dist&lt;/span&gt; laravel/laravel belajar-api
&lt;span class="nb"&gt;cd &lt;/span&gt;belajar-api
composer require laravel/sanctum
php artisan vendor:publish &lt;span class="nt"&gt;--provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Laravel&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="s2"&gt;anctum&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="s2"&gt;anctumServiceProvider"&lt;/span&gt;
php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tambahkan middleware Sanctum di &lt;code&gt;app/Http/Kernel.php&lt;/code&gt; pada group &lt;code&gt;api&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s1"&gt;'api'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nc"&gt;\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'throttle:api'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nc"&gt;\Illuminate\Routing\Middleware\SubstituteBindings&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&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;h2&gt;
  
  
  Step 2: Setup Model User &amp;amp; Artikel (Ownership Data)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  User
&lt;/h3&gt;

&lt;p&gt;Pastikan model &lt;code&gt;User&lt;/code&gt; pakai trait &lt;code&gt;HasApiTokens&lt;/code&gt; dan relasi ke artikel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Laravel\Sanctum\HasApiTokens&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Authenticatable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasApiTokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Notifiable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;articles&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="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasMany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Artikel
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:model Article &lt;span class="nt"&gt;-m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;foreignId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user_id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;constrained&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;cascadeOnDelete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamps&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;Jalankan migrasi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Di model &lt;code&gt;Article.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$fillable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'user_id'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;user&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="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;belongsTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&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;h2&gt;
  
  
  Step 3: Auth Controller (Register, Login, Logout)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:controller Api/AuthController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Contoh fungsi register, login, logout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$validated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|email|unique:users'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|min:6'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api-token'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;plainTextToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'user'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'token'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;only&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;attempt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$credentials&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="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Unauthorized'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api-token'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;plainTextToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'user'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'token'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;currentAccessToken&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Logged out'&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;h2&gt;
  
  
  Step 4: Article Controller (CRUD)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:controller Api/ArticleController &lt;span class="nt"&gt;--resource&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Contoh fungsi CRUD:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index&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="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$validated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'content'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="c1"&gt;// Ownership: artikel milik user login&lt;/span&gt;
    &lt;span class="nv"&gt;$article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;findOrFail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Authorization: hanya pemilik yang boleh akses&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Unauthorized'&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="nv"&gt;$article&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;findOrFail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Unauthorized'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;$validated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'content'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;findOrFail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Unauthorized'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;204&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;h2&gt;
  
  
  Step 5: Route API
&lt;/h2&gt;

&lt;p&gt;Edit &lt;code&gt;routes/api.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controllers\Api\AuthController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controllers\Api\ArticleController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'register'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;AuthController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'register'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'login'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;AuthController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'login'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'auth:sanctum'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'logout'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;AuthController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'logout'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;apiResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ArticleController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&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;h2&gt;
  
  
  Step 6: Testing API CRUD dengan Postman
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Fungsi&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/api/articles&lt;/td&gt;
&lt;td&gt;List semua artikel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/api/articles&lt;/td&gt;
&lt;td&gt;Simpan artikel baru&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/api/articles/{id}&lt;/td&gt;
&lt;td&gt;Detail artikel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;/api/articles/{id}&lt;/td&gt;
&lt;td&gt;Update artikel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;/api/articles/{id}&lt;/td&gt;
&lt;td&gt;Hapus artikel&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Jangan lupa kirim token di header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization: Bearer {token}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Contoh Response JSON
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Belajar Laravel API"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Laravel API itu powerful..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Kenapa API Ini Aman?
&lt;/h2&gt;

&lt;p&gt;Dengan Sanctum + &lt;code&gt;auth:sanctum&lt;/code&gt;, API ini tidak bisa diakses tanpa token. Setiap request divalidasi berdasarkan user yang login, dan hanya pemilik data yang bisa mengakses/mengubah artikelnya sendiri.&lt;/p&gt;




&lt;h2&gt;
  
  
  Kalau Mau Dipakai di Frontend
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;React: simpan token di localStorage, kirim di header Authorization setiap request&lt;/li&gt;
&lt;li&gt;Axios: gunakan interceptor untuk otomatis attach token&lt;/li&gt;
&lt;li&gt;Jangan expose token di public repo!&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Error Handling &amp;amp; Status Code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;201 Created: Data berhasil dibuat&lt;/li&gt;
&lt;li&gt;200 OK: Data berhasil diambil/diupdate&lt;/li&gt;
&lt;li&gt;204 No Content: Data dihapus&lt;/li&gt;
&lt;li&gt;401 Unauthorized: Token salah/expired&lt;/li&gt;
&lt;li&gt;404 Not Found: Data tidak ditemukan&lt;/li&gt;
&lt;li&gt;422 Unprocessable Entity: Validasi gagal&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Common Mistake Pemula
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lupa migrate/publish Sanctum&lt;/li&gt;
&lt;li&gt;Lupa middleware &lt;code&gt;auth:sanctum&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Token tidak dikirim di header&lt;/li&gt;
&lt;li&gt;Lupa set &lt;code&gt;Accept: application/json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Salah endpoint (POST login, bukan GET)&lt;/li&gt;
&lt;li&gt;Salah group route (harus di dalam middleware)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Next Step
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;API Resource (response lebih rapi)&lt;/li&gt;
&lt;li&gt;Pagination &amp;amp; filtering&lt;/li&gt;
&lt;li&gt;Role &amp;amp; permission&lt;/li&gt;
&lt;li&gt;Testing dengan Thunder Client&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Yuk Diskusi &amp;amp; Share!
&lt;/h2&gt;

&lt;p&gt;Kalau kamu stuck di step tertentu, tulis di komentar ya! Share juga pengalaman kamu bikin API CRUD Laravel, atau request topik lanjutan (API Resource, pagination, dsb).&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://laravel.com/docs/10.x/sanctum" rel="noopener noreferrer"&gt;Laravel Sanctum Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://laravel.com/docs/10.x/eloquent-resources" rel="noopener noreferrer"&gt;Laravel API Resource&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://laravel.com/docs/10.x/controllers#resource-controllers" rel="noopener noreferrer"&gt;Laravel CRUD API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>laravel</category>
      <category>crud</category>
      <category>api</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Laravel API Authentication dengan Sanctum</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Sun, 11 Jan 2026 14:50:53 +0000</pubDate>
      <link>https://forem.com/bangkah/laravel-api-authentication-dengan-sanctum-5fm</link>
      <guid>https://forem.com/bangkah/laravel-api-authentication-dengan-sanctum-5fm</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"Pernah nggak, API kamu bisa diakses siapa saja tanpa login? Atau frontend sudah jadi, tapi bingung gimana cara login ke backend Laravel? Di sinilah Laravel Sanctum jadi solusi autentikasi API yang simpel dan powerful."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Kenapa Perlu Autentikasi API?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Melindungi data dari akses sembarangan&lt;/li&gt;
&lt;li&gt;Wajib untuk aplikasi SPA, mobile, dan public API&lt;/li&gt;
&lt;li&gt;User harus login untuk akses data pribadi&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Cara Kerja Sanctum (Token Based Auth)
&lt;/h2&gt;

&lt;p&gt;Laravel Sanctum menggunakan token-based authentication. Artinya, setelah login, user akan mendapatkan token yang harus dikirim di setiap request API melalui header Authorization. Ini membuat API lebih aman dan mudah diintegrasikan dengan frontend atau mobile app.&lt;/p&gt;




&lt;h2&gt;
  
  
  Studi Kasus: API Artikel dengan Login
&lt;/h2&gt;

&lt;p&gt;Di artikel ini, kita akan membuat API Artikel yang hanya bisa diakses user yang sudah login menggunakan Laravel Sanctum.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Install Sanctum
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require laravel/sanctum
php artisan vendor:publish &lt;span class="nt"&gt;--provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Laravel&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="s2"&gt;anctum&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="s2"&gt;anctumServiceProvider"&lt;/span&gt;
php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Command ini akan menambahkan tabel &lt;code&gt;personal_access_tokens&lt;/code&gt; yang digunakan untuk menyimpan token API user.&lt;/p&gt;

&lt;p&gt;Tambahkan middleware Sanctum di &lt;code&gt;app/Http/Kernel.php&lt;/code&gt; pada group &lt;code&gt;api&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s1"&gt;'api'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nc"&gt;\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'throttle:api'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nc"&gt;\Illuminate\Routing\Middleware\SubstituteBindings&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&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;h2&gt;
  
  
  Step 2: Setup Model User
&lt;/h2&gt;

&lt;p&gt;Pastikan model &lt;code&gt;User&lt;/code&gt; pakai trait &lt;code&gt;HasApiTokens&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Laravel\Sanctum\HasApiTokens&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Authenticatable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasApiTokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Notifiable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Membuat Endpoint Auth (Login, Register, Logout)
&lt;/h2&gt;

&lt;p&gt;Buat controller misal &lt;code&gt;AuthController&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;php artisan make:controller Api/AuthController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Contoh fungsi register, login, dan logout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$validated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|email|unique:users'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|min:6'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api-token'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;plainTextToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'user'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'token'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;only&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;attempt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$credentials&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="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Unauthorized'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// hapus token lama, 1 user = 1 token aktif&lt;/span&gt;
    &lt;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api-token'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;plainTextToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'user'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'token'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;currentAccessToken&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Logout akan menghapus token aktif sehingga request berikutnya akan ditolak.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Logged out'&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;h2&gt;
  
  
  Step 4: Route API Auth &amp;amp; Proteksi Artikel
&lt;/h2&gt;

&lt;p&gt;Edit &lt;code&gt;routes/api.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'register'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;AuthController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'register'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'login'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;AuthController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'login'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'auth:sanctum'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'logout'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;AuthController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'logout'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;apiResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ArticleController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&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;h2&gt;
  
  
  Step 5: Testing API Auth dengan Postman
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Register
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /api/register
Content-Type: application/json
{
  "name": "Atha",
  "email": "atha@mail.com",
  "password": "password123"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Login
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /api/login
Content-Type: application/json
{
  "email": "atha@mail.com",
  "password": "password123"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Atha"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1|longapitoken..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Akses Artikel (dengan token)
&lt;/h3&gt;

&lt;p&gt;Tambahkan header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization: Bearer 1|longapitoken...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /api/articles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Error Handling &amp;amp; Status Code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;201 Created: Register sukses&lt;/li&gt;
&lt;li&gt;200 OK: Login sukses, data diambil&lt;/li&gt;
&lt;li&gt;401 Unauthorized: Token salah/expired&lt;/li&gt;
&lt;li&gt;422 Unprocessable Entity: Validasi gagal&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Common Mistake Pemula
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lupa publish/migrate Sanctum&lt;/li&gt;
&lt;li&gt;Lupa tambahkan middleware &lt;code&gt;auth:sanctum&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Token tidak dikirim di header&lt;/li&gt;
&lt;li&gt;Lupa set &lt;code&gt;Accept: application/json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Salah endpoint (POST login, bukan GET)&lt;/li&gt;
&lt;li&gt;Salah group route (harus di dalam middleware)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Next Step
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Refresh token&lt;/li&gt;
&lt;li&gt;Role/permission&lt;/li&gt;
&lt;li&gt;API Resource&lt;/li&gt;
&lt;li&gt;Testing dengan Thunder Client&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Yuk Diskusi &amp;amp; Share!
&lt;/h2&gt;

&lt;p&gt;Kalau kamu stuck di step tertentu, tulis di komentar ya! Share juga pengalaman kamu pakai Sanctum, atau request topik lanjutan (refresh token, role, dsb).&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://laravel.com/docs/10.x/sanctum" rel="noopener noreferrer"&gt;Laravel Sanctum Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://laravel.com/docs/10.x/authentication" rel="noopener noreferrer"&gt;Laravel API Authentication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>laravel</category>
      <category>api</category>
      <category>authentication</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Belajar API Laravel: Dari Problem ke Solusi!</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Sun, 11 Jan 2026 14:24:47 +0000</pubDate>
      <link>https://forem.com/bangkah/belajar-api-laravel-dari-problem-ke-solusi-47p1</link>
      <guid>https://forem.com/bangkah/belajar-api-laravel-dari-problem-ke-solusi-47p1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"Pernah nggak, frontend React kamu gagal ambil data dari backend Laravel? Atau Postman cuma muter-muter nggak dapet respon? Tenang, kamu nggak sendirian! Banyak pemula Laravel ngalamin hal yang sama. Di sinilah API Laravel jadi penyelamat."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ketika kamu bikin frontend React dan backend Laravel, tapi data nggak tampil karena API belum siap — itu frustrasi banget. Nah, artikel ini kasih solusi lengkapnya biar kamu nggak pusing lagi!&lt;/p&gt;




&lt;h2&gt;
  
  
  Kenapa API itu Penting?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;API itu jembatan antara frontend dan backend&lt;/li&gt;
&lt;li&gt;Wajib untuk Single Page Application (SPA) &amp;amp; mobile app&lt;/li&gt;
&lt;li&gt;Tanpa API, data nggak bisa ditampilkan ke user&lt;/li&gt;
&lt;/ul&gt;







&lt;h2&gt;
  
  
  Contoh API Laravel: CRUD Artikel
&lt;/h2&gt;

&lt;p&gt;Di artikel ini, kita bakal bikin &lt;strong&gt;API Artikel&lt;/strong&gt; (CRUD) pakai Laravel. Simpel, tapi bener-bener kepake buat blog, news, atau project latihan.&lt;/p&gt;




&lt;h2&gt;
  
  
  Alur Kerja API Laravel
&lt;/h2&gt;

&lt;p&gt;Sebelum ngoding, pahami dulu alurnya:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client (Postman / Frontend)
→ Request HTTP
→ Route API
→ Controller
→ Model
→ Database
→ Response JSON
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jadi, setiap kali client minta data, request-nya lewat route, diproses controller, ambil data dari model/database, lalu balikin response JSON.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Setup Project Laravel
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Laravel versi terbaru (misal 10.x)&lt;/li&gt;
&lt;li&gt;Pastikan Composer sudah terinstal
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer create-project &lt;span class="nt"&gt;--prefer-dist&lt;/span&gt; laravel/laravel belajar-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setting database di &lt;code&gt;.env&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=belajar_api
DB_USERNAME=root
DB_PASSWORD=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Buat Model &amp;amp; Migration Artikel
&lt;/h2&gt;

&lt;p&gt;Kenapa pakai &lt;code&gt;-m&lt;/code&gt;?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;-m&lt;/code&gt; otomatis bikin migration file, jadi nggak perlu bikin manual.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:model Article &lt;span class="nt"&gt;-m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit migration di &lt;code&gt;database/migrations/..._create_articles_table.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamps&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;Jalankan migrasi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pentingnya &lt;code&gt;$fillable&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Di model &lt;code&gt;Article.php&lt;/code&gt; tambahkan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$fillable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kenapa harus diisi?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Kalau tidak diisi, Laravel tidak bisa menyimpan data karena proteksi mass assignment. Ini fitur keamanan agar data yang masuk ke database benar-benar sesuai yang diizinkan.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 3: Membuat Controller API Artikel
&lt;/h2&gt;

&lt;p&gt;Bikin controller resource:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:controller Api/ArticleController &lt;span class="nt"&gt;--resource&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Penjelasan fungsi-fungsi utama:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;index()&lt;/code&gt; → Ambil semua artikel dari database, balikin dalam bentuk JSON.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;store()&lt;/code&gt; → Simpan artikel baru. Biasanya ambil data dari request, validasi, lalu simpan.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;show($id)&lt;/code&gt; → Ambil detail artikel berdasarkan ID.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;update($id)&lt;/code&gt; → Ubah data artikel tertentu.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;destroy($id)&lt;/code&gt; → Hapus artikel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Contoh implementasi (singkat):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index&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="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Validasi dulu&lt;/span&gt;
    &lt;span class="nv"&gt;$validated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'content'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="c1"&gt;// Simpan data&lt;/span&gt;
    &lt;span class="nv"&gt;$article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&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="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;findOrFail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;findOrFail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$article&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;204&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;h2&gt;
  
  
  Step 4: Menambahkan Route API
&lt;/h2&gt;

&lt;p&gt;Edit &lt;code&gt;routes/api.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;apiResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'articles'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controllers\Api\ArticleController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Cara Testing API dengan Postman
&lt;/h2&gt;

&lt;p&gt;Cek endpoint pakai Postman/curl:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Fungsi&lt;/th&gt;
&lt;th&gt;Contoh Request&lt;/th&gt;
&lt;th&gt;Contoh Response&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/api/articles&lt;/td&gt;
&lt;td&gt;List semua artikel&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ {...} ]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/api/articles&lt;/td&gt;
&lt;td&gt;Simpan artikel baru&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{ "title": "Belajar Laravel API", "content": "Tutorial lengkap &amp;amp; mudah!" }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{ "id": 1, ... }&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/api/articles/{id}&lt;/td&gt;
&lt;td&gt;Detail artikel&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{ "id": 1, ... }&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;/api/articles/{id}&lt;/td&gt;
&lt;td&gt;Update artikel&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{ "title": "Update", "content": "Edit konten" }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{ "id": 1, ... }&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;/api/articles/{id}&lt;/td&gt;
&lt;td&gt;Hapus artikel&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Contoh Lengkap Request &amp;amp; Response
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Request POST:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /api/articles
Content-Type: application/json

{
    "title": "Belajar Laravel API",
    "content": "Tutorial lengkap &amp;amp; mudah!"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Response 201 Created:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Belajar Laravel API"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tutorial lengkap &amp;amp; mudah!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-10"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Request GET:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /api/articles/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Response 200 OK:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Belajar Laravel API"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tutorial lengkap &amp;amp; mudah!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-10"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Request PUT:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PUT /api/articles/1
Content-Type: application/json

{
    "title": "Update Judul",
    "content": "Konten sudah diupdate!"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Response 200 OK:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Update Judul"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Konten sudah diupdate!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-10"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Request DELETE:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DELETE /api/articles/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Response 204 No Content:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;






&lt;h3&gt;
  
  
  Error Handling &amp;amp; Status Code di Laravel
&lt;/h3&gt;

&lt;p&gt;Laravel otomatis mengirim status code sesuai aksi:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;200 OK&lt;/strong&gt;: Data berhasil diambil/diupdate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;201 Created&lt;/strong&gt;: Data berhasil dibuat&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;204 No Content&lt;/strong&gt;: Data berhasil dihapus&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;404 Not Found&lt;/strong&gt;: Data tidak ditemukan&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;422 Unprocessable Entity&lt;/strong&gt;: Validasi gagal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;500 Internal Server Error&lt;/strong&gt;: Error server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Contoh error response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"No query results for model [App&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;Models&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;Article] 99"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tips: Gunakan &lt;code&gt;findOrFail()&lt;/code&gt; untuk otomatis dapat response 404 jika data tidak ditemukan.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistake Pemula
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"Kesalahan umum pemula waktu bikin API Laravel:"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Lupa nambah &lt;code&gt;$fillable&lt;/code&gt; di model, jadi data nggak bisa disimpan.&lt;/li&gt;
&lt;li&gt;Pakai method GET buat simpan data (harusnya POST).&lt;/li&gt;
&lt;li&gt;Nggak validasi input, data jadi berantakan.&lt;/li&gt;
&lt;li&gt;Langsung expose semua field tanpa filter.&lt;/li&gt;
&lt;li&gt;Salah setup &lt;code&gt;.env&lt;/code&gt; (database, port, user/password)&lt;/li&gt;
&lt;li&gt;Menjalankan route di &lt;code&gt;web.php&lt;/code&gt; bukan di &lt;code&gt;api.php&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Lupa restart server setelah ubah konfigurasi&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tips:&lt;/strong&gt; Selalu cek error di response, pastikan method &amp;amp; field sudah benar, dan cek konfigurasi environment!&lt;/p&gt;




&lt;h2&gt;
  
  
  Next Step: Level Up API-mu!
&lt;/h2&gt;

&lt;p&gt;Jangan berhenti di CRUD. Coba explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sanctum / Auth&lt;/strong&gt;: Biar API kamu aman&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Resource&lt;/strong&gt;: Format response lebih rapi&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pagination&lt;/strong&gt;: Untuk data banyak&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate Limiting&lt;/strong&gt;: Biar nggak di-spam&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tunggu artikel lanjutan ya!&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Yuk Diskusi &amp;amp; Share!
&lt;/h2&gt;

&lt;p&gt;Kalau kamu stuck di step tertentu, tulis di komentar ya! Share juga pengalaman kamu bikin API Laravel, atau request topik lanjutan (autentikasi, API resource, pagination, dll).&lt;/p&gt;

&lt;p&gt;Jangan lupa follow &amp;amp; share artikel ini ke teman yang lagi belajar Laravel!&lt;/p&gt;




&lt;h2&gt;
  
  
  Struktur Ringkas
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Masalah yang sering dialami pemula&lt;/li&gt;
&lt;li&gt;Apa yang akan dibuat&lt;/li&gt;
&lt;li&gt;Alur kerja API Laravel&lt;/li&gt;
&lt;li&gt;Setup singkat&lt;/li&gt;
&lt;li&gt;CRUD API step by step&lt;/li&gt;
&lt;li&gt;Testing API&lt;/li&gt;
&lt;li&gt;Kesalahan umum&lt;/li&gt;
&lt;li&gt;Next step / lanjutan&lt;/li&gt;
&lt;/ol&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://laravel.com/docs" rel="noopener noreferrer"&gt;Laravel Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>api</category>
      <category>webdev</category>
    </item>
    <item>
      <title>IDS/IPS Tool: Open Source Modular Intrusion Detection &amp; Prevention System + Real-time Dashboard</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Fri, 19 Dec 2025 22:33:32 +0000</pubDate>
      <link>https://forem.com/bangkah/building-a-modular-idsips-tool-with-python-a-practical-guide-to-network-security-4fgb</link>
      <guid>https://forem.com/bangkah/building-a-modular-idsips-tool-with-python-a-practical-guide-to-network-security-4fgb</guid>
      <description>&lt;p&gt;Keamanan server bukan lagi sekadar pilihan, melainkan keharusan. Di dunia di mana serangan &lt;em&gt;brute force&lt;/em&gt; dan &lt;em&gt;port scanning&lt;/em&gt; terjadi setiap detik, memiliki sistem pertahanan yang ringan dan adaptif adalah kunci.&lt;/p&gt;

&lt;p&gt;Saya mengembangkan &lt;strong&gt;IDS-IPS-Tool&lt;/strong&gt;, sebuah solusi keamanan modular berbasis Python yang dirancang untuk deteksi dini dan pencegahan otomatis. Proyek ini bukan sekadar skrip log, melainkan kerangka kerja (framework) keamanan yang siap pakai.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Kenapa IDS/IPS Tool?
&lt;/h2&gt;

&lt;p&gt;Banyak solusi enterprise sangat kompleks dan berat. &lt;strong&gt;IDS-IPS-Tool&lt;/strong&gt; hadir dengan pendekatan yang berbeda: &lt;strong&gt;Modular, Lightweight, dan Dev-Friendly.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔥 Fitur Utama
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IDS (Intrusion Detection System):&lt;/strong&gt; Analisis file log secara cerdas menggunakan pola Regex untuk mendeteksi &lt;em&gt;failed login&lt;/em&gt;, serangan web, dan anomali lainnya.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IPS (Intrusion Prevention System):&lt;/strong&gt; Tidak hanya mendeteksi, tapi juga menghentikan. Sistem secara otomatis memblokir IP penyerang.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Firewall Backend:&lt;/strong&gt; Mendukung &lt;strong&gt;iptables, ufw,&lt;/strong&gt; dan &lt;strong&gt;nftables&lt;/strong&gt; (firewall standar Linux modern). Sistem dapat mendeteksi backend mana yang tersedia secara otomatis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network IDS (Sniffer):&lt;/strong&gt; Dilengkapi dengan kemampuan &lt;em&gt;sniffing&lt;/em&gt; paket jaringan secara &lt;em&gt;real-time&lt;/em&gt; (ala Suricata) menggunakan library Scapy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern Dashboard:&lt;/strong&gt; Visualisasi data yang ditenagai oleh &lt;strong&gt;FastAPI&lt;/strong&gt; dan &lt;strong&gt;Chart.js&lt;/strong&gt; untuk memantau trafik dan serangan tanpa perlu membuka terminal.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏗️ Tech Stack &amp;amp; Arsitektur
&lt;/h2&gt;

&lt;p&gt;Saya merancang alat ini agar mudah dikembangkan (extensible). Semua logika deteksi dipisahkan dari inti program melalui file konfigurasi JSON.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; FastAPI (Asynchronous &amp;amp; High Performance)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time Log Monitoring:&lt;/strong&gt; Watchdog API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Sniffing:&lt;/strong&gt; Scapy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; HTML5, TailwindCSS, &amp;amp; Chart.js&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Project Structure:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IDS-IPS-Tool/
├── src/           # Modular logic (IDS, IPS, NetIDS)
├── config.json    # Attack signatures &amp;amp; Firewall settings
├── dashboard_main.py # Web UI Entrypoint
├── netids_main.py # Sniffer Entrypoint
└── requirements.txt

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚡ Instalasi &amp;amp; Penggunaan Cepat
&lt;/h2&gt;

&lt;p&gt;Cukup dengan beberapa langkah, Anda bisa mengamankan server Anda:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone &amp;amp; Install:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Bangkah/IDS-IPS-Tool.git
&lt;span class="nb"&gt;cd &lt;/span&gt;IDS-IPS-Tool
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Konfigurasi Firewall:&lt;/strong&gt;
Atur backend favorit Anda di &lt;code&gt;config.json&lt;/code&gt; (auto, nftables, ufw, atau iptables).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jalankan Dashboard:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python dashboard_main.py

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

&lt;/div&gt;



&lt;p&gt;Buka &lt;code&gt;http://localhost:8000&lt;/code&gt; untuk memantau serangan secara real-time!&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Lessons Learned
&lt;/h2&gt;

&lt;p&gt;Dalam membangun proyek ini, saya belajar banyak tentang:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Low-level Networking:&lt;/strong&gt; Bagaimana menangani paket data tanpa membuat &lt;em&gt;bottleneck&lt;/em&gt; pada jaringan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firewall Orchestration:&lt;/strong&gt; Berinteraksi dengan kernel Linux melalui berbagai utilitas firewall secara aman.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI/UX for Security:&lt;/strong&gt; Menyajikan data keamanan yang kompleks menjadi visualisasi yang mudah dipahami.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🤝 Mari Berkolaborasi!
&lt;/h2&gt;

&lt;p&gt;Proyek ini sepenuhnya &lt;em&gt;open-source&lt;/em&gt; dan saya sangat terbuka untuk kontribusi. Apakah itu menambah pola regex baru, integrasi notifikasi Telegram, atau dukungan firewall lainnya.&lt;/p&gt;

&lt;p&gt;⭐ &lt;strong&gt;Pantau proyeknya di GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Bangkah/IDS-IPS-Tool" rel="noopener noreferrer"&gt;Bangkah/IDS-IPS-Tool&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  python #cybersecurity #linux #opensource #fastapi #securityengineer
&lt;/h1&gt;

</description>
      <category>tooling</category>
      <category>security</category>
      <category>opensource</category>
      <category>linux</category>
    </item>
    <item>
      <title>Skip the Boilerplate: Scaffold a Production-Ready Laravel Project in Seconds with Bangkah Starter Kit</title>
      <dc:creator>Muhammad Dhiyaul Atha</dc:creator>
      <pubDate>Tue, 16 Dec 2025 19:30:45 +0000</pubDate>
      <link>https://forem.com/bangkah/skip-the-boilerplate-scaffold-a-production-ready-laravel-project-in-seconds-with-bangkah-starter-31p8</link>
      <guid>https://forem.com/bangkah/skip-the-boilerplate-scaffold-a-production-ready-laravel-project-in-seconds-with-bangkah-starter-31p8</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8u6uq76pu0lclxxzktz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8u6uq76pu0lclxxzktz.png" alt="Bangkah CLI scaffolding a Laravel project" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Bangkah CLI scaffolding a production-ready Laravel project with Docker support.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hello developers 👋&lt;/p&gt;

&lt;p&gt;Setting up a &lt;strong&gt;production-ready Laravel project&lt;/strong&gt; often means repeating the same steps: configuring Docker, setting up Nginx, wiring authentication, preparing environment files, and optimizing builds. While all of this is necessary, it quickly becomes a &lt;strong&gt;time-consuming and repetitive process&lt;/strong&gt;—especially when you start new projects often.&lt;/p&gt;

&lt;p&gt;That’s exactly why I built &lt;strong&gt;Bangkah — a Laravel Starter Kit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bangkah&lt;/strong&gt; is a CLI tool designed to eliminate boilerplate and let you scaffold a &lt;strong&gt;fully configured, production-ready Laravel project in seconds&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔 Why Bangkah? Solving Setup Fatigue
&lt;/h2&gt;

&lt;p&gt;Bangkah goes far beyond a simple &lt;code&gt;composer create-project&lt;/code&gt;. It packages the &lt;strong&gt;essential infrastructure&lt;/strong&gt; needed for modern Laravel applications, so you can focus on &lt;strong&gt;building features&lt;/strong&gt;, not setting up the foundation.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Key Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ Zero-Config Docker Integration
&lt;/h3&gt;

&lt;p&gt;Bangkah generates a complete and ready-to-use &lt;code&gt;docker-compose.yml&lt;/code&gt;, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nginx&lt;/strong&gt; — pre-configured to serve your Laravel application&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PHP-FPM&lt;/strong&gt; — running PHP 8.2+ with required extensions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt; — choose between &lt;strong&gt;MySQL&lt;/strong&gt; or &lt;strong&gt;PostgreSQL&lt;/strong&gt; during setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this setup, you can go from scaffolding to running your app locally using just &lt;strong&gt;one or two Docker commands&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  2️⃣ Dual Application Templates
&lt;/h3&gt;

&lt;p&gt;Not every Laravel project is a monolith. Bangkah provides &lt;strong&gt;two specialized templates&lt;/strong&gt; depending on your use case:&lt;/p&gt;

&lt;h4&gt;
  
  
  🖥️ Web Application Template
&lt;/h4&gt;

&lt;p&gt;Ideal for traditional Laravel web apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication scaffolding (Laravel Breeze or UI)&lt;/li&gt;
&lt;li&gt;Frontend tooling with &lt;strong&gt;Vite&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Standard web routes and structure&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🔌 API Template
&lt;/h4&gt;

&lt;p&gt;Designed for &lt;strong&gt;headless backends&lt;/strong&gt;, SPAs, and mobile apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CORS pre-configured&lt;/li&gt;
&lt;li&gt;API-first structure&lt;/li&gt;
&lt;li&gt;Ready for versioning&lt;/li&gt;
&lt;li&gt;Built-in rate limiting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feownbr685acq83jgzdgf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feownbr685acq83jgzdgf.png" alt="Generated Laravel project structure" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Generated project structure with Docker, Nginx, and Laravel pre-configured.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  3️⃣ Optimized for Speed &amp;amp; Security
&lt;/h3&gt;

&lt;p&gt;Bangkah is built with &lt;strong&gt;performance and best practices&lt;/strong&gt; in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-stage Docker builds&lt;/strong&gt; for smaller and faster images&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimized Composer installs&lt;/strong&gt; for quicker dependency management&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pre-integrated modern UI stacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bootstrap&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Everything is prepared to be &lt;strong&gt;production-friendly from day one&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Get Started
&lt;/h2&gt;

&lt;p&gt;Explore the source code, read the documentation, and try Bangkah today:&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;GitHub Repository&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/Bangkah/bangkah-launcher" rel="noopener noreferrer"&gt;https://github.com/Bangkah/bangkah-launcher&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🤝 We Need Your Collaboration
&lt;/h2&gt;

&lt;p&gt;Bangkah is &lt;strong&gt;100% open source&lt;/strong&gt; and built for the Laravel community. If you’re a Laravel developer, you can help by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Trying it out&lt;/strong&gt; — see how much setup time you save&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharing feedback&lt;/strong&gt; — ideas and suggestions are always welcome&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contributing&lt;/strong&gt; — fork the repo and submit a Pull Request&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s build a faster and cleaner way to launch Laravel projects together 🚀&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Coding!&lt;/strong&gt; 💻✨&lt;/p&gt;




</description>
      <category>productivity</category>
      <category>tooling</category>
      <category>laravel</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
