<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Posts on João Senger</title>
    <link>/en/posts/</link>
    <description>João Senger (Posts)</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-US</language>
    <managingEditor>joaosenger.dev@gmail.com (João Senger)</managingEditor>
    <webMaster>joaosenger.dev@gmail.com (João Senger)</webMaster>
    <lastBuildDate>Thu, 19 Mar 2026 12:10:56 -0300</lastBuildDate>
    
    <atom:link href="/en/posts/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Docker - Basic Commands</title>
      <link>/en/posts/docker-comandos-basicos/</link>
      <pubDate>Thu, 19 Mar 2026 12:10:56 -0300</pubDate>
      <author>joaosenger.dev@gmail.com (João Senger)</author>
      <guid>/en/posts/docker-comandos-basicos/</guid>
      <description>&lt;p&gt;Learn the main Docker commands we use practically every day.&lt;/p&gt;
&lt;h2 id=&#34;introduction&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#introduction&#34;&gt;
        #
    &lt;/a&gt;
    Introduction
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Docker is currently the most widely used tool for container management. One thing that stands out when you start learning Docker is that its commands follow a logical pattern, and understanding that pattern makes container management much easier.&lt;/p&gt;
&lt;h2 id=&#34;understanding-the-pattern&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#understanding-the-pattern&#34;&gt;
        #
    &lt;/a&gt;
    Understanding the pattern
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Almost all Docker commands follow the same pattern:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker OBJECT ACTION [options]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Where:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Object&lt;/strong&gt; is what we want to manage, for example: images, networks, volumes, and so on.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Action&lt;/strong&gt; is the verb, what we want to do, for example: ls, rm, run, inspect, start, stop, etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Options&lt;/strong&gt; are command helpers. For example, the command &lt;strong&gt;&lt;code&gt;docker container ls&lt;/code&gt;&lt;/strong&gt; lists &lt;strong&gt;running&lt;/strong&gt; containers, but if we add the option (or flag) &lt;code&gt;-a&lt;/code&gt;, the output will list all containers, including those that are &lt;strong&gt;stopped&lt;/strong&gt;, like this: &lt;strong&gt;&lt;code&gt;docker container ls -a&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;container-commands&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#container-commands&#34;&gt;
        #
    &lt;/a&gt;
    Container commands
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Containers are running instances created from an image. In daily work, these are the most commonly used commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# List running containers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker container ls
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# List all containers (including stopped ones)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker container ls -a
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Create and start a container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker container run -d --name my-nginx -p 8080:80 nginx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Stop a running container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker container stop my-nginx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Start a stopped container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker container start my-nginx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Remove a stopped container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker container rm my-nginx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Show technical details about a container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker container inspect my-nginx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Show container logs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker container logs my-nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Very common equivalent shortcuts:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker ps        &lt;span style=&#34;color:#78787e&#34;&gt;# equivalent to docker container ls&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker rm &amp;lt;id&amp;gt;   &lt;span style=&#34;color:#78787e&#34;&gt;# equivalent to docker container rm &amp;lt;id&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;image-commands&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#image-commands&#34;&gt;
        #
    &lt;/a&gt;
    Image commands
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Images are the &amp;ldquo;templates&amp;rdquo; used to create containers. They follow the same pattern as well:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# List local images&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker image ls
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Pull an image from a registry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker image pull nginx:latest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Build an image from a Dockerfile&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker image build -t my-api:1.0 .
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Remove an image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker image rm nginx:latest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Show image layer history&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker image &lt;span style=&#34;color:#ff5c57&#34;&gt;history&lt;/span&gt; nginx:latest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Show technical details about an image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker image inspect nginx:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Equivalent shortcuts:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker images          &lt;span style=&#34;color:#78787e&#34;&gt;# equivalent to docker image ls&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker rmi &amp;lt;image&amp;gt;     &lt;span style=&#34;color:#78787e&#34;&gt;# equivalent to docker image rm &amp;lt;image&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;volume-and-network-commands&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#volume-and-network-commands&#34;&gt;
        #
    &lt;/a&gt;
    Volume and network commands
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Volumes and networks are very important support resources for data persistence and communication between containers.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Volumes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker volume ls
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker volume create app-data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker volume inspect app-data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker volume rm app-data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Networks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker network ls
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker network create my-network
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker network inspect my-network
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker network rm my-network
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;cleanup-commands&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#cleanup-commands&#34;&gt;
        #
    &lt;/a&gt;
    Cleanup commands
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Over time, unused resources accumulate in your environment. These commands help with maintenance:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Remove stopped containers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker container prune
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Remove unused images&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker image prune
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Remove unused volumes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker volume prune
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Remove unused networks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker network prune
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# General cleanup (use with care)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker system prune -a
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;practical-daily-workflow&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#practical-daily-workflow&#34;&gt;
        #
    &lt;/a&gt;
    Practical daily workflow
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;A simple and common workflow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check what is running: &lt;code&gt;docker container ls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Check local resources: &lt;code&gt;docker image ls&lt;/code&gt;, &lt;code&gt;docker volume ls&lt;/code&gt;, &lt;code&gt;docker network ls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Start a service: &lt;code&gt;docker container run ...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Validate logs and state: &lt;code&gt;docker container logs ...&lt;/code&gt; and &lt;code&gt;docker container inspect ...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Stop and clean up when needed: &lt;code&gt;docker container stop&lt;/code&gt;, &lt;code&gt;docker container rm&lt;/code&gt;, &lt;code&gt;docker * prune&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;conclusion&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#conclusion&#34;&gt;
        #
    &lt;/a&gt;
    Conclusion
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Once you understand the &lt;code&gt;docker OBJECT ACTION [options]&lt;/code&gt; pattern, learning new commands becomes much easier. Instead of memorizing everything, you start reasoning about what you want to manage and which action you want to perform.&lt;/p&gt;
&lt;p&gt;This pattern applies to almost the entire Docker ecosystem and speeds up day-to-day work.&lt;/p&gt;
&lt;br&gt;
&lt;script type=&#39;text/javascript&#39; src=&#39;https://storage.ko-fi.com/cdn/widget/Widget_2.js&#39;&gt;&lt;/script&gt;&lt;script type=&#39;text/javascript&#39;&gt;kofiwidget2.init(&#39;Buy Me a Coffee&#39;, &#39;#29abe0&#39;, &#39;E1E1GK08T&#39;);kofiwidget2.draw();&lt;/script&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34; data-repo=&#34;joaosenger/blogcomments&#34; data-repo-id=&#34;R_kgDOMUgpYw&#34;
    data-category=&#34;General&#34; data-category-id=&#34;DIC_kwDOMUgpY84Cgsfq&#34; data-mapping=&#34;pathname&#34; data-strict=&#34;0&#34;
    data-reactions-enabled=&#34;1&#34; data-emit-metadata=&#34;0&#34; data-input-position=&#34;bottom&#34;
    data-theme=&#34;preferred_color_scheme&#34; data-lang=&#34;en&#34; crossorigin=&#34;anonymous&#34; async&gt;
&lt;/script&gt;</description>
    </item>
    
    <item>
      <title>Docker - Container stopping after closing SSH session</title>
      <link>/en/posts/docker-container-encerrando-apos-sair-da-sessao-sh-ec2/</link>
      <pubDate>Wed, 19 Mar 2025 13:20:56 -0300</pubDate>
      <author>joaosenger.dev@gmail.com (João Senger)</author>
      <guid>/en/posts/docker-container-encerrando-apos-sair-da-sessao-sh-ec2/</guid>
      <description>&lt;p&gt;Does your container stop when you end the SSH session with the server? Understand what might be happening.&lt;/p&gt;
&lt;h2 id=&#34;introduction&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#introduction&#34;&gt;
        #
    &lt;/a&gt;
    Introduction
&lt;/div&gt;
&lt;/h2&gt;
&lt;h3 id=&#34;the-problem&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#the-problem&#34;&gt;
        ##
    &lt;/a&gt;
    The Problem
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Recently I had to deploy a very simple environment on AWS, it was an application with two containers that were run by &lt;code&gt;Docker Compose&lt;/code&gt;. However, something strange was happening: when I ended the ssh session with the server, the containers immediately became unavailable.&lt;/p&gt;
&lt;h2 id=&#34;investigating-the-problem&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#investigating-the-problem&#34;&gt;
        #
    &lt;/a&gt;
    Investigating the problem
&lt;/div&gt;
&lt;/h2&gt;
&lt;h3 id=&#34;docker-logs&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#docker-logs&#34;&gt;
        ##
    &lt;/a&gt;
    Docker Logs
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;One of the first things I do to investigate an unexpected container stop is to analyze its logs, this can be easily analyzed through the command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker logs container_name
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When analyzing the logs, I noticed the following error:
&lt;code&gt;[Tue Mar 18 19:13:05.229898 2025] [mpm_prefork:notice] [pid 1:tid 1] AH00169: caught SIGTERM, shutting down&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;At first glance, I realized that the action of disconnecting from the server was shutting down the containers, through a &lt;code&gt;SIGTERM&lt;/code&gt; command, which is basically a &lt;code&gt;kill&lt;/code&gt; command to stop a process.&lt;/p&gt;
&lt;h3 id=&#34;looking-for-a-solution&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#looking-for-a-solution&#34;&gt;
        ##
    &lt;/a&gt;
    Looking for a solution
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;When searching the internet about the problem, I discovered that users who ran Docker as regular users and not as &lt;code&gt;root&lt;/code&gt; faced this problem, which makes sense. When a user logs out, all their processes are terminated, meaning when closing the ssh connection all processes were terminated. Important: I was using the &lt;code&gt;ubuntu&lt;/code&gt; user, which is created by EC2 when creating a VM with Ubuntu AMI. To solve the problem I would need to do something so that the processes wouldn&amp;rsquo;t be terminated, this would be my solution.&lt;/p&gt;
&lt;h2 id=&#34;applying-the-solution&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#applying-the-solution&#34;&gt;
        #
    &lt;/a&gt;
    Applying the solution
&lt;/div&gt;
&lt;/h2&gt;
&lt;h3 id=&#34;linger&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#linger&#34;&gt;
        ##
    &lt;/a&gt;
    Linger
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Basically, this little guy makes the user&amp;rsquo;s processes continue running after logout.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Makes processes continue running&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo loginctl enable-linger &lt;span style=&#34;color:#ff6ac1&#34;&gt;$(&lt;/span&gt;whoami&lt;span style=&#34;color:#ff6ac1&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# Makes Docker start automatically for the current user&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemctl --user &lt;span style=&#34;color:#ff5c57&#34;&gt;enable&lt;/span&gt; docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After that, I paused the applications with the &lt;code&gt;docker-compose down&lt;/code&gt; command and brought them up again with &lt;code&gt;docker-compose up -d&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After that, problem solved. 😁&lt;/p&gt;
&lt;br&gt;
&lt;script type=&#39;text/javascript&#39; src=&#39;https://storage.ko-fi.com/cdn/widget/Widget_2.js&#39;&gt;&lt;/script&gt;&lt;script type=&#39;text/javascript&#39;&gt;kofiwidget2.init(&#39;Buy Me a Coffee&#39;, &#39;#29abe0&#39;, &#39;E1E1GK08T&#39;);kofiwidget2.draw();&lt;/script&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34; data-repo=&#34;joaosenger/blogcomments&#34; data-repo-id=&#34;R_kgDOMUgpYw&#34;
    data-category=&#34;General&#34; data-category-id=&#34;DIC_kwDOMUgpY84Cgsfq&#34; data-mapping=&#34;pathname&#34; data-strict=&#34;0&#34;
    data-reactions-enabled=&#34;1&#34; data-emit-metadata=&#34;0&#34; data-input-position=&#34;bottom&#34;
    data-theme=&#34;preferred_color_scheme&#34; data-lang=&#34;en&#34; crossorigin=&#34;anonymous&#34; async&gt;
&lt;/script&gt;</description>
    </item>
    
    <item>
      <title>Understanding: GNU, Linux, FSF and GPL</title>
      <link>/en/posts/linux-entendendo-gnu-fsf-gpl/</link>
      <pubDate>Tue, 11 Mar 2025 20:30:44 -0300</pubDate>
      <author>joaosenger.dev@gmail.com (João Senger)</author>
      <guid>/en/posts/linux-entendendo-gnu-fsf-gpl/</guid>
      <description>&lt;p&gt;Understand what the GNU Project, Linux, Free Software Foundation and the GPL - GNU General Public License are.&lt;/p&gt;
&lt;h2 id=&#34;gnulinux&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#gnulinux&#34;&gt;
        #
    &lt;/a&gt;
    GNU/Linux
&lt;/div&gt;
&lt;/h2&gt;
&lt;h3 id=&#34;brief-history-about-gnu&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#brief-history-about-gnu&#34;&gt;
        ##
    &lt;/a&gt;
    Brief history about GNU
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;In the 1980s, at &lt;a href=&#34;https://en.wikipedia.org/wiki/Massachusetts_Institute_of_Technology&#34; target=&#34;_blanket&#34;&gt;MIT&lt;/a&gt;, a nerd named &lt;a href=&#34;https://en.wikipedia.org/wiki/Richard_Matthew_Stallman&#34; target=&#34;_blanket&#34;&gt;Richard Stallman&lt;/a&gt; was dissatisfied with the development of exclusively proprietary software, where developers and users had no freedom to study the software.&lt;/p&gt;
&lt;p&gt;In 1983 Stallman created the &lt;a href=&#34;https://www.gnu.org/gnu/gnu-history.pt-br.html&#34; target=&#34;_blanket&#34;&gt;GNU Project&lt;/a&gt; (Gnu is Not Unix) with the idea of a free &lt;a href=&#34;https://en.wikipedia.org/wiki/Unix&#34; target=&#34;_blanket&#34;&gt;Unix&lt;/a&gt;, without the restrictions that proprietary software of the time imposed. Thus, he and several programmers enthusiastic about the idea of free software began to develop some of the tools that are used to this day, such as the &lt;strong&gt;GCC&lt;/strong&gt; compiler, &lt;strong&gt;Bash&lt;/strong&gt; and many others.&lt;/p&gt;
&lt;h3 id=&#34;the-birth-of-linux&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#the-birth-of-linux&#34;&gt;
        ##
    &lt;/a&gt;
    The Birth of Linux
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;While the GNU Project advanced in developing a free operating system, an essential component was missing from the system: a free kernel. The kernel is the operating system component responsible for &amp;ldquo;talking&amp;rdquo; to the hardware, it&amp;rsquo;s the bridge that connects the &amp;ldquo;physical&amp;rdquo; part of the computer with the &amp;ldquo;logical&amp;rdquo; part. The GNU Project was developing its own kernel, called &lt;strong&gt;Hurd&lt;/strong&gt;, however, its development progress was slow.&lt;/p&gt;
&lt;p&gt;In 1991 a Finnish student named &lt;a href=&#34;https://en.wikipedia.org/wiki/Linus_Torvalds&#34; target=&#34;_blanket&#34;&gt;Linus Torvalds&lt;/a&gt; began developing his own kernel as a hobby, his goal was to create a system that was Unix-compatible, free and that could run on personal computers.&lt;/p&gt;
&lt;p&gt;Torvalds posted his idea on a forum at the time and invited other programmers to contribute to the project. Thus, the kernel was called Linux (a mix of Linus + Unix).&lt;/p&gt;
&lt;h3 id=&#34;gnulinux-1&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#gnulinux-1&#34;&gt;
        ##
    &lt;/a&gt;
    GNU/Linux
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;The use of GNU Project tools with the Linux kernel resulted in what is now so well known as &lt;b&gt;GNU/Linux&lt;/b&gt;. This fusion was only possible thanks to the characteristics of free software.&lt;/p&gt;
&lt;h2 id=&#34;free-software-foundation-and-gpl&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#free-software-foundation-and-gpl&#34;&gt;
        #
    &lt;/a&gt;
    Free Software Foundation and GPL
&lt;/div&gt;
&lt;/h2&gt;
&lt;h3 id=&#34;free-software-foundation&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#free-software-foundation&#34;&gt;
        ##
    &lt;/a&gt;
    Free Software Foundation
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.fsf.org/&#34; target=&#34;_blanket&#34;&gt;Free Software Foundation&lt;/a&gt; was created in 1985 by Richard Stallman with the goal of promoting free software. The FSF works to ensure that programs can be used, studied, modified and shared freely, without restrictions from companies or governments.&lt;/p&gt;
&lt;h3 id=&#34;gpl-license---gnu-general-public-license&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#gpl-license---gnu-general-public-license&#34;&gt;
        ##
    &lt;/a&gt;
    GPL License - GNU General Public License
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Also created by Stallman, the &lt;a href=&#34;https://www.gnu.org/licenses/&#34; target=&#34;_blanket&#34;&gt;GNU Public License&lt;/a&gt;, GNU GPL or simply GPL is a software license designed to guarantee four fundamental freedoms to users:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Freedom to run the program&lt;/li&gt;
&lt;li&gt;Freedom to study and modify the source code&lt;/li&gt;
&lt;li&gt;Freedom to redistribute copies&lt;/li&gt;
&lt;li&gt;Freedom to distribute modified versions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The marriage between GNU and Linux is largely due to the fact that both share the philosophy of free software and the GPL licenses that are present in both software.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#conclusion&#34;&gt;
        #
    &lt;/a&gt;
    Conclusion
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;GNU/Linux is the operating system that dominates the tech market. It&amp;rsquo;s present in servers, smartphones, smartwatches, smart refrigerators and even on Mars, aboard Ingenuity.&lt;/p&gt;
&lt;p&gt;In summary, GNU is a set of tools and utilities designed to create a free operating system, based on Unix principles. Linux is a kernel that brings the GNU tools to life.&lt;/p&gt;
&lt;p&gt;GNU + Linux = Complete operating system.&lt;/p&gt;
&lt;br&gt;
&lt;script type=&#39;text/javascript&#39; src=&#39;https://storage.ko-fi.com/cdn/widget/Widget_2.js&#39;&gt;&lt;/script&gt;&lt;script type=&#39;text/javascript&#39;&gt;kofiwidget2.init(&#39;Buy Me a Coffee&#39;, &#39;#29abe0&#39;, &#39;E1E1GK08T&#39;);kofiwidget2.draw();&lt;/script&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34; data-repo=&#34;joaosenger/blogcomments&#34; data-repo-id=&#34;R_kgDOMUgpYw&#34;
    data-category=&#34;General&#34; data-category-id=&#34;DIC_kwDOMUgpY84Cgsfq&#34; data-mapping=&#34;pathname&#34; data-strict=&#34;0&#34;
    data-reactions-enabled=&#34;1&#34; data-emit-metadata=&#34;0&#34; data-input-position=&#34;bottom&#34;
    data-theme=&#34;preferred_color_scheme&#34; data-lang=&#34;pt&#34; crossorigin=&#34;anonymous&#34; async&gt;
&lt;/script&gt;</description>
    </item>
    
    <item>
      <title>Django REST framework: CRUD API with JWT Authentication</title>
      <link>/en/posts/django-rest-framework-api-crud-com-autenticacao-jwt/</link>
      <pubDate>Thu, 04 Jul 2024 21:46:06 -0300</pubDate>
      <author>joaosenger.dev@gmail.com (João Senger)</author>
      <guid>/en/posts/django-rest-framework-api-crud-com-autenticacao-jwt/</guid>
      <description>&lt;p&gt;Learn how to create a professional REST API using Django REST framework. Build a complete CRUD with user authentication using JWT.&lt;/p&gt;
&lt;h2 id=&#34;introduction&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#introduction&#34;&gt;
        #
    &lt;/a&gt;
    Introduction
&lt;/div&gt;
&lt;/h2&gt;
&lt;h3 id=&#34;what-will-we-learn&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#what-will-we-learn&#34;&gt;
        ##
    &lt;/a&gt;
    What will we learn?
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Our project will be to create an API for managing tasks (To-Do). We&amp;rsquo;ll use Django users and permissions to access API resources, plus JWT authentication.&lt;/p&gt;
&lt;p&gt;The project code can be found &lt;a href=&#34;https://github.com/joaosenger/todo_api&#34; target=&#34;_blank&#34;&gt;at this link&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This article is not for complete beginners, topics like &lt;code&gt;what is a JWT token&lt;/code&gt;, &lt;code&gt;what is a REST API&lt;/code&gt; or &lt;code&gt;what is the HTTP protocol&lt;/code&gt; will not be covered.&lt;/p&gt;
&lt;h3 id=&#34;what-is-django-rest-framework&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#what-is-django-rest-framework&#34;&gt;
        ##
    &lt;/a&gt;
    What is Django REST framework?
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.django-rest-framework.org/&#34;&gt;Django REST framework&lt;/a&gt; is a toolkit for building Web APIs within the Django ecosystem. It has several ready-made implementations, such as Serializers, Views, authentication and permissions.&lt;/p&gt;
&lt;h3 id=&#34;what-are-the-benefits-of-using-a-framework-for-development&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#what-are-the-benefits-of-using-a-framework-for-development&#34;&gt;
        ##
    &lt;/a&gt;
    What are the benefits of using a Framework for development?
&lt;/div&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security:&lt;/strong&gt; protection against common vulnerabilities, such as SQL Injection, Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ORM (Object-Relational Mapping):&lt;/strong&gt; facilitating work with relational databases, allowing you to manipulate the database using ready-made objects instead of SQL queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Community:&lt;/strong&gt; collaborative development, several programmers test the tool and contribute to the framework&amp;rsquo;s evolution&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Development speed:&lt;/strong&gt; ready-made functionalities can be used for quick and secure project implementation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Maintenance:&lt;/strong&gt; clean and organized code ensures ease in maintenance and implementation of new features&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reliability:&lt;/strong&gt; popular frameworks (like DRF - Django REST framework) are widely used and tested, reducing the probability of bugs and failures.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prerequisites&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#prerequisites&#34;&gt;
        #
    &lt;/a&gt;
    Prerequisites
&lt;/div&gt;
&lt;/h2&gt;
&lt;h3 id=&#34;knowledge&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#knowledge&#34;&gt;
        ##
    &lt;/a&gt;
    Knowledge:
&lt;/div&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Basic knowledge about REST API&lt;/li&gt;
&lt;li&gt;Basic knowledge in web development&lt;/li&gt;
&lt;li&gt;Python: basic knowledge and object orientation&lt;/li&gt;
&lt;li&gt;Basic knowledge about HTTP protocol&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;software&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#software&#34;&gt;
        ##
    &lt;/a&gt;
    Software:
&lt;/div&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.8 or higher&lt;/li&gt;
&lt;li&gt;Code editor (I recommend VSCode)&lt;/li&gt;
&lt;li&gt;Postman or Insomnia (optional)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;initial-setup&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#initial-setup&#34;&gt;
        #
    &lt;/a&gt;
    Initial setup
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;First, let&amp;rsquo;s create a virtual environment for our project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python -m venv venv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff5c57&#34;&gt;source&lt;/span&gt; venv/bin/activate &lt;span style=&#34;color:#78787e&#34;&gt;# for Linux/MacOS users&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.&lt;span style=&#34;color:#5af78e&#34;&gt;\v&lt;/span&gt;env&lt;span style=&#34;color:#5af78e&#34;&gt;\S&lt;/span&gt;cripts&lt;span style=&#34;color:#5af78e&#34;&gt;\A&lt;/span&gt;ctivate.ps1 &lt;span style=&#34;color:#78787e&#34;&gt;# for Windows users&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With the environment created, let&amp;rsquo;s install Django and Django Rest Framework (DRF):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install django &lt;span style=&#34;color:#ff6ac1&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; pip install djangorestframework
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;starting-and-configuring-the-project&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#starting-and-configuring-the-project&#34;&gt;
        ##
    &lt;/a&gt;
    Starting and configuring the project
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Now that we have our environment with Django and DRF installed, let&amp;rsquo;s start a new Django project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;django-admin startproject app .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can test our new project by running the command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python manage.py runserver
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When accessing &lt;a href=&#34;http://127.0.0.1:8000/&#34; target=&#34;_blank&#34;&gt;http://127.0.0.1:8000/&lt;/a&gt; a Django &amp;lsquo;welcome&amp;rsquo; page should be displayed:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;img/django-startproject.png&#34; alt=&#34;Django-welcome&#34;&gt;&lt;/p&gt;
&lt;p&gt;We can stop the server by pressing &lt;code&gt;CTRL+C&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;creating-our-first-application&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#creating-our-first-application&#34;&gt;
        ##
    &lt;/a&gt;
    Creating our first application
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;With our Django project created, we can create a new application, which will be called &lt;code&gt;todo_api&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python manage.py startapp todo_api
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; our project is called &lt;code&gt;app&lt;/code&gt; and in this project we have an application called &lt;code&gt;todo_api&lt;/code&gt;, don&amp;rsquo;t confuse them!&lt;/p&gt;
&lt;p&gt;A new directory called &lt;code&gt;todo_api&lt;/code&gt; was created in our project. We need to add Django REST framework and our application to our project &lt;code&gt;app&lt;/code&gt; settings, for this, access the file &lt;strong&gt;&lt;code&gt;app/settings.py&lt;/code&gt;&lt;/strong&gt; and add &lt;code&gt;todo_api&lt;/code&gt; to &lt;code&gt;INSTALLED_APPS&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# app/settings.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;INSTALLED_APPS &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.admin&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.auth&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.contenttypes&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.sessions&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.messages&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.staticfiles&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;rest_framework&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;todo_api&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we have our project and application configured, we can make our first database operation, which creates an SQLite database and Django&amp;rsquo;s initial tables:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python manage.py migrate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;api-development&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#api-development&#34;&gt;
        #
    &lt;/a&gt;
    API Development
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;With the project and application created and configured, we can start developing the API itself.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll start developing our Model, that is, the model of our API in the database, which will be simple.&lt;/p&gt;
&lt;h3 id=&#34;models-and-serializers&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#models-and-serializers&#34;&gt;
        ##
    &lt;/a&gt;
    Models and Serializers
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Our model will have only three fields: id, task and done, being:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;id:&lt;/strong&gt; automatically created by Django, we don&amp;rsquo;t need to declare it (how convenient!)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;task:&lt;/strong&gt; will be the name of our &amp;ldquo;task&amp;rdquo;, will be a &lt;code&gt;CharField&lt;/code&gt; type data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;done:&lt;/strong&gt; will be the status of our task, will be a &lt;code&gt;boolean&lt;/code&gt; (true/false)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Open the file &lt;code&gt;todo_api/models.py&lt;/code&gt; and insert the following code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# todo_api/models.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; django.db &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; models
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#f3f99d&#34;&gt;Todo&lt;/span&gt;(models&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    task &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;CharField(max_length&lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff9f43&#34;&gt;250&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    done &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; models&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;BooleanField()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff6ac1&#34;&gt;def&lt;/span&gt; __str__(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ff6ac1&#34;&gt;return&lt;/span&gt; self&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;task
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Django will interpret this model and automatically create the table in the database according to our specifications, we don&amp;rsquo;t need to worry about SQL, this is one of the facilities that Django ORM brings us.&lt;/p&gt;
&lt;p&gt;For Django to &amp;ldquo;read&amp;rdquo; the &lt;code&gt;models&lt;/code&gt; files of our project, we need to run the command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python manage.py makemigrations
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After that, we run the &lt;code&gt;migrate&lt;/code&gt; command to apply:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python manage.py migrate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A table will be created in your local database (SQLite) with the name &lt;code&gt;todo_todo_api&lt;/code&gt;, that is: &lt;code&gt;modelname_appname&lt;/code&gt;. The &lt;strong&gt;id&lt;/strong&gt;, &lt;strong&gt;task&lt;/strong&gt; and &lt;strong&gt;done&lt;/strong&gt; fields will also be created.&lt;/p&gt;
&lt;p&gt;Our model was created, however, API data must travel in &lt;strong&gt;JSON&lt;/strong&gt; format, not in database object format, to &amp;ldquo;serialize&amp;rdquo; our data from object to json, we need to create a &lt;strong&gt;serializer&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;As everything in Django is simple, this functionality is already ready, just use it!&lt;/p&gt;
&lt;p&gt;Create a file called &lt;code&gt;serializers.py&lt;/code&gt; inside your &lt;code&gt;todo_api&lt;/code&gt; app: &lt;strong&gt;todo_api/serializers.py&lt;/strong&gt; and insert the code below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# todo_api/serializers.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; rest_framework &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; serializers
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; todo_api.models &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; Todo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#f3f99d&#34;&gt;TodoSerializer&lt;/span&gt;(serializers&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;ModelSerializer):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff6ac1&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#f3f99d&#34;&gt;Meta&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        model &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; Todo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        fields &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;__all__&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Basically we import our &lt;code&gt;Todo&lt;/code&gt; Model, which is the representation of our data in the database and use Django REST framework&amp;rsquo;s &lt;code&gt;ModelSerializer&lt;/code&gt;, which will serialize automatically. We also inform that we want to serialize all fields with &lt;code&gt;fields = __all__&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;views-and-view-classes&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#views-and-view-classes&#34;&gt;
        ##
    &lt;/a&gt;
    Views and View Classes
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;todo_api/views.py&lt;/code&gt; file is responsible for our API&amp;rsquo;s business logic, here all the logic of our CRUD will be implemented. As our API is simple, we&amp;rsquo;ll use two ready-made DRF classes to abstract operations, being:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ListCreateAPIView&lt;/strong&gt;: responsible for &lt;code&gt;GET&lt;/code&gt; and &lt;code&gt;POST&lt;/code&gt; verbs, lists all tasks and allows creating a new task.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RetrieveUpdateDestroyAPIView&lt;/strong&gt;: works with task ids, here we can use all http verbs: &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;. We can list, change or delete tasks according to their unique id.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Inside the file &lt;code&gt;todo_api/views.py&lt;/code&gt; insert the code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# todo_api/views.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; rest_framework &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; generics
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; todo_api.models &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; Todo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; todo_api.serializers &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; TodoSerializer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#f3f99d&#34;&gt;TodoCreateListView&lt;/span&gt;(generics&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;ListCreateAPIView):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    queryset &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; Todo&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;all()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    serializer_class &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; TodoSerializer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#f3f99d&#34;&gt;TodoRetrieveUpdateDestroyView&lt;/span&gt;(generics&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;RetrieveUpdateDestroyAPIView):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    queryset &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; Todo&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;all()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    serializer_class &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; TodoSerializer
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We created two classes, one for each DRF View Class, now, we can configure our URLs to send requests to our views.&lt;/p&gt;
&lt;h2 id=&#34;urls-and-api-versioning&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#urls-and-api-versioning&#34;&gt;
        #
    &lt;/a&gt;
    URLs and API Versioning
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Inside the &lt;code&gt;todo_api&lt;/code&gt; directory create a file called &lt;code&gt;urls.py&lt;/code&gt; and insert the code below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# todo_api/urls.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; django.urls &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; path
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; . &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; views
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;urlpatterns &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    path(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;todos/&amp;#39;&lt;/span&gt;, views&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;TodoCreateListView&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;as_view(), name&lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;todo-create-list-view&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    path(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;todos/&amp;lt;int:pk&amp;gt;&amp;#39;&lt;/span&gt;, views&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;TodoRetrieveUpdateDestroyView&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;as_view(), name&lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;todo-detail-view&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This piece of code informs that when accessing our api on the route &lt;strong&gt;/todos/&lt;/strong&gt; and &lt;strong&gt;/todos/id/&lt;/strong&gt; Django should use the view configured previously.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not a good practice to access routes directly, the good practice is to use url versioning, that is, before accessing the path &lt;strong&gt;/todos/&lt;/strong&gt;, for example, we access &lt;strong&gt;/api/v1/todos/&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This ensures that in a new implementation, in case of a v2, clients using the &lt;strong&gt;/v1/&lt;/strong&gt; endpoint are not affected.&lt;/p&gt;
&lt;p&gt;To implement versioning, access the file &lt;code&gt;app/urls.py&lt;/code&gt; and insert the code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# app/urls.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; django.contrib &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; admin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; django.urls &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; path, include
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;urlpatterns &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    path(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;admin/&amp;#39;&lt;/span&gt;, admin&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;site&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;urls),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    path(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;api/v1/&amp;#39;&lt;/span&gt;, include(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;todo_api.urls&amp;#39;&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We use Django&amp;rsquo;s &lt;strong&gt;include&lt;/strong&gt; to create versioning, now, our api will be accessed by: &lt;a href=&#34;http://127.0.0.1:8000/api/v1/todos/&#34; target=&#34;_blank&#34;&gt;http://127.0.0.1:8000/api/v1/todos/&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;api-working-first-test&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#api-working-first-test&#34;&gt;
        ##
    &lt;/a&gt;
    API working, first test!
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Our API is already functional, we can test it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python manage&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;py runserver
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Access &lt;a href=&#34;http://127.0.0.1:8000/api/v1/todos/&#34; target=&#34;_blank&#34;&gt;http://127.0.0.1:8000/api/v1/todos/&lt;/a&gt; and create some tasks.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;img/drf_post.png&#34; alt=&#34;drf-post&#34;&gt;&lt;/p&gt;
&lt;p&gt;When accessing the url passing some &lt;strong&gt;id&lt;/strong&gt;, we can see the &lt;code&gt;RetrieveUpdateDestroyAPIView&lt;/code&gt; in action, with options to view, change or delete a specific resource.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;img/drf_retrieve_update_destroy.png&#34; alt=&#34;drf-get-put-delete&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;django-admin---user-creation-and-management&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#django-admin---user-creation-and-management&#34;&gt;
        ##
    &lt;/a&gt;
    Django ADMIN - User creation and management
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Django already brings us a ready platform to manage users, user groups and database Models.&lt;/p&gt;
&lt;p&gt;To create the first user (root) type in the terminal:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python manage.py createsuperuser
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;img/django-createsuperuser.png&#34; alt=&#34;django-create-superuser&#34;&gt;&lt;/p&gt;
&lt;p&gt;To add our model to Django Admin, access the file &lt;code&gt;todo_api/admin&lt;/code&gt; and insert the code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# todo_api/admin.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; django.contrib &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; admin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; todo_api.models &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; Todo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff9f43&#34;&gt;@admin.register&lt;/span&gt;(Todo)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#f3f99d&#34;&gt;TodoAdmin&lt;/span&gt;(admin&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;ModelAdmin):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    list_display &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;task&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;done&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Run the server:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python manage.py runserver
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Access the django admin url:
&lt;a href=&#34;http://127.0.0.1:8000/admin/&#34; target=&#34;_blank&#34;&gt;http://127.0.0.1:8000/admin/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;img/django-admin.png&#34; alt=&#34;django-admin&#34;&gt;&lt;/p&gt;
&lt;p&gt;Enter your credentials and access the dashboard.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;img/django-admin-dashboard.png&#34; alt=&#34;django-dashboard&#34;&gt;&lt;/p&gt;
&lt;p&gt;Create at least one user, without admin credentials for us to proceed.&lt;/p&gt;
&lt;h3 id=&#34;security---jwt-authentication-and-endpoint-protection&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#security---jwt-authentication-and-endpoint-protection&#34;&gt;
        ##
    &lt;/a&gt;
    Security - JWT Authentication and endpoint protection
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;With our CRUD ready and django admin managing users, we can start our API authentication.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll require that only authenticated users have access to the API, plus we&amp;rsquo;ll protect our endpoints, where only authenticated and permitted users can access the API and execute actions.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install Django REST framework Simple JWT&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pip install djangorestframework-simplejwt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;In the project configuration, &lt;code&gt;app/settings.py&lt;/code&gt; add the code below at the end of the file:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# app/settings.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;REST_FRAMEWORK &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;DEFAULT_AUTHENTICATION_CLASSES&amp;#39;&lt;/span&gt;: (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;rest_framework_simplejwt.authentication.JWTAuthentication&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SIMPLE_JWT &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#34;ACCESS_TOKEN_LIFETIME&amp;#34;&lt;/span&gt;: timedelta(days&lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff9f43&#34;&gt;1&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#34;REFRESH_TOKEN_LIFETIME&amp;#34;&lt;/span&gt;: timedelta(days&lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff9f43&#34;&gt;7&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At the beginning of the file, import &lt;code&gt;timedelta&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; datetime &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; timedelta
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this code we configure that authentication will be done by Simple JWT and what will be the token lifetime before it expires.&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Creating the endpoint to generate the token&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We need to create an endpoint to generate our jwt token. We&amp;rsquo;ll create a new application to be responsible for authentication:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;python manage.py startapp authentication
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add the new app in the file &lt;code&gt;app/settings.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;INSTALLED_APPS &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.admin&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.auth&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.contenttypes&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.sessions&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.messages&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;django.contrib.staticfiles&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;rest_framework&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;todo&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;authentication&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Inside this new app, create a file called &lt;code&gt;urls.py&lt;/code&gt; and insert the code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# authentication/urls.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; django.urls &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; path
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; rest_framework_simplejwt.views &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; TokenObtainPairView, TokenRefreshView, TokenVerifyView
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;urlpatterns &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    path(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;authentication/token/&amp;#39;&lt;/span&gt;, TokenObtainPairView&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;as_view(), name&lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;token-obtain-pair-view&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    path(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;authentication/token/refresh/&amp;#39;&lt;/span&gt;, TokenRefreshView&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;as_view(), name&lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;token-refresh-vier&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    path(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;authentication/token/verify&amp;#39;&lt;/span&gt;, TokenVerifyView&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;as_view(), name&lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;token-verify-view&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;re creating endpoints to generate our JWT token, its refresh and verify.&lt;/p&gt;
&lt;p&gt;All this is abstracted by DRF, we don&amp;rsquo;t need to create everything by hand.&lt;/p&gt;
&lt;p&gt;Now, in the file &lt;code&gt;app/urls.py&lt;/code&gt; we&amp;rsquo;ll import our new endpoints, the code should look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# app/urls.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; django.contrib &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; admin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; django.urls &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; path, include
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;urlpatterns &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    path(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;admin/&amp;#39;&lt;/span&gt;, admin&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;site&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;urls),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    path(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;api/v1/&amp;#39;&lt;/span&gt;, include(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;authentication.urls&amp;#39;&lt;/span&gt;)), &lt;span style=&#34;color:#78787e&#34;&gt;# endpoint for authentication&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    path(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;api/v1/&amp;#39;&lt;/span&gt;, include(&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;todo_api.urls&amp;#39;&lt;/span&gt;)),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, let&amp;rsquo;s protect our views. In the file &lt;code&gt;todo/views.py&lt;/code&gt; we&amp;rsquo;ll add &lt;code&gt;permission_classes&lt;/code&gt; to our routes, this is a DRF resource used to protect routes. The file should look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# todo/views.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; rest_framework &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; generics
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; rest_framework.permissions &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; IsAuthenticated
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; todo_api.models &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; Todo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; todo_api.serializers &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; TodoSerializer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#f3f99d&#34;&gt;TodoCreateListView&lt;/span&gt;(generics&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;ListCreateAPIView):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    permission_classes &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; (IsAuthenticated, )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    queryset &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; Todo&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;all()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    serializer_class &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; TodoSerializer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#f3f99d&#34;&gt;TodoRetrieveUpdateDestroyView&lt;/span&gt;(generics&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;RetrieveUpdateDestroyAPIView):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    permission_classes &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; (IsAuthenticated, )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    queryset &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; Todo&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;all()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    serializer_class &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; TodoSerializer
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, when trying to access any resource from our API, it won&amp;rsquo;t be possible. See:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;img/drf-rota-protegida.png&#34; alt=&#34;drf-IsAuthenticated&#34;&gt;&lt;/p&gt;
&lt;p&gt;To access, it will be necessary to generate a JWT Token on the route &lt;code&gt;api/v1/authentication/token/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;From here, we&amp;rsquo;ll use Postman to make requests to the API, as we&amp;rsquo;ll have to inform the token in our requests.&lt;/p&gt;
&lt;p&gt;Access Postman and make a &lt;code&gt;POST&lt;/code&gt; request to the url &lt;code&gt;127.0.0.1:8000/api/v1/authentication/token/&lt;/code&gt; passing the username/password in the request &lt;code&gt;body&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#ff6ac1&#34;&gt;&amp;#34;username&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#34;yourusername&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#ff6ac1&#34;&gt;&amp;#34;password&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#34;yourpassword&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When making the request informing the user and password you created in Django Admin, an Access Token and a Verify Token will be returned, however, in this tutorial we&amp;rsquo;ll only use the access token:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;img/drf-simplejwt.png&#34; alt=&#34;drf-simplejwt&#34;&gt;&lt;/p&gt;
&lt;p&gt;Copy the &lt;code&gt;access token&lt;/code&gt; and make a new request on the route &lt;code&gt;127.0.0.1:8000/api/v1/todos&lt;/code&gt; passing the copied token in &lt;code&gt;Authorization &amp;gt; Bearer Token&lt;/code&gt;, as shown in the image below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;img/drf-jwt-authenticated.png&#34; alt=&#34;drf-jwt-authenticated&#34;&gt;&lt;/p&gt;
&lt;p&gt;With this, only authenticated users can access our tasks. But what if I want some user to have read-only permission, but not data modification? that is, can do a &lt;code&gt;GET&lt;/code&gt;, but not a &lt;code&gt;PUT&lt;/code&gt;? To solve this problem, we&amp;rsquo;ll use user permissions.&lt;/p&gt;
&lt;h3 id=&#34;user-permissions&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#user-permissions&#34;&gt;
        ##
    &lt;/a&gt;
    User Permissions
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;At this point only authenticated users can use the API, however, we want to restrict access for these users. For example, a certain user may only have read permission &lt;code&gt;GET&lt;/code&gt;, while another user can read and create new tasks &lt;code&gt;GET&lt;/code&gt; and &lt;code&gt;POST&lt;/code&gt;, while another type of user can do all actions. For this, we&amp;rsquo;ll use Django user permissions.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s create two examples, the first will be a group of users that can only do &lt;code&gt;GET&lt;/code&gt; and the second with all permissions.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Access Django Admin&lt;/li&gt;
&lt;li&gt;Click on &amp;ldquo;Groups&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Create a group called &lt;code&gt;&amp;quot;read_only&amp;quot;&lt;/code&gt; and give the permission &lt;code&gt;Todo_Api | todo | Can view todo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Save&lt;/li&gt;
&lt;li&gt;Repeat the process, now create a group called &lt;code&gt;&amp;quot;full_access&amp;quot;&lt;/code&gt; and give the permissions:
&lt;code&gt;Todo_Api | todo | Can view todo&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Todo_Api | todo | Can add todo&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Todo_Api | todo | Can delete todo&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Todo_Api | todo | Can change todo&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Example of creating the &amp;ldquo;full_access&amp;rdquo; group:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;img/django-admin-group.png&#34; alt=&#34;django-admin-group&#34;&gt;&lt;/p&gt;
&lt;p&gt;Now we have two user groups with different permissions, this is the best practice for user permission management.&lt;/p&gt;
&lt;p&gt;Now, we need to inform in the code that users besides being authenticated must have permission to execute actions in the API.&lt;/p&gt;
&lt;p&gt;Inside &lt;code&gt;app&lt;/code&gt; create a file called &lt;code&gt;permissions.py&lt;/code&gt; and insert the code below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# app/permissions.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; rest_framework &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; permissions
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#f3f99d&#34;&gt;GlobalDefaultPermission&lt;/span&gt;(permissions&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;BasePermission):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff6ac1&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#57c7ff&#34;&gt;has_permission&lt;/span&gt;(self, request, view):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        model_permission_codename &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;__get_model_permission_codename(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            method&lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt;request&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;method,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            view&lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt;view,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        )
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ff6ac1&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#ff6ac1&#34;&gt;not&lt;/span&gt; model_permission_codename:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#ff6ac1&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff6ac1&#34;&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ff6ac1&#34;&gt;return&lt;/span&gt; request&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;user&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;has_perm(model_permission_codename)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff6ac1&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#57c7ff&#34;&gt;__get_model_permission_codename&lt;/span&gt;(self, method, view):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ff6ac1&#34;&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            model_name &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; view&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;queryset&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;model&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;_meta&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;model_name
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            app_label &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; view&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;queryset&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;model&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;_meta&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;app_label
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            action &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;__get_action_sufix(method)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#ff6ac1&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#5af78e&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;{&lt;/span&gt;app_label&lt;span style=&#34;color:#5af78e&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;{&lt;/span&gt;action&lt;span style=&#34;color:#5af78e&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;{&lt;/span&gt;model_name&lt;span style=&#34;color:#5af78e&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ff6ac1&#34;&gt;except&lt;/span&gt; AttributeError:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#ff6ac1&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ff6ac1&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff6ac1&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#57c7ff&#34;&gt;__get_action_sufix&lt;/span&gt;(self, method):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        method_actions &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;GET&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;view&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;add&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;PUT&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;change&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;PATCH&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;change&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;DELETE&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;delete&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;OPTIONS&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;view&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;HEAD&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;view&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ff6ac1&#34;&gt;return&lt;/span&gt; method_actions&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;get(method, &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This code overwrites the &lt;code&gt;has_permission&lt;/code&gt; function inherited from &lt;code&gt;permissions.BasePermission&lt;/code&gt;. This function should return &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;. The code checks if the user has attached permission and returns &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Finally, let&amp;rsquo;s add this permission class to our &lt;code&gt;views&lt;/code&gt; file. In the file &lt;code&gt;todo_api/views.py&lt;/code&gt; import the &lt;code&gt;GlobalDefaultPermission&lt;/code&gt; class created previously and include it in the &lt;code&gt;permission_classes&lt;/code&gt;. The code should look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#78787e&#34;&gt;# todo_api/views.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; rest_framework &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; generics
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; rest_framework.permissions &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; IsAuthenticated
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; todo_api.models &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; Todo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; todo_api.serializers &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; TodoSerializer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;from&lt;/span&gt; app.permissions &lt;span style=&#34;color:#ff6ac1&#34;&gt;import&lt;/span&gt; GlobalDefaultPermission
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#f3f99d&#34;&gt;TodoCreateListView&lt;/span&gt;(generics&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;ListCreateAPIView):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    permission_classes &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; (IsAuthenticated, GlobalDefaultPermission)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    queryset &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; Todo&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;all()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    serializer_class &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; TodoSerializer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff6ac1&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#f3f99d&#34;&gt;TodoRetrieveUpdateDestroyView&lt;/span&gt;(generics&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;RetrieveUpdateDestroyAPIView):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    permission_classes &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; (IsAuthenticated, GlobalDefaultPermission)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    queryset &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; Todo&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color:#ff6ac1&#34;&gt;.&lt;/span&gt;all()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    serializer_class &lt;span style=&#34;color:#ff6ac1&#34;&gt;=&lt;/span&gt; TodoSerializer
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;tests&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#tests&#34;&gt;
        #
    &lt;/a&gt;
    Tests
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;In Django Admin, create a user and put them in the &lt;code&gt;read_only&lt;/code&gt; group, it will work normally, then try to register a new task, you won&amp;rsquo;t have permission. After that, add the &lt;code&gt;full_access&lt;/code&gt; group to the user and try again, you&amp;rsquo;ll be able to create the task.&lt;/p&gt;
&lt;p&gt;Example of access attempt with a user without permission:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;img/sem_permissao.png&#34; alt=&#34;sem-permissao&#34;&gt;&lt;/p&gt;
&lt;p&gt;Now with the user being part of the &lt;code&gt;read_only&lt;/code&gt; group:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;img/com-permissao.png&#34; alt=&#34;sem-permissao&#34;&gt;&lt;/p&gt;
&lt;p&gt;Thus, our API is complete. We perform CRUD operations with authenticated users and protected routes.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#conclusion&#34;&gt;
        #
    &lt;/a&gt;
    Conclusion
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;In this article we learned to use Django REST framework to create a REST API in a simple, secure and professional way. The work of a Backend developer is often tied to CRUD operations in the database, plus data modeling and application security. This API doesn&amp;rsquo;t aim to exhaust all development best practices, but to guide beginning developers about practices used in the market.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#next-steps&#34;&gt;
        #
    &lt;/a&gt;
    Next steps
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;We can always improve our project, in the future we&amp;rsquo;ll implement some functionalities, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Flake8 linter configuration for code standardization according to PEP 8&lt;/li&gt;
&lt;li&gt;Create API documentation with Swagger&lt;/li&gt;
&lt;li&gt;Create a Dockerfile to run the application as a container&lt;/li&gt;
&lt;li&gt;Deploy the API on AWS with a complete Pipeline (CodeCommit + CodePipeline + CodeBuild + ECR + ECS with Fargate)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These contents will be published soon here on the blog.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll be waiting for you. 😁&lt;/p&gt;
&lt;br&gt;
&lt;script type=&#39;text/javascript&#39; src=&#39;https://storage.ko-fi.com/cdn/widget/Widget_2.js&#39;&gt;&lt;/script&gt;&lt;script type=&#39;text/javascript&#39;&gt;kofiwidget2.init(&#39;Buy Me a Coffee&#39;, &#39;#29abe0&#39;, &#39;E1E1GK08T&#39;);kofiwidget2.draw();&lt;/script&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34; data-repo=&#34;joaosenger/blogcomments&#34; data-repo-id=&#34;R_kgDOMUgpYw&#34;
    data-category=&#34;General&#34; data-category-id=&#34;DIC_kwDOMUgpY84Cgsfq&#34; data-mapping=&#34;pathname&#34; data-strict=&#34;0&#34;
    data-reactions-enabled=&#34;1&#34; data-emit-metadata=&#34;0&#34; data-input-position=&#34;bottom&#34;
    data-theme=&#34;preferred_color_scheme&#34; data-lang=&#34;pt&#34; crossorigin=&#34;anonymous&#34; async&gt;
&lt;/script&gt;</description>
    </item>
    
    <item>
      <title>What is Linux and what are Linux distributions</title>
      <link>/en/posts/o-que-e-linux-e-o-que-sao-distros-linux/</link>
      <pubDate>Tue, 11 Jun 2024 07:36:03 -0300</pubDate>
      <author>joaosenger.dev@gmail.com (João Senger)</author>
      <guid>/en/posts/o-que-e-linux-e-o-que-sao-distros-linux/</guid>
      <description>&lt;p&gt;Understand what Linux is and what Linux distributions are in a brief and succinct way.&lt;/p&gt;
&lt;h2 id=&#34;what-is-linux&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#what-is-linux&#34;&gt;
        #
    &lt;/a&gt;
    What is Linux?
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Linux is a &lt;strong&gt;Kernel&lt;/strong&gt;, created in 1991 by &lt;strong&gt;Linus Torvalds&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Kernel&lt;/strong&gt; is the operating system component responsible for &amp;ldquo;talking&amp;rdquo; to the hardware, it&amp;rsquo;s the bridge that connects the &amp;ldquo;physical&amp;rdquo; part of the computer with the &amp;ldquo;logical&amp;rdquo; part.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&#34;img/kernel.png&#34; alt=&#34;Kernel&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;linux-distributions&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#linux-distributions&#34;&gt;
        #
    &lt;/a&gt;
    Linux Distributions
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;The Kernel is just one part of a Linux distribution, responsible for hardware communication with the operating system&amp;rsquo;s application layer. On the other hand, a Linux distribution is the use of the Linux Kernel with other tools, in order to create a usable operating system, with interface, applications, administrative tools and various other functionalities.&lt;/p&gt;
&lt;p&gt;Some examples of Linux distributions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Debian&lt;/li&gt;
&lt;li&gt;RedHat&lt;/li&gt;
&lt;li&gt;openSUSE&lt;/li&gt;
&lt;li&gt;Slackware&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#conclusion&#34;&gt;
        #
    &lt;/a&gt;
    Conclusion
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Linux&lt;/strong&gt; is the kernel, the core of the system. It handles communication between hardware (CPU, Memory and Devices) and the logical part of the system (applications).&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;Linux Distribution&lt;/strong&gt; is a collection of software that uses the Linux Kernel, bringing to life a usable operating system based on the Linux Kernel.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s worth noting that this post doesn&amp;rsquo;t aim to exhaust the understanding of what Linux and Linux Distributions are, it&amp;rsquo;s just an overview of a very broad topic discussed in the community.&lt;/p&gt;
&lt;h2 id=&#34;want-to-know-more-about-the-topic&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#want-to-know-more-about-the-topic&#34;&gt;
        #
    &lt;/a&gt;
    Want to know more about the topic?
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.redhat.com/pt-br/topics/linux&#34; target=&#34;_blank&#34;&gt;RedHat: conheça o Linux&lt;/a&gt;&lt;br&gt;
&lt;a href=&#34;https://learning.lpi.org/pt/learning-materials/010-160/1/1.1/1.1_01/&#34; target=&#34;_blank&#34;&gt;LPI: A evolução do Linux e sistemas operacionais populares&lt;/a&gt;&lt;br&gt;
&lt;a href=&#34;https://www.guiafoca.org/guiaonline/iniciante/&#34; target=&#34;_blank&#34;&gt;GuiaFoca Linux - Iniciante&lt;/a&gt;&lt;/p&gt;
&lt;br&gt;
&lt;script type=&#39;text/javascript&#39; src=&#39;https://storage.ko-fi.com/cdn/widget/Widget_2.js&#39;&gt;&lt;/script&gt;&lt;script type=&#39;text/javascript&#39;&gt;kofiwidget2.init(&#39;Buy Me a Coffee&#39;, &#39;#29abe0&#39;, &#39;E1E1GK08T&#39;);kofiwidget2.draw();&lt;/script&gt;
&lt;script src=&#34;https://giscus.app/client.js&#34; data-repo=&#34;joaosenger/blogcomments&#34; data-repo-id=&#34;R_kgDOMUgpYw&#34;
    data-category=&#34;General&#34; data-category-id=&#34;DIC_kwDOMUgpY84Cgsfq&#34; data-mapping=&#34;pathname&#34; data-strict=&#34;0&#34;
    data-reactions-enabled=&#34;1&#34; data-emit-metadata=&#34;0&#34; data-input-position=&#34;bottom&#34;
    data-theme=&#34;preferred_color_scheme&#34; data-lang=&#34;pt&#34; crossorigin=&#34;anonymous&#34; async&gt;
&lt;/script&gt;</description>
    </item>
    
    <item>
      <title>How to Host a Static Website on Amazon S3</title>
      <link>/en/posts/como-hospedar-site-estatico-amazon-s3/</link>
      <pubDate>Tue, 11 Jun 2024 07:02:25 -0300</pubDate>
      <author>joaosenger.dev@gmail.com (João Senger)</author>
      <guid>/en/posts/como-hospedar-site-estatico-amazon-s3/</guid>
      <description>&lt;p&gt;Learn how to host your static website on Amazon S3 quickly and cost-effectively.&lt;/p&gt;
&lt;h2 id=&#34;introduction&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#introduction&#34;&gt;
        #
    &lt;/a&gt;
    Introduction
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Amazon S3 (Simple Storage Service) is an excellent option for hosting static websites. It&amp;rsquo;s cost-effective, scalable, and easy to configure. In this guide, you&amp;rsquo;ll learn how to set up static website hosting on S3.&lt;/p&gt;
&lt;h2 id=&#34;what-youll-need&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#what-youll-need&#34;&gt;
        #
    &lt;/a&gt;
    What You&amp;rsquo;ll Need
&lt;/div&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AWS account&lt;/li&gt;
&lt;li&gt;Static website (HTML, CSS, JS files)&lt;/li&gt;
&lt;li&gt;Domain name (optional)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;step-by-step-guide&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#step-by-step-guide&#34;&gt;
        #
    &lt;/a&gt;
    Step-by-Step Guide
&lt;/div&gt;
&lt;/h2&gt;
&lt;h3 id=&#34;1-create-an-s3-bucket&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#1-create-an-s3-bucket&#34;&gt;
        ##
    &lt;/a&gt;
    1. Create an S3 Bucket
&lt;/div&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Access the AWS Console&lt;/li&gt;
&lt;li&gt;Navigate to S3 service&lt;/li&gt;
&lt;li&gt;Click &amp;ldquo;Create bucket&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Choose a unique name for your bucket&lt;/li&gt;
&lt;li&gt;Select your preferred region&lt;/li&gt;
&lt;li&gt;Uncheck &amp;ldquo;Block all public access&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Click &amp;ldquo;Create bucket&amp;rdquo;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;2-upload-your-website-files&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#2-upload-your-website-files&#34;&gt;
        ##
    &lt;/a&gt;
    2. Upload Your Website Files
&lt;/div&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Open your created bucket&lt;/li&gt;
&lt;li&gt;Click &amp;ldquo;Upload&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Add your website files&lt;/li&gt;
&lt;li&gt;Make sure you have an &lt;code&gt;index.html&lt;/code&gt; file&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;3-configure-static-website-hosting&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#3-configure-static-website-hosting&#34;&gt;
        ##
    &lt;/a&gt;
    3. Configure Static Website Hosting
&lt;/div&gt;
&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;In your bucket, go to &amp;ldquo;Properties&amp;rdquo; tab&lt;/li&gt;
&lt;li&gt;Scroll down to &amp;ldquo;Static website hosting&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Click &amp;ldquo;Edit&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Select &amp;ldquo;Enable&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Set index document: &lt;code&gt;index.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Set error document: &lt;code&gt;error.html&lt;/code&gt; (optional)&lt;/li&gt;
&lt;li&gt;Save changes&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;4-configure-bucket-policy&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#4-configure-bucket-policy&#34;&gt;
        ##
    &lt;/a&gt;
    4. Configure Bucket Policy
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Add this policy to make your files publicly readable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff6ac1&#34;&gt;&amp;#34;Version&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#34;2012-10-17&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff6ac1&#34;&gt;&amp;#34;Statement&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#ff6ac1&#34;&gt;&amp;#34;Sid&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#34;PublicReadGetObject&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#ff6ac1&#34;&gt;&amp;#34;Effect&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#ff6ac1&#34;&gt;&amp;#34;Principal&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#ff6ac1&#34;&gt;&amp;#34;Action&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#34;s3:GetObject&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#ff6ac1&#34;&gt;&amp;#34;Resource&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#5af78e&#34;&gt;&amp;#34;arn:aws:s3:::YOUR-BUCKET-NAME/*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Replace &lt;code&gt;YOUR-BUCKET-NAME&lt;/code&gt; with your actual bucket name.&lt;/p&gt;
&lt;h3 id=&#34;5-access-your-website&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#5-access-your-website&#34;&gt;
        ##
    &lt;/a&gt;
    5. Access Your Website
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Your website will be available at:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;http://YOUR-BUCKET-NAME.s3-website-REGION.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;adding-a-custom-domain&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#adding-a-custom-domain&#34;&gt;
        #
    &lt;/a&gt;
    Adding a Custom Domain
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;To use your own domain:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Configure Route 53 or your DNS provider&lt;/li&gt;
&lt;li&gt;Create a CNAME record pointing to your S3 endpoint&lt;/li&gt;
&lt;li&gt;Consider using CloudFront for HTTPS and better performance&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;benefits-of-s3-hosting&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#benefits-of-s3-hosting&#34;&gt;
        #
    &lt;/a&gt;
    Benefits of S3 Hosting
&lt;/div&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Low cost&lt;/strong&gt;: Pay only for storage and bandwidth used&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;High availability&lt;/strong&gt;: 99.999999999% (11 9&amp;rsquo;s) durability&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scalability&lt;/strong&gt;: Handles traffic spikes automatically&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easy deployment&lt;/strong&gt;: Simple file upload process&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;limitations&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#limitations&#34;&gt;
        #
    &lt;/a&gt;
    Limitations
&lt;/div&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Only supports static content&lt;/li&gt;
&lt;li&gt;No server-side processing&lt;/li&gt;
&lt;li&gt;Limited to HTTP (HTTPS requires CloudFront)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#conclusion&#34;&gt;
        #
    &lt;/a&gt;
    Conclusion
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Amazon S3 is an excellent choice for hosting static websites. It&amp;rsquo;s simple to set up, cost-effective, and highly reliable. For more advanced features like HTTPS and CDN, consider adding CloudFront to your setup.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Need help with AWS or web development? Feel free to &lt;a href=&#34;https://www.joaosenger.com/en/contact/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;contact me&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Cloud Computing Service Models: IaaS, PaaS, and SaaS</title>
      <link>/en/posts/modelos-de-servicos-cloud-computing/</link>
      <pubDate>Sun, 09 Jun 2024 23:17:30 -0300</pubDate>
      <author>joaosenger.dev@gmail.com (João Senger)</author>
      <guid>/en/posts/modelos-de-servicos-cloud-computing/</guid>
      <description>&lt;p&gt;Understand the differences between IaaS, PaaS, and SaaS and choose the best model for your project.&lt;/p&gt;
&lt;h2 id=&#34;introduction&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#introduction&#34;&gt;
        #
    &lt;/a&gt;
    Introduction
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Cloud computing revolutionized how we consume and manage IT resources. Instead of purchasing and maintaining physical servers, we can rent computing resources as needed. There are three main service models, each offering different levels of control and management.&lt;/p&gt;
&lt;h2 id=&#34;the-three-service-models&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#the-three-service-models&#34;&gt;
        #
    &lt;/a&gt;
    The Three Service Models
&lt;/div&gt;
&lt;/h2&gt;
&lt;h3 id=&#34;1-iaas-infrastructure-as-a-service&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#1-iaas-infrastructure-as-a-service&#34;&gt;
        ##
    &lt;/a&gt;
    1. IaaS (Infrastructure as a Service)
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;What it is&lt;/strong&gt;: Provides basic computing infrastructure - virtual machines, storage, networks, and operating systems.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What you manage&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Applications&lt;/li&gt;
&lt;li&gt;Data&lt;/li&gt;
&lt;li&gt;Runtime&lt;/li&gt;
&lt;li&gt;Middleware&lt;/li&gt;
&lt;li&gt;Operating System&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What the provider manages&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Virtualization&lt;/li&gt;
&lt;li&gt;Servers&lt;/li&gt;
&lt;li&gt;Storage&lt;/li&gt;
&lt;li&gt;Networking&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Amazon EC2&lt;/li&gt;
&lt;li&gt;Google Compute Engine&lt;/li&gt;
&lt;li&gt;Microsoft Azure VMs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You need maximum control over the environment&lt;/li&gt;
&lt;li&gt;Custom applications requiring specific configurations&lt;/li&gt;
&lt;li&gt;Migration of existing applications to the cloud&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-paas-platform-as-a-service&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#2-paas-platform-as-a-service&#34;&gt;
        ##
    &lt;/a&gt;
    2. PaaS (Platform as a Service)
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;What it is&lt;/strong&gt;: Provides a development and deployment platform, including runtime environment, development tools, and database management.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What you manage&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Applications&lt;/li&gt;
&lt;li&gt;Data&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What the provider manages&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Runtime&lt;/li&gt;
&lt;li&gt;Middleware&lt;/li&gt;
&lt;li&gt;Operating System&lt;/li&gt;
&lt;li&gt;Virtualization&lt;/li&gt;
&lt;li&gt;Servers&lt;/li&gt;
&lt;li&gt;Storage&lt;/li&gt;
&lt;li&gt;Networking&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google App Engine&lt;/li&gt;
&lt;li&gt;Heroku&lt;/li&gt;
&lt;li&gt;AWS Elastic Beanstalk&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rapid application development&lt;/li&gt;
&lt;li&gt;Focus on code, not infrastructure&lt;/li&gt;
&lt;li&gt;Development teams without DevOps expertise&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;3-saas-software-as-a-service&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#3-saas-software-as-a-service&#34;&gt;
        ##
    &lt;/a&gt;
    3. SaaS (Software as a Service)
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;What it is&lt;/strong&gt;: Complete applications delivered over the internet, ready to use.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What you manage&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Data and user access&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;What the provider manages&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Everything else&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google Workspace&lt;/li&gt;
&lt;li&gt;Microsoft 365&lt;/li&gt;
&lt;li&gt;Salesforce&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Standard business applications&lt;/li&gt;
&lt;li&gt;Quick implementation without development&lt;/li&gt;
&lt;li&gt;Focus on using the tool, not maintaining it&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;comparison-table&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#comparison-table&#34;&gt;
        #
    &lt;/a&gt;
    Comparison Table
&lt;/div&gt;
&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;IaaS&lt;/th&gt;
&lt;th&gt;PaaS&lt;/th&gt;
&lt;th&gt;SaaS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Control&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Management Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Time to Market&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Slow&lt;/td&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;Immediate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Variable&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Predictable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;choosing-the-right-model&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#choosing-the-right-model&#34;&gt;
        #
    &lt;/a&gt;
    Choosing the Right Model
&lt;/div&gt;
&lt;/h2&gt;
&lt;h3 id=&#34;choose-iaas-when&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#choose-iaas-when&#34;&gt;
        ##
    &lt;/a&gt;
    Choose IaaS when:
&lt;/div&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You need complete control over the environment&lt;/li&gt;
&lt;li&gt;You have specific compliance requirements&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;re migrating legacy applications&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;choose-paas-when&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#choose-paas-when&#34;&gt;
        ##
    &lt;/a&gt;
    Choose PaaS when:
&lt;/div&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You want to focus on development&lt;/li&gt;
&lt;li&gt;You need to deploy applications quickly&lt;/li&gt;
&lt;li&gt;You have a development team but limited DevOps&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;choose-saas-when&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#choose-saas-when&#34;&gt;
        ##
    &lt;/a&gt;
    Choose SaaS when:
&lt;/div&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You need standard business applications&lt;/li&gt;
&lt;li&gt;You want minimal IT management&lt;/li&gt;
&lt;li&gt;Quick implementation is priority&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;hybrid-approaches&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#hybrid-approaches&#34;&gt;
        #
    &lt;/a&gt;
    Hybrid Approaches
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Many companies use a combination of models:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SaaS&lt;/strong&gt; for office applications (email, documents)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PaaS&lt;/strong&gt; for custom application development&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IaaS&lt;/strong&gt; for specific infrastructure needs&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34; &gt;
&lt;div&gt;
    &lt;a href=&#34;#conclusion&#34;&gt;
        #
    &lt;/a&gt;
    Conclusion
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Each cloud service model has its place depending on your needs, technical expertise, and business objectives. The key is understanding what level of control and management you need versus what you&amp;rsquo;re willing to delegate to the cloud provider.&lt;/p&gt;
&lt;p&gt;Understanding these models helps make informed decisions about cloud strategy and choosing the right services for each use case.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Want to learn more about cloud computing? Check out my other posts or &lt;a href=&#34;https://www.joaosenger.com/en/contact/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;get in touch&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
