<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Maria Leitão</title>
    <description>The latest articles on DEV Community by Maria Leitão (@marialuizaleitao).</description>
    <link>https://dev.to/marialuizaleitao</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1714091%2F39064049-215a-48cd-b5a2-464160930f79.jpeg</url>
      <title>DEV Community: Maria Leitão</title>
      <link>https://dev.to/marialuizaleitao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marialuizaleitao"/>
    <language>en</language>
    <item>
      <title>Documentando uma API com Java Spring Boot usando Swagger</title>
      <dc:creator>Maria Leitão</dc:creator>
      <pubDate>Tue, 30 Jul 2024 22:26:11 +0000</pubDate>
      <link>https://dev.to/marialuizaleitao/documentando-uma-api-com-java-spring-boot-usando-swagger-4hgd</link>
      <guid>https://dev.to/marialuizaleitao/documentando-uma-api-com-java-spring-boot-usando-swagger-4hgd</guid>
      <description>&lt;p&gt;Passos para documentar uma RESTful API em Java Spring Boot com Swagger&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Adicionar dependências do Swagger&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Adicione as dependências do Swagger no arquivo pom.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.springfox&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;springfox-swagger2&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.9.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.springfox&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;springfox-swagger-ui&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.9.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Configurar o Swagger&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Crie uma classe de configuração do Swagger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Bean&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Configuration&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.builders.ApiInfoBuilder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.builders.PathSelectors&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.builders.RequestHandlerSelectors&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.spi.DocumentationType&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.spring.web.plugins.Docket&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;springfox.documentation.swagger2.annotations.EnableSwagger2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="nd"&gt;@EnableSwagger2&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SwaggerConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Docket&lt;/span&gt; &lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Docket&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DocumentationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SWAGGER_2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apis&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RequestHandlerSelectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;basePackage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.example"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PathSelectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;any&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apiInfo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApiInfoBuilder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"My API"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This is a RESTful API in Java Spring Boot using Swagger"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;springfox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;documentation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Contact&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"API Support"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"support@example.com"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Adicionar Anotações Swagger para Descrever Endpoints, Parâmetros e Respostas&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Anotações de Operação:&lt;/p&gt;

&lt;p&gt;Para cada endpoint, adicione anotações com detalhes da requisição HTTP, caminho e um resumo básico.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.swagger.annotations.Api&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.swagger.annotations.ApiOperation&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.swagger.annotations.ApiParam&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.GetMapping&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.PathVariable&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.RequestMapping&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.RestController&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/movies"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Api&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Movies"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MovieController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@ApiOperation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Get a list of movies"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Retrieves a list of movies"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Movie&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getMovies&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// code ...&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@ApiOperation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Get a movie by ID"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Retrieves a movie by its ID"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/{id}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Movie&lt;/span&gt; &lt;span class="nf"&gt;getMovie&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nd"&gt;@ApiParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ID of the movie to be obtained"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
            &lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// code ...&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Definindo Modelos de Resposta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.swagger.annotations.ApiModel&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.swagger.annotations.ApiModelProperty&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ApiModel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Details about the Movie"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Movie&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@ApiModelProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The unique ID of the movie"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@ApiModelProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The name of the movie"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// getters and setters&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ApiModel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Details about the ErrorResponse"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ErrorResponse&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@ApiModelProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The error code"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@ApiModelProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The error message"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// getters and setters&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Gerar a Documentação do Swagger&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Inicie a aplicação Spring Boot e acesse a interface Swagger UI no navegador:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;http://localhost:8080/swagger-ui.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Boas Práticas de Documentação&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Use linguagem descritiva e sucinta para ajudar no entendimento da API.&lt;/li&gt;
&lt;li&gt;Organize a ordem das anotações de forma lógica para seguir um fluxo claro e padronizado, facilitando a manutenção.&lt;/li&gt;
&lt;li&gt;Atualize a documentação sempre que houverem mudanças na API para mantê-la consistente e útil.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Seguindo esses passos, você poderá documentar sua API em Java Spring Boot usando Swagger de maneira eficaz e clara.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building a Simple Load Balancer in Go</title>
      <dc:creator>Maria Leitão</dc:creator>
      <pubDate>Thu, 11 Jul 2024 17:27:13 +0000</pubDate>
      <link>https://dev.to/marialuizaleitao/building-a-simple-load-balancer-in-go-pbd</link>
      <guid>https://dev.to/marialuizaleitao/building-a-simple-load-balancer-in-go-pbd</guid>
      <description>&lt;p&gt;Load balancing is an essential component in distributed systems, ensuring that incoming requests are evenly distributed across multiple backend servers. In this post, we’ll build a simple, thread-safe load balancer in Go using a round-robin algorithm. We’ll walk through the code step-by-step, explaining how each part works and how you can adapt it to fit your needs.&lt;/p&gt;

&lt;p&gt;You can clone the project from my &lt;a href="https://github.com/marialuizaleitao/go-load-balancer" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We’ll Build
&lt;/h2&gt;

&lt;p&gt;Our load balancer will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Distribute incoming HTTP requests among multiple backend servers.&lt;/li&gt;
&lt;li&gt;Use a round-robin algorithm to ensure even distribution.&lt;/li&gt;
&lt;li&gt;Be thread-safe, using &lt;code&gt;sync.Mutex&lt;/code&gt; for safe access to shared resources.&lt;/li&gt;
&lt;li&gt;Allow dynamic addition and removal of backend servers.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Make sure you have Go 1.16 or later installed on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Overview
&lt;/h2&gt;

&lt;p&gt;Here’s the complete code for our load balancer:&lt;br&gt;
&lt;/p&gt;

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

import (
    "fmt"
    "net/http"
    "net/http/httputil"
    "net/url"
    "sync"
)

// Server interface defines the methods that a backend server should implement.
type Server interface {
    Address() string
    IsAlive() bool
    Serve(rw http.ResponseWriter, r *http.Request)
}

// SimpleServer implements the Server interface and represents a single backend server.
type SimpleServer struct {
    address string
    proxy   *httputil.ReverseProxy
}

// Address returns the address of the server.
func (s *SimpleServer) Address() string {
    return s.address
}

// IsAlive returns the health status of the server. Always returns true in this example.
func (s *SimpleServer) IsAlive() bool {
    return true
}

// Serve forwards the request to the backend server using the reverse proxy.
func (s *SimpleServer) Serve(rw http.ResponseWriter, r *http.Request) {
    s.proxy.ServeHTTP(rw, r)
}

// LoadBalancer manages the distribution of requests to multiple backend servers.
type LoadBalancer struct {
    port            string
    roundRobinCount int
    servers         []Server
    mu              sync.Mutex
}

// NewLoadBalancer creates a new LoadBalancer instance.
func NewLoadBalancer(port string, servers []Server) *LoadBalancer {
    return &amp;amp;LoadBalancer{
        port:            port,
        roundRobinCount: 0,
        servers:         servers,
    }
}

// NewSimpleServer creates a new SimpleServer instance.
func NewSimpleServer(address string) *SimpleServer {
    serverURL, err := url.Parse(address)
    if err != nil {
        panic(fmt.Sprintf("Error parsing server URL %s: %v", address, err))
    }

    return &amp;amp;SimpleServer{
        address: address,
        proxy:   httputil.NewSingleHostReverseProxy(serverURL),
    }
}

// getNextAvailableServer returns the next available server using a round-robin algorithm.
func (lb *LoadBalancer) getNextAvailableServer() Server {
    lb.mu.Lock()
    defer lb.mu.Unlock()

    for i := 0; i &amp;lt; len(lb.servers); i++ {
        server := lb.servers[lb.roundRobinCount%len(lb.servers)]
        lb.roundRobinCount++
        if server.IsAlive() {
            return server
        }
    }

    if len(lb.servers) &amp;gt; 0 {
        return lb.servers[0]
    }

    return nil
}

// serveProxy forwards the request to the next available backend server.
func (lb *LoadBalancer) serveProxy(rw http.ResponseWriter, r *http.Request) {
    targetServer := lb.getNextAvailableServer()
    if targetServer == nil {
        http.Error(rw, "No available servers", http.StatusServiceUnavailable)
        return
    }

    fmt.Printf("Forwarding request to address %s\n", targetServer.Address())
    targetServer.Serve(rw, r)
}

func main() {
    // List of backend servers.
    servers := []Server{
        NewSimpleServer("https://www.facebook.com"),
        NewSimpleServer("http://www.bing.com"),
        NewSimpleServer("https://www.google.com"),
    }
    lb := NewLoadBalancer("8000", servers)
    handleRedirect := func(rw http.ResponseWriter, r *http.Request) {
        lb.serveProxy(rw, r)
    }
    http.HandleFunc("/", handleRedirect)

    fmt.Printf("Serving requests at 'localhost:%v'\n", lb.port)
    http.ListenAndServe(":"+lb.port, nil)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step-by-Step Explanation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Server Interface
&lt;/h3&gt;

&lt;p&gt;The Server interface defines the methods that any backend server should implement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Server interface {
    Address() string
    IsAlive() bool
    Serve(rw http.ResponseWriter, r *http.Request)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. SimpleServer Struct
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;SimpleServer&lt;/code&gt; struct implements the Server interface. It holds the server address and a reverse proxy to forward requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type SimpleServer struct {
    address string
    proxy   *httputil.ReverseProxy
}

func (s *SimpleServer) Address() string {
    return s.address
}

func (s *SimpleServer) IsAlive() bool {
    return true
}

func (s *SimpleServer) Serve(rw http.ResponseWriter, r *http.Request) {
    s.proxy.ServeHTTP(rw, r)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. LoadBalancer Struct
&lt;/h3&gt;

&lt;p&gt;The LoadBalancer struct manages the distribution of requests to multiple backend servers. It uses a round-robin algorithm to select the next available server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type LoadBalancer struct {
    port            string
    roundRobinCount int
    servers         []Server
    mu              sync.Mutex
}

func NewLoadBalancer(port string, servers []Server) *LoadBalancer {
    return &amp;amp;LoadBalancer{
        port:            port,
        roundRobinCount: 0,
        servers:         servers,
    }
}

func (lb *LoadBalancer) getNextAvailableServer() Server {
    lb.mu.Lock()
    defer lb.mu.Unlock()

    for i := 0; i &amp;lt; len(lb.servers); i++ {
        server := lb.servers[lb.roundRobinCount%len(lb.servers)]
        lb.roundRobinCount++
        if server.IsAlive() {
            return server
        }
    }

    if len(lb.servers) &amp;gt; 0 {
        return lb.servers[0]
    }

    return nil
}

func (lb *LoadBalancer) serveProxy(rw http.ResponseWriter, r *http.Request) {
    targetServer := lb.getNextAvailableServer()
    if targetServer == nil {
        http.Error(rw, "No available servers", http.StatusServiceUnavailable)
        return
    }

    fmt.Printf("Forwarding request to address %s\n", targetServer.Address())
    targetServer.Serve(rw, r)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Main Function
&lt;/h3&gt;

&lt;p&gt;The main function initializes the load balancer with a list of backend servers and starts the HTTP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
    servers := []Server{
        NewSimpleServer("https://www.facebook.com"),
        NewSimpleServer("http://www.bing.com"),
        NewSimpleServer("https://www.google.com"),
    }
    lb := NewLoadBalancer("8000", servers)
    handleRedirect := func(rw http.ResponseWriter, r *http.Request) {
        lb.serveProxy(rw, r)
    }
    http.HandleFunc("/", handleRedirect)

    fmt.Printf("Serving requests at 'localhost:%v'\n", lb.port)
    http.ListenAndServe(":"+lb.port, nil)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adapting the Load Balancer
&lt;/h2&gt;

&lt;p&gt;This basic load balancer can be extended in several ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Health Checks: Implement health checks to periodically check the status of backend servers and mark them as unavailable if they fail.&lt;/li&gt;
&lt;li&gt;Dynamic Server Management: Add endpoints to dynamically add or remove backend servers.&lt;/li&gt;
&lt;li&gt;Load Balancing Algorithms: Implement different load balancing algorithms like least connections, IP hash, etc.
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;We’ve built a simple load balancer in Go that uses a round-robin algorithm to distribute incoming requests. This example serves as a starting point, and you can extend it to meet more complex requirements. Happy coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>ACID: O Pilar dos Bancos de Dados Relacionais</title>
      <dc:creator>Maria Leitão</dc:creator>
      <pubDate>Wed, 10 Jul 2024 15:05:00 +0000</pubDate>
      <link>https://dev.to/marialuizaleitao/acid-o-pilar-dos-bancos-de-dados-relacionais-5g47</link>
      <guid>https://dev.to/marialuizaleitao/acid-o-pilar-dos-bancos-de-dados-relacionais-5g47</guid>
      <description>&lt;h1&gt;
  
  
  O Que é ACID em Bancos de Dados Relacionais?
&lt;/h1&gt;

&lt;p&gt;Se você já trabalhou com bancos de dados relacionais, provavelmente já se deparou com a sigla ACID. Mas o que exatamente isso significa e por que é tão importante? Vamos explorar cada componente de ACID e entender o seu papel nos sistemas de banco de dados. &lt;/p&gt;

&lt;h3&gt;
  
  
  O que é ACID?
&lt;/h3&gt;

&lt;p&gt;ACID é um acrônimo que representa quatro propriedades fundamentais garantidas pelos sistemas de banco de dados relacionais para garantir a integridade e a confiabilidade das transações. Estas propriedades são: Atomicidade, Consistência, Isolamento e Durabilidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Componentes do ACID
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Atomicidade (Atomicity):
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conceito:&lt;/strong&gt; Assegura que todas as operações dentro de uma transação são completadas com sucesso ou nenhuma delas é aplicada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo real:&lt;/strong&gt; Em uma transação de transferência bancária, se a transferência do valor da Conta A para a Conta B falhar, nenhuma das contas deve ser alterada.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Consistência (Consistency):
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conceito:&lt;/strong&gt; Garante que uma transação leva o banco de dados de um estado válido para outro estado válido, preservando as regras de integridade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo real:&lt;/strong&gt; Após uma transação, todas as regras de integridade, como restrições e gatilhos, são respeitadas. Se um depósito for feito, o saldo total do banco deve refletir essa mudança.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Isolamento (Isolation):
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conceito:&lt;/strong&gt; Assegura que as operações de uma transação são isoladas de outras transações simultâneas. As transações não devem interferir umas com as outras.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo real:&lt;/strong&gt; Se duas pessoas estão comprando o último item disponível em uma loja online ao mesmo tempo, o sistema deve garantir que apenas uma transação finalize a compra.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Durabilidade (Durability):
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conceito:&lt;/strong&gt; Garante que uma vez que uma transação foi concluída com sucesso, suas alterações são permanentes, mesmo em caso de falha do sistema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exemplo real:&lt;/strong&gt; Após a confirmação de um pedido em um e-commerce, os detalhes do pedido devem permanecer registrados, mesmo que ocorra uma queda de energia logo em seguida.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Importância do ACID
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Confiabilidade:&lt;/strong&gt; ACID é crucial para garantir que os bancos de dados se comportem de maneira previsível e confiável.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integridade de Dados:&lt;/strong&gt; Mantém a integridade dos dados, assegurando que eles não fiquem em um estado incorreto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Segurança:&lt;/strong&gt; Proporciona uma camada adicional de segurança, garantindo que as transações sejam corretamente registradas e mantidas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;As propriedades ACID são muito importante nos bancos de dados relacionais, já que garantem que as transações serão realizadas de forma segura, confiável e eficiente. Compreender ACID é fundamental para qualquer profissional que trabalhe com bancos de dados, pois garante a integridade e a consistência dos dados, aspectos que são vitais em qualquer aplicação crítica.&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>sql</category>
      <category>postgres</category>
      <category>community</category>
    </item>
    <item>
      <title>Documentando uma API com Go Swagger</title>
      <dc:creator>Maria Leitão</dc:creator>
      <pubDate>Thu, 04 Jul 2024 16:34:26 +0000</pubDate>
      <link>https://dev.to/marialuizaleitao/documentando-uma-api-com-go-swagger-587</link>
      <guid>https://dev.to/marialuizaleitao/documentando-uma-api-com-go-swagger-587</guid>
      <description>&lt;p&gt;Passos para documentar uma RESTful API em Go com Swagger&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Instalar o Swagger Tools&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;go get -u github.com/swaggo/swag/cmd/swag&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Adicionar Swagger Annotations para descrever endpoints, parâmetros e respostas&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Swagger Info Annotation:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;No topo do arquivo &lt;code&gt;main.go&lt;/code&gt; ou em um arquivo específico, adicione informações como versão, título e descrição.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// @title My API&lt;/span&gt;
&lt;span class="c"&gt;// @version 1.0&lt;/span&gt;
&lt;span class="c"&gt;// @description This is a RESTful API in Go using Swagger&lt;/span&gt;
&lt;span class="c"&gt;// @contact.name API Support&lt;/span&gt;
&lt;span class="c"&gt;// @contact.email support@example.com&lt;/span&gt;
&lt;span class="c"&gt;// @host localhost:8000&lt;/span&gt;
&lt;span class="c"&gt;// @BasePath /v1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Operation Annotations:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Para cada endpoint, anote a function com os detalhes da requisição HTTP, path, e um resumo básico.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// @Summary Get a list of movies&lt;/span&gt;
&lt;span class="c"&gt;// @Description Retrieves a list of movies&lt;/span&gt;
&lt;span class="c"&gt;// @Tags movies&lt;/span&gt;
&lt;span class="c"&gt;// @Accept json&lt;/span&gt;
&lt;span class="c"&gt;// @Produce json&lt;/span&gt;
&lt;span class="c"&gt;// @Success 200 {array} Movie&lt;/span&gt;
&lt;span class="c"&gt;// @Router /movies [get]&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getMovies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// code ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Parameter Annotations:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Descreva o path, a query, e o body da requisição.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// previous Operation Annotations...&lt;/span&gt;

&lt;span class="c"&gt;// @Param id path string true "Movie ID"&lt;/span&gt;
&lt;span class="c"&gt;// @Success 200 {object} Movie&lt;/span&gt;
&lt;span class="c"&gt;// @Failure 404 {object} ErrorResponse&lt;/span&gt;
&lt;span class="c"&gt;// @Router /movies/{id} [get]&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getMovie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// code ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Response Annotations:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Defina a estrutura de responses retornadas pelos endpoints da API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Movie struct&lt;/span&gt;
&lt;span class="c"&gt;// @Description structure of Movie&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Movie&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;   &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// ErrorResponse struct&lt;/span&gt;
&lt;span class="c"&gt;// @Description structure of ErrorResponse&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;ErrorResponse&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Code&lt;/span&gt;    &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"code"`&lt;/span&gt;
    &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"message"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Gerar a Documentação do Swagger:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Rode o comando &lt;code&gt;swag init&lt;/code&gt; no diretório do projeto pra gerar o Swagger JSON e YAML baseados nas anotações. &lt;strong&gt;Se houverem mudanças nas anotações, esse comando deve ser rodado novamente.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;swag&lt;/span&gt; &lt;span class="k"&gt;init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suba a aplicação e entrar na Swagger UI (&lt;code&gt;http://localhost:8000/swagger/index.html&lt;/code&gt;) pra interagir com a documentação.&lt;/p&gt;

&lt;h1&gt;
  
  
  Boas práticas de documentação:
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Use linguagem descritiva e sucinta pra ajudar no entendimento da API.&lt;/li&gt;
&lt;li&gt;Organize a ordem das anotações de forma lógica pra seguir um fluxo claro e padronizado, facilitando a manutenção.&lt;/li&gt;
&lt;/ul&gt;

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