<?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: Petros Stergioulas</title>
    <description>The latest articles on DEV Community by Petros Stergioulas (@petros0).</description>
    <link>https://dev.to/petros0</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%2F40136%2F230b4cbb-222e-4840-a679-bde7c7a3f288.jpeg</url>
      <title>DEV Community: Petros Stergioulas</title>
      <link>https://dev.to/petros0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/petros0"/>
    <language>en</language>
    <item>
      <title>'Code First' API Documentation with Springdoc and Spring Boot</title>
      <dc:creator>Petros Stergioulas</dc:creator>
      <pubDate>Sat, 06 Jun 2020 08:49:20 +0000</pubDate>
      <link>https://dev.to/petros0/code-first-api-documentation-with-springdoc-and-spring-boot-10l9</link>
      <guid>https://dev.to/petros0/code-first-api-documentation-with-springdoc-and-spring-boot-10l9</guid>
      <description>&lt;p&gt;&lt;strong&gt;This article was first published on &lt;a href="https://reflectoring.io/spring-boot-springdoc/" rel="noopener noreferrer"&gt;reflectoring.io&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;When following a "code first" approach in API development, we first start with writing code, and then we generate the API specification from the code, which then becomes the documentation.&lt;/p&gt;

&lt;p&gt;"Code first" is not the only way to develop an API. &lt;a href="https://reflectoring.io/spring-boot-openapi/" rel="noopener noreferrer"&gt;"API first"&lt;/a&gt; is another option where we do exactly the opposite. First, we write the specification, and then we generate code from that specification and implement against it. &lt;/p&gt;

&lt;p&gt;Let's discuss the benefits of using this approach and how to implement it with Springdoc and Spring Boot.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/thombergs" rel="noopener noreferrer"&gt;
        thombergs
      &lt;/a&gt; / &lt;a href="https://github.com/thombergs/code-examples" rel="noopener noreferrer"&gt;
        code-examples
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A collection of code examples from blog posts etc.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  When to Choose the "Code First" Approach
&lt;/h2&gt;

&lt;p&gt;When we need to go to production fast, or create a prototype something, "code first" may be a good approach. Then we can generate our documentation from the API we have already programmed.&lt;/p&gt;

&lt;p&gt;Another benefit of code first is the fact that the documentation will be generated from the actual code, which means that we don't have to manually keep the documentation in sync with our code. &lt;strong&gt;The documentation is more likely to match the behavior of the code and is always up-to-date&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;In this article, we'll be using &lt;a href="https://spring.io/projects/spring-boot" rel="noopener noreferrer"&gt;Spring Boot&lt;/a&gt; together with &lt;a href="https://springdoc.org/" rel="noopener noreferrer"&gt;springdoc-openapi&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All the annotations that we will be using are from &lt;a href="https://swagger.io/" rel="noopener noreferrer"&gt;Swagger&lt;/a&gt;&lt;/strong&gt;. Springdoc wraps Swagger and offers us a single dependency which we can use to create our API documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;To get started we only need to add the &lt;a href="https://search.maven.org/search?q=g:org.springdoc%20AND%20a:springdoc-openapi" rel="noopener noreferrer"&gt;Springdoc dependency&lt;/a&gt; (Gradle notation):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.springdoc:springdoc-openapi-ui:1.3.3'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, let's define the path of our documentation. We define it in the &lt;code&gt;application.yml&lt;/code&gt; of our Spring Boot project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;springdoc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;api-docs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/reflectoring-openapi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Springdoc will now add the endpoint &lt;code&gt;/reflectoring-openapi&lt;/code&gt; to our application where it will beautifully display our endpoints. For more configuration properties please check the &lt;a href="https://springdoc.org/springdoc-properties.html" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining General API Information
&lt;/h3&gt;

&lt;p&gt;Next, let's define some information about our API:&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="nd"&gt;@OpenAPIDefinition&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;@Info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Code-First Approach (reflectoring.io)"&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;""&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s"&gt;"Lorem ipsum dolor ..."&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;contact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;@Contact&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Reflectoring"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://reflectoring.io"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"petros.stergioulas94@gmail.com"&lt;/span&gt;
  &lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;@License&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"MIT Licence"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://github.com/thombergs/code-examples/blob/master/LICENSE"&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt;
  &lt;span class="n"&gt;servers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;@Server&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://localhost:8080"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OpenAPIConfiguration&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;Note that we don't need to define the class above as a Spring bean. Springdoc will just use reflection to obtain the information it needs.&lt;/p&gt;

&lt;p&gt;Now, if we start the Spring Boot application and navigate to &lt;a href="http://localhost:8080/swagger-ui/index.html?configUrl=/reflectoring-openapi/swagger-config" rel="noopener noreferrer"&gt;http://localhost:8080/swagger-ui/index.html?configUrl=/reflectoring-openapi/swagger-config&lt;/a&gt;, we should see the information we defined above:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Fgeneral-info.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Fgeneral-info.png" alt="General Information"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining the REST API
&lt;/h3&gt;

&lt;p&gt;Next, let's add some REST endpoints. We'll be building a TODO API with CRUD operations.&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="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/todos"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Tag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Todo API"&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;"euismod in pellentesque ..."&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;TodoApi&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;
  &lt;span class="nd"&gt;@ResponseStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;OK&lt;/span&gt;&lt;span class="o"&gt;)&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;Todo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findAll&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="nd"&gt;@ResponseStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;OK&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="nf"&gt;findById&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="nd"&gt;@PostMapping&lt;/span&gt;
  &lt;span class="nd"&gt;@ResponseStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CREATED&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@PutMapping&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="nd"&gt;@ResponseStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;OK&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="nf"&gt;update&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="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@DeleteMapping&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="nd"&gt;@ResponseStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NO_CONTENT&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;delete&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the &lt;code&gt;@Tag&lt;/code&gt; annotation, we add some additional information to the API.&lt;/p&gt;

&lt;p&gt;Now, we have to implement this interface and annotate our controller with &lt;br&gt;
&lt;code&gt;@RestController&lt;/code&gt;. This will let Springdoc know that this is a controller and that it should produce a documentation for it:&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="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TodoController&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;TodoApi&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// method implementations  &lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's start the application again and take a look at the &lt;a href="http://localhost:8080/swagger-ui/index.html?configUrl=/reflectoring-openapi/swagger-config" rel="noopener noreferrer"&gt;Swagger UI&lt;/a&gt;. It should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Ftodo-api-info.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Ftodo-api-info.png" alt="Todo API Information"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Springdoc did its magic and created a documentation for our API!&lt;/p&gt;

&lt;p&gt;Let's dive a little more into Springdoc by defining a security scheme.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining a Security Scheme
&lt;/h3&gt;

&lt;p&gt;To define a security scheme for our application we just need to add the &lt;code&gt;@SecurityScheme&lt;/code&gt; annotation in one of our classes:&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="c1"&gt;// other annotations omitted&lt;/span&gt;
&lt;span class="nd"&gt;@SecurityScheme&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"api"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
  &lt;span class="n"&gt;scheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"basic"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SecuritySchemeType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SecuritySchemeIn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;HEADER&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OpenAPIConfiguration&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;The above &lt;code&gt;@SecurityScheme&lt;/code&gt; will be referred to as &lt;code&gt;api&lt;/code&gt; and will do a basic authentication via HTTP. We add this annotation in the &lt;code&gt;OpenAPIConfiguration&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Let's see what this annotation produced for us:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Fsecure-scheme.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Fsecure-scheme.png" alt="Secure Scheme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our documentation has now also an "Authorize" Button! If we press this button we will get a dialog where we can authenticate:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Fsecure-scheme-dialog.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Fsecure-scheme-dialog.png" alt="Secure Scheme Dialog"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To define that an API endpoint uses the above security scheme we have to annotate it with the &lt;code&gt;@SecurityRequirement&lt;/code&gt; annotation.&lt;/p&gt;

&lt;p&gt;Now, the &lt;code&gt;TodoApi&lt;/code&gt; looks like this:&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="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/todos"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Tag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Todo API"&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;"euismod in pellentesque ..."&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@SecurityRequirement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"api"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;TodoApi&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// other methods omitted&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the Swagger UI will show a lock on each of our endpoints to mark them as "secured":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Ftodo-api-info-with-lock.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Ftodo-api-info-with-lock.png" alt="Todo API with lock"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Actually, the endpoints are not secured, yet. If we try to request the &lt;code&gt;/api/todos&lt;/code&gt; resource, for example, &lt;strong&gt;we will still be able to receive the data without authentication&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Ftodo-api-info-with-lock-unsecured.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Ftodo-api-info-with-lock-unsecured.png" alt="Todo API with lock unsecured"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have to implement the actual security ourselves. See the code in the &lt;a href="https://github.com/thombergs/code-examples/tree/master/spring-boot/spring-boot-springdoc" rel="noopener noreferrer"&gt;repository&lt;/a&gt; for the full implementation with Spring Security.&lt;/p&gt;

&lt;p&gt;After securing the application we can now see that we receive a &lt;code&gt;401&lt;/code&gt; status code if we try to access any resource under &lt;code&gt;/api/todos&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Ftodo-api-info-with-lock-secured-401.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Ftodo-api-info-with-lock-secured-401.png" alt="Todo API with lock secured 401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After authenticating we can again access the resource:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Ftodo-api-info-with-lock-secured-200.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Freflectoring.io%2Fassets%2Fimg%2Fposts%2Freflect-92%2Ftodo-api-info-with-lock-secured-200.png" alt="Todo API with lock secured 200"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;As we saw in this article, the "code first" approach with Springdoc is all about speed. First, we build our API in code, then we generate the specification/documentation via annotations.&lt;br&gt;
Springdoc elevates Swagger and helps us create our OpenAPI Specification.&lt;/p&gt;

&lt;p&gt;If you want to have a deeper look, browse the code &lt;a href="https://github.com/thombergs/code-examples/tree/master/spring-boot/spring-boot-springdoc" rel="noopener noreferrer"&gt;on GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>api</category>
    </item>
    <item>
      <title>API-First Development with Spring Boot and Swagger</title>
      <dc:creator>Petros Stergioulas</dc:creator>
      <pubDate>Sat, 14 Mar 2020 19:39:25 +0000</pubDate>
      <link>https://dev.to/petros0/api-first-development-with-spring-boot-and-swagger-1lm8</link>
      <guid>https://dev.to/petros0/api-first-development-with-spring-boot-and-swagger-1lm8</guid>
      <description>&lt;p&gt;&lt;strong&gt;This article was first published on &lt;a href="https://reflectoring.io/spring-boot-openapi/"&gt;reflectoring.io&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Following an API-first approach, we specify an API before we start coding. Via API description languages, teams can collaborate without having implemented anything, yet.&lt;/p&gt;

&lt;p&gt;Those description languages specify endpoints, security schemas, object schemas, and much more. Moreover, most of the time we can also generate code such a specification.&lt;/p&gt;

&lt;p&gt;Often, an API specification also becomes the documentation of the API. &lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/thombergs"&gt;
        thombergs
      &lt;/a&gt; / &lt;a href="https://github.com/thombergs/code-examples"&gt;
        code-examples
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A collection of code examples from blog posts etc.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Benefits of API-First
&lt;/h2&gt;

&lt;p&gt;To start working on an integration between components or systems, a team needs a contract. In our case, the contract is the API specification. API-first helps teams to communicate with each other, without implementing a thing. &lt;strong&gt;It also enables teams to work in parallel.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Where the API-first approach shines is on building a &lt;strong&gt;better API&lt;/strong&gt;. Focusing on the functionality that it is needed to provide and only that. Minimalistic APIs mean less code to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating an API Spec with the Swagger Editor
&lt;/h2&gt;

&lt;p&gt;Let's create our own OpenAPI specification in a YAML document. To make it easier to follow, we'll split the discussion into separate parts of the YAML document we're creating.&lt;/p&gt;

&lt;p&gt;If you want to learn more details about the OpenAPI-Specification you can visit the &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#versions"&gt;Github repository&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  General Information
&lt;/h3&gt;

&lt;p&gt;We start with some general information about our API at the top of our document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;openapi&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.0.2&lt;/span&gt;
&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Reflectoring&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tutorials&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;on&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Spring&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Boot&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Java."&lt;/span&gt;
  &lt;span class="na"&gt;termsOfService&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://swagger.io/terms/&lt;/span&gt;
  &lt;span class="na"&gt;contact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;petros.stergioulas94@gmail.com&lt;/span&gt;
  &lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apache &lt;/span&gt;&lt;span class="m"&gt;2.0&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://www.apache.org/licenses/LICENSE-2.0.html&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.0.1-SNAPSHOT&lt;/span&gt;
&lt;span class="na"&gt;externalDocs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Find out more about Reflectoring&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://reflectoring.io/about/&lt;/span&gt;
&lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://reflectoring.swagger.io/v2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#openapi-object"&gt;&lt;code&gt;openapi&lt;/code&gt;&lt;/a&gt; field allows us to define the version of the OpenAPI spec that our document follows.&lt;/p&gt;

&lt;p&gt;Within the &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#infoObject"&gt;&lt;code&gt;info&lt;/code&gt;&lt;/a&gt; section, we add some information about our API. The fields should be pretty self-explanatory.&lt;/p&gt;

&lt;p&gt;Finally, in the &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#serverObject"&gt;&lt;code&gt;servers&lt;/code&gt;&lt;/a&gt; section, we provide a list of servers that implement the API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tags
&lt;/h3&gt;

&lt;p&gt;Then comes some additional metadata about our API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Operations about user&lt;/span&gt;
  &lt;span class="na"&gt;externalDocs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Find out more about our store&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://swagger.io&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#fixed-fields"&gt;&lt;code&gt;tags&lt;/code&gt;&lt;/a&gt; section provides fields for additional metadata which we can use to make our API more readable and easier to follow. We can add multiple tags, but each tag should be unique.&lt;/p&gt;

&lt;h3&gt;
  
  
  Paths
&lt;/h3&gt;

&lt;p&gt;Next, we'll describe some paths. A path holds information about an individual endpoint and its operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;/user/{username}&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;user&lt;/span&gt;
      &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get user by user name&lt;/span&gt;
      &lt;span class="na"&gt;operationId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;getUserByName&lt;/span&gt;
      &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;username&lt;/span&gt;
        &lt;span class="na"&gt;in&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;path&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;that&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;needs&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;be&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;fetched.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
      &lt;span class="na"&gt;responses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;200&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;successful operation&lt;/span&gt;
          &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="s"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/schemas/User'&lt;/span&gt;
        &lt;span class="na"&gt;404&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;User not found&lt;/span&gt;
          &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#fixed-fields-8"&gt;&lt;code&gt;$ref&lt;/code&gt;&lt;/a&gt; field allows us to refer to objects in a self-defined schema. In this case we refer to the &lt;code&gt;User&lt;/code&gt; schema object (see the next section about Components).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;summary&lt;/code&gt; is a short description of what the operation does.&lt;/p&gt;

&lt;p&gt;With the &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#fixed-fields-8"&gt;&lt;code&gt;operationId&lt;/code&gt;&lt;/a&gt;, we can define a unique identifier for the operation. We can think about it as our method name.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responsesObject"&gt;&lt;code&gt;responses&lt;/code&gt;&lt;/a&gt; object allows us to define the outcomes of an operation. We must define at least one successful response code for any operation call. &lt;/p&gt;

&lt;h3&gt;
  
  
  Components
&lt;/h3&gt;

&lt;p&gt;The objects of the API are all described in the &lt;code&gt;components&lt;/code&gt; section. The objects defined within the components object will not affect the API unless they are explicitly referenced from properties outside the components object, as we have seen above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schemas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;User&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;integer&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;int64&lt;/span&gt;
        &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="s"&gt;... more attributes&lt;/span&gt;
        &lt;span class="na"&gt;userStatus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;integer&lt;/span&gt;
          &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;User Status&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;int32&lt;/span&gt;
  &lt;span class="na"&gt;securitySchemes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;reflectoring_auth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oauth2&lt;/span&gt;
      &lt;span class="na"&gt;flows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;implicit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;authorizationUrl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://reflectoring.swagger.io/oauth/dialog&lt;/span&gt;
          &lt;span class="na"&gt;scopes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="s"&gt;write:users: modify users&lt;/span&gt;
            &lt;span class="s"&gt;read:users: read users&lt;/span&gt;
    &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apiKey&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;api_key&lt;/span&gt;
      &lt;span class="na"&gt;in&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;header&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#schema-object"&gt;&lt;code&gt;schemas&lt;/code&gt;&lt;/a&gt; section allows us to define the objects we want to use in our API.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#security-scheme-object"&gt;&lt;code&gt;securitySchemes&lt;/code&gt;&lt;/a&gt; section, we can define security schemes that can be used by the operations.&lt;/p&gt;

&lt;p&gt;There two possible ways to make use of security schemes. &lt;/p&gt;

&lt;p&gt;First, we can add a security scheme to a specific operation using the &lt;code&gt;security&lt;/code&gt; field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;/user/{username}&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;user&lt;/span&gt;
      &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get user by user name&lt;/span&gt;
      &lt;span class="na"&gt;security&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the above example we explicitly specify that the path /user/{username} is secured with the &lt;code&gt;api_key&lt;/code&gt; scheme we defined above. &lt;/p&gt;

&lt;p&gt;However, if we want to apply security on the whole project, we just need to specify it as a top-level field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;/user/{username}&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;user&lt;/span&gt;
      &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get user by user name&lt;/span&gt;
&lt;span class="na"&gt;security&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, all of our paths should be secured with the &lt;code&gt;api_key&lt;/code&gt; scheme.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating Code From an API Specification
&lt;/h2&gt;

&lt;p&gt;Having defined an API, we'll now create code from the &lt;a href="https://github.com/thombergs/code-examples/tree/master/spring-boot/spring-boot-openapi/specification/src/main/resources/openapi.yml"&gt;YAML document above&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;We'll take a look at two different approaches to generating the code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using the &lt;a href="http://editor.swagger.io/"&gt;Swagger Editor&lt;/a&gt; to generate code manually, and&lt;/li&gt;
&lt;li&gt;using the &lt;a href="https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-maven-plugin"&gt;OpenAPI Maven plugin&lt;/a&gt; to generate code from a Maven build.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Generating Code from Swagger Editor
&lt;/h3&gt;

&lt;p&gt;Although this is an approach that I wouldn't take, let's talk about it and discuss why I think it's a bad idea. &lt;/p&gt;

&lt;p&gt;Let's go over to Swagger Editor and paste our YAML file into it. Then, we select &lt;em&gt;Generate Server&lt;/em&gt; from the menu and pick what kind of a server we'd like to generate (I went with "Spring").&lt;/p&gt;

&lt;p&gt;So why is this a bad idea?&lt;/p&gt;

&lt;p&gt;First, the code that was generated for me is using Java 7 and Spring Boot 1.5.22, both of which are quite outdated. &lt;/p&gt;

&lt;p&gt;Second, if we make a change to the specification (and changes happen all the time), we'd have to copy-and-paste the files that were changed manually. &lt;/p&gt;

&lt;h3&gt;
  
  
  Generating Code with the OpenAPI Maven plugin
&lt;/h3&gt;

&lt;p&gt;A better alternative is to generate the code from within a Maven build with the OpenAPI Maven plugin. &lt;/p&gt;

&lt;p&gt;Let's take a look at the folder structure. I chose to use a multi-module maven project, where we have two projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app&lt;/code&gt;, an application that implements the API from our specification.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specification&lt;/code&gt;, whose only job is to provide the API Specification for our app.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The folder structure looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring-boot-openapi
├── app
│   └── pom.xml
│   └── src
│       └── main
│           └── java
│               └── io.reflectoring
│                   └── OpenAPIConsumerApp.java
├── specification
│   └── pom.xml
│   └── src
│       └── resources
│           └── openapi.yml
└── pom.xml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For the sake of simplicity, we omit the test folders.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;app&lt;/code&gt; is a simple Spring Boot project that we can automatically generate on &lt;a href="https://start.spring.io"&gt;start.spring.io&lt;/a&gt;, so let's focus on the &lt;code&gt;pom.xml&lt;/code&gt; from the &lt;code&gt;specification&lt;/code&gt; module, where we configure &lt;br&gt;
the OpenAPI Maven plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.openapitools&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;openapi-generator-maven-plugin&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;4.2.3&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;generate&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;inputSpec&amp;gt;&lt;/span&gt;
                  ${project.basedir}/src/main/resources/openapi.yml
                &lt;span class="nt"&gt;&amp;lt;/inputSpec&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;generatorName&amp;gt;&lt;/span&gt;spring&lt;span class="nt"&gt;&amp;lt;/generatorName&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;apiPackage&amp;gt;&lt;/span&gt;io.reflectoring.api&lt;span class="nt"&gt;&amp;lt;/apiPackage&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;modelPackage&amp;gt;&lt;/span&gt;io.reflectoring.model&lt;span class="nt"&gt;&amp;lt;/modelPackage&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;supportingFilesToGenerate&amp;gt;&lt;/span&gt;
                  ApiUtil.java
                &lt;span class="nt"&gt;&amp;lt;/supportingFilesToGenerate&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;configOptions&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;delegatePattern&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/delegatePattern&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/configOptions&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can see the full &lt;code&gt;pom.xml&lt;/code&gt; file &lt;a href="https://github.com/thombergs/code-examples/tree/master/spring-boot/spring-boot-openapi/specification/pom.xml"&gt;on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For this tutorial, we're using the &lt;code&gt;spring&lt;/code&gt; generator. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simply running the command &lt;code&gt;./mvnw install&lt;/code&gt; will generate code that implements our OpenAPI specification!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Taking a look into the folder &lt;code&gt;target/generated-sources/openapi/src/main/java/io/reflectoring/model&lt;/code&gt;, we find the code for the &lt;code&gt;User&lt;/code&gt; model we defined in our YAML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@javax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;annotation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Generated&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;User&lt;/span&gt;   &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@JsonProperty&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;private&lt;/span&gt; &lt;span class="nc"&gt;Long&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;@JsonProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&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;username&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@JsonProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"firstName"&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;firstName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// ... more properties&lt;/span&gt;

  &lt;span class="nd"&gt;@JsonProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"userStatus"&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;Integer&lt;/span&gt; &lt;span class="n"&gt;userStatus&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;p&gt;The generator does not only generate the models but also the endpoints. Let's take a quick look at what we generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;UserApiDelegate&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NativeWebRequest&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getRequest&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="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;empty&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * POST /user : Create user
     * Create user functionality
     *
     * @param body Created user object (required)
     * @return successful operation (status code 200)
     * @see UserApi#createUser
     */&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;body&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="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NOT_IMPLEMENTED&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// ... omit deleteUser, getUserByName and updateUser&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Of course, the generator cannot generate our business logic for us, but it does generate interfaces like &lt;code&gt;UserApiDelegate&lt;/code&gt; above for us to implement.&lt;/p&gt;

&lt;p&gt;It also creates a &lt;code&gt;UserApi&lt;/code&gt; interface which delegates calls to &lt;code&gt;UserApiDelegate&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Validated&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user"&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;"the user API"&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;interface&lt;/span&gt; &lt;span class="nc"&gt;UserApi&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nc"&gt;UserApiDelegate&lt;/span&gt; &lt;span class="nf"&gt;getDelegate&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;UserApiDelegate&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;span class="cm"&gt;/**
     * POST /user : Create user
     * Create user functionality
     *
     * @param body Created user object (required)
     * @return successful operation (status code 200)
     */&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;"Create user"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;nickname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"createUser"&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;"Create user functionality"&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;"user"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
    &lt;span class="nd"&gt;@ApiResponses&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="o"&gt;{&lt;/span&gt; 
        &lt;span class="nd"&gt;@ApiResponse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"successful operation"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;
    &lt;span class="nd"&gt;@RequestMapping&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;"/user"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;POST&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;createUser&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;"Created user object"&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;@Valid&lt;/span&gt; 
      &lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;body&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="nf"&gt;getDelegate&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;createUser&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// ... other methods omitted&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The generator also creates a Spring controller for us that implements the &lt;code&gt;UserApi&lt;/code&gt; interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@javax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;annotation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Generated&lt;/span&gt;&lt;span class="o"&gt;(...)&lt;/span&gt;
&lt;span class="nd"&gt;@Controller&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;"${openapi.reflectoring.base-path:/v2}"&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;UserApiController&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;UserApi&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;UserApiDelegate&lt;/span&gt; &lt;span class="n"&gt;delegate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;UserApiController&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nd"&gt;@Autowired&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;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;UserApiDelegate&lt;/span&gt; &lt;span class="n"&gt;delegate&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delegate&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElse&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;UserApiDelegate&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;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;UserApiDelegate&lt;/span&gt; &lt;span class="nf"&gt;getDelegate&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="n"&gt;delegate&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;p&gt;Spring will inject our implementation of &lt;code&gt;UserApiDelegate&lt;/code&gt; into the controller's constructor if it finds it in the application context. Otherwise, the default implementation will be used.&lt;/p&gt;

&lt;p&gt;Let's start our application and hit the GET endpoint &lt;code&gt;/v2/user/{username}&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -I http://localhost:8080/v2/user/Petros
HTTP/1.1 501
Content-Length: 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But why do we get a 501 response (Not Implemented)?&lt;/p&gt;

&lt;p&gt;Because we did not implement the &lt;code&gt;UserApiDelegate&lt;/code&gt; interface and the  &lt;code&gt;UserApiController&lt;/code&gt; used the default one, which returns &lt;code&gt;HttpStatus.NOT_IMPLEMENTED&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now let's implement the &lt;code&gt;UserApiDelegate&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Service&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;UserApiDelegateImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;UserApiDelegate&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getUserByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&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;User&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFirstName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Petros"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// ... omit other initialization&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&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;p&gt;It's important to add a &lt;code&gt;@Service&lt;/code&gt; or &lt;code&gt;@Component&lt;/code&gt; annotation to the class so that Spring can pick it up and inject it into the &lt;code&gt;UserApiController&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we run &lt;code&gt;curl http://localhost:8080/v2/user/Petros&lt;/code&gt; again now, we'll receive a valid JSON response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"firstName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Petros"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;omit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;properties&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;UserApiDelegate&lt;/code&gt; is the single point of truth. That enables us to make fast changes in our API. For example, if we change the specification and generate it again, we only have to implement the newly generated methods.&lt;/p&gt;

&lt;p&gt;The good thing is that if we won't implement them, our application doesn't break. By default, those endpoints would return HTTP status 501 (Not Implemented).&lt;/p&gt;

&lt;p&gt;In my opinion, generating the OpenAPI Specification with Maven plugin instead of Swagger Editor is the better choice. &lt;br&gt;
That's because we have more control over our options. The plugin provides some configuration and with Git as a version control tool, we can safely track any changes in either &lt;code&gt;pom.xml&lt;/code&gt; and &lt;code&gt;openapi.yml&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;With OpenAPI we can create an API specification that we can share among teams to communicate contracts. The OpenAPI Maven plugin allows us to generate boilerplate code for Spring Boot from such a specification so that we only need to implement the business logic ourselves.&lt;/p&gt;

&lt;p&gt;You can browse the example code on &lt;a href="https://github.com/thombergs/code-examples/tree/master/spring-boot/spring-boot-openapi"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>swagger</category>
      <category>api</category>
    </item>
    <item>
      <title>Microservices: OAuth2 vs Simple JWT Authentication</title>
      <dc:creator>Petros Stergioulas</dc:creator>
      <pubDate>Tue, 17 Dec 2019 12:44:12 +0000</pubDate>
      <link>https://dev.to/petros0/microservices-oauth2-vs-simple-jwt-authentication-3oe</link>
      <guid>https://dev.to/petros0/microservices-oauth2-vs-simple-jwt-authentication-3oe</guid>
      <description>&lt;p&gt;I am trying to figure out, how I should implement the security for my microservices architecture.&lt;/p&gt;

&lt;p&gt;For example, I have a client(web), a gateway and some other microservices.&lt;/p&gt;

&lt;p&gt;Now I am thinking, should I implement my own Authentication/Authorization server(not an OAuth2), which will just authenticate the user? Or should I just pick a standard like &lt;a href="https://www.keycloak.org/"&gt;keycloak&lt;/a&gt; or &lt;a href="https://docs.cloudfoundry.org/api/uaa/version/74.4.0/index.html#overview"&gt;uaa&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;Does it make sense to use a fully OAuth2 capable server? &lt;/p&gt;

</description>
      <category>help</category>
      <category>security</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Hey Cyber Security Experts, I have some questions!</title>
      <dc:creator>Petros Stergioulas</dc:creator>
      <pubDate>Tue, 19 Nov 2019 18:00:07 +0000</pubDate>
      <link>https://dev.to/petros0/hey-cyber-security-experts-i-have-some-questions-2ld5</link>
      <guid>https://dev.to/petros0/hey-cyber-security-experts-i-have-some-questions-2ld5</guid>
      <description>&lt;p&gt;I am thinking of expanding my knowledge on the field. Based on that thought, I am considering doing a Master.&lt;/p&gt;

&lt;p&gt;What should one know, to be able to work on the field? Do you think a Master is a waste of resources(money, time, etc)?&lt;/p&gt;

&lt;p&gt;Currently I am a developer, will that help me on that journey?&lt;/p&gt;

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

</description>
      <category>career</category>
      <category>cybersecurity</category>
      <category>discuss</category>
      <category>help</category>
    </item>
    <item>
      <title>Getting started with Spring WebFlux and R2DBC in Spring Boot</title>
      <dc:creator>Petros Stergioulas</dc:creator>
      <pubDate>Fri, 01 Nov 2019 17:04:35 +0000</pubDate>
      <link>https://dev.to/petros0/getting-started-with-spring-webflux-and-r2dbc-in-spring-boot-191f</link>
      <guid>https://dev.to/petros0/getting-started-with-spring-webflux-and-r2dbc-in-spring-boot-191f</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In this short article I will try to introduce you to &lt;a href="https://r2dbc.io/" rel="noopener noreferrer"&gt;R2DBC&lt;/a&gt; using &lt;a href="https://github.com/spring-projects/spring-data-r2dbc" rel="noopener noreferrer"&gt;Spring Data R2DBC&lt;/a&gt; and in the world of reactive applications with &lt;a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webflux" rel="noopener noreferrer"&gt;Spring WebFlux&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What is R2DBC and why should you bother looking at it? First, R2DBC stands for Reactive Relational Database Connectivity. What does that mean? In simple words, R2DBC brings the possibility of non-blocking calls to our Relational Databases (SQL)!&lt;/p&gt;

&lt;p&gt;Quoting &lt;a href="https://r2dbc.io/" rel="noopener noreferrer"&gt;https://r2dbc.io/&lt;/a&gt;, R2DBC is in a nutshell:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reactive Streams - R2DBC&lt;/strong&gt; is founded on Reactive Streams providing a fully reactive non-blocking API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relational Databases - R2DBC&lt;/strong&gt; engages SQL databases with a reactive API, something not possible with the blocking nature of JDBC.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalable Solutions - Reactive Streams&lt;/strong&gt; makes it possible to move from the classic one thread per connection approach to a more powerful, more scalable approach.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open Specification - R2DBC&lt;/strong&gt; is an open specification establishing a SPI that driver vendors can implement and clients can consume.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this tutorial, we will build a simple REST API with &lt;a href="https://kotlinlang.org/" rel="noopener noreferrer"&gt;Kotlin&lt;/a&gt;, &lt;a href="(https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webflux)"&gt;Spring WebFlux&lt;/a&gt; and we will connect to our &lt;a href="https://www.h2database.com/html/main.html" rel="noopener noreferrer"&gt;H2 Database&lt;/a&gt; using &lt;a href="https://spring.io/projects/spring-data-r2dbc" rel="noopener noreferrer"&gt;Spring Data R2DBC&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;If you want to easily get started with a Springboot project I recommend always using the &lt;a href="https://start.spring.io" rel="noopener noreferrer"&gt;Spring Initializr&lt;/a&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Second Best Place on the Internet @ &lt;a href="https://github.com/joshlong" rel="noopener noreferrer"&gt;Josh Long&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Gradle Configuration
&lt;/h2&gt;

&lt;p&gt;First of all, we have to configure our &lt;code&gt;build.gradle.kts&lt;/code&gt; and include the dependencies:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;For the complete &lt;code&gt;build.gradle.kts&lt;/code&gt; check here:&lt;br&gt;
&lt;a href="https://github.com/Petros0/springboot-full-reactive-kotlin/blob/master/build.gradle.kts" rel="noopener noreferrer"&gt;build.gradle.kts&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Application Configuration
&lt;/h2&gt;

&lt;p&gt;Spring Boot comes with a handful of auto-configurations for Spring Data R2DBC out-of-the-box.&lt;br&gt;
Below we are leveraging the power of Spring Boot to create a connection to the database:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Then we create a table called &lt;code&gt;Employee&lt;/code&gt; and we populate it with some data:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;While that may not seem really safe, in our application we do not have any problems, while the database will always be created on startup and destroyed on shutdown of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  REST API
&lt;/h2&gt;

&lt;p&gt;Ok, so we created our database and we populated it with data, now what? Let's make use of it and create a REST API!&lt;/p&gt;

&lt;p&gt;Below we have a simple domain model called &lt;code&gt;Employee&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Then, let's create our repository, which will provide some queries out-of-the-box and we will also define one of our own. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Last but not least, let's create our endpoint:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;Let's execute our application with the command &lt;code&gt;./gradlew bootRun&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The application now runs on &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;!! Congratulations!&lt;/p&gt;

&lt;h1&gt;
  
  
  Closing thoughts
&lt;/h1&gt;

&lt;p&gt;Spring Data R2DBC is still on experimental stage. Although it is on the official release of Spring Boot 2.2.0, I would not recommend using it on production :).&lt;/p&gt;

&lt;p&gt;I hope you now have a better understanding of R2DBC.&lt;/p&gt;

&lt;p&gt;You can find the repository right here:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Petros0" rel="noopener noreferrer"&gt;
        Petros0
      &lt;/a&gt; / &lt;a href="https://github.com/Petros0/spring-boot-r2dbc-kotlin" rel="noopener noreferrer"&gt;
        spring-boot-r2dbc-kotlin
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Spring Boot R2DBC&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;This project aims to give an idea on how to work with the R2DBC and Spring Data R2DBC.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;code&gt;./gradlew bootRun&lt;/code&gt;, the application now runs localhost:8080.&lt;/p&gt;
&lt;p&gt;Navigate to:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://localhost:8080/employees/" rel="nofollow noopener noreferrer"&gt;http://localhost:8080/employees/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Available endpoints:&lt;/p&gt;
&lt;p&gt;GET &lt;a href="http://localhost:8080/employees/" rel="nofollow noopener noreferrer"&gt;http://localhost:8080/employees/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;GET &lt;a href="http://localhost:8080/employees/1" rel="nofollow noopener noreferrer"&gt;http://localhost:8080/employees/1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;POST &lt;a href="http://localhost:8080/employees/" rel="nofollow noopener noreferrer"&gt;http://localhost:8080/employees/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;DELETE &lt;a href="http://localhost:8080/employees/" rel="nofollow noopener noreferrer"&gt;http://localhost:8080/employees/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Petros0/spring-boot-r2dbc-kotlin" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://r2dbc.io/" rel="noopener noreferrer"&gt;R2DBC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spring.io/projects/spring-data-r2dbc" rel="noopener noreferrer"&gt;Spring Data R2DBC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webflux" rel="noopener noreferrer"&gt;Spring WebFlux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>java</category>
      <category>kotlin</category>
      <category>springboot</category>
    </item>
    <item>
      <title>Getting started with RSocket in Spring Boot</title>
      <dc:creator>Petros Stergioulas</dc:creator>
      <pubDate>Mon, 10 Jun 2019 14:21:29 +0000</pubDate>
      <link>https://dev.to/petros0/getting-started-with-rsocket-in-springboot-5889</link>
      <guid>https://dev.to/petros0/getting-started-with-rsocket-in-springboot-5889</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;RSocket is a binary protocol for use on byte stream transports such as TCP, WebSockets, and Aeron.&lt;/p&gt;

&lt;p&gt;It enables the following symmetric interaction models via async message passing over a single connection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;request/response (stream of 1)&lt;/li&gt;
&lt;li&gt;request/stream (finite stream of many)&lt;/li&gt;
&lt;li&gt;fire-and-forget (no response)&lt;/li&gt;
&lt;li&gt;event subscription (infinite stream of many)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It supports session resumption, to allow resuming long-lived streams across different transport connections. This is particularly useful for mobile⬄server communication when network connections drop, switch, and reconnect frequently.&lt;/p&gt;

&lt;p&gt;In our tutorial, we will implement RSocket using the Java programming language.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Springboot
&lt;/h1&gt;

&lt;p&gt;Although I could simply implement RSocket with a simple Java application, I chose Springboot because it's a huge project on the JVM languages ecosystem. Springboot doesn't have a stable version for RSocket yet, but that shouldn't stop us experimenting with it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Structure
&lt;/h1&gt;

&lt;p&gt;Our project will consist of two sub-projects. The &lt;strong&gt;Consumer&lt;/strong&gt;, who will do the requests and the &lt;strong&gt;Producer&lt;/strong&gt;, who will provide the &lt;strong&gt;Consumer&lt;/strong&gt; with data.&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;If you want to easily get started with a Springboot project I recommend always using the &lt;a href="https://start.spring.io/" rel="noopener noreferrer"&gt;Spring Initializr&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Gradle
&lt;/h2&gt;

&lt;p&gt;First of all we have to configure our build.gradle and include the rsocket-starter-dependency from Springboot:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;For the &lt;strong&gt;Consumer&lt;/strong&gt; we should include also the reactive-web-starter dependency, because we want to somehow display the data that we receive from the &lt;strong&gt;Producer&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Configuration
&lt;/h1&gt;

&lt;p&gt;Now let's get our hands dirty and write some code 😉.&lt;/p&gt;

&lt;h2&gt;
  
  
  Producer
&lt;/h2&gt;

&lt;p&gt;First we have to configure in which port will our &lt;strong&gt;Producer&lt;/strong&gt; receive new connections:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;spring.rsocket.server.port=7000&lt;/code&gt; configures the RSocket to start listening on port 7000 and the &lt;code&gt;spring.main.lazy-initialization=true&lt;/code&gt; is to make sure that Springboot will initialize its beans lazily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consumer
&lt;/h2&gt;

&lt;p&gt;Now, here, we configure the RSocket client, by creating two &lt;em&gt;Beans&lt;/em&gt; of type &lt;em&gt;RSocket&lt;/em&gt; and &lt;em&gt;RSocketRequester&lt;/em&gt;. The &lt;em&gt;RSocket bean&lt;/em&gt; is used to create the connection to the &lt;strong&gt;Producer&lt;/strong&gt;. The &lt;em&gt;RSocketRequester bean&lt;/em&gt; is like our &lt;code&gt;WebClient&lt;/code&gt; (if we are using Reactive) or the &lt;code&gt;RestTemplate&lt;/code&gt; (if we are using MVC), he will do the requests to &lt;strong&gt;Producer&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  The Actual Code
&lt;/h1&gt;

&lt;p&gt;Our two applications (the &lt;strong&gt;Producer&lt;/strong&gt; and the &lt;strong&gt;Consumer&lt;/strong&gt;) will use the following domain objects for their communication:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Simple Communication
&lt;/h2&gt;

&lt;p&gt;Let's start with an easy example, a simple Request with a single Response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Producer
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;If you ever used WebSockets with Springboot the &lt;code&gt;@MessageMapping&lt;/code&gt; annotation should be familiar.&lt;br&gt;
Here, with the &lt;code&gt;@MessageMapping("greet")&lt;/code&gt; we specify the route "greet", which receives a &lt;code&gt;GreetingsRequest&lt;/code&gt; and returns a single object &lt;code&gt;GreetingsResponse&lt;/code&gt; as a response.&lt;/p&gt;
&lt;h3&gt;
  
  
  Consumer
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here we see a simple &lt;code&gt;@RestController&lt;/code&gt; which injects the &lt;code&gt;RSocketRequester&lt;/code&gt; (the one we configured earlier) and uses him to do the Request. As you see, we tell the &lt;code&gt;requester&lt;/code&gt; to do a Request to the "greet" route (which we configured earlier in the &lt;strong&gt;Producer&lt;/strong&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Communication with Stream
&lt;/h2&gt;

&lt;p&gt;Delivering a stream of data with RSocket comes natural and with not that much of an effort.&lt;/p&gt;

&lt;h3&gt;
  
  
  Producer
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As you see in the gist above, we configured our &lt;code&gt;@MessageMapping&lt;/code&gt; as before, but now we return a Flux (don't know what Mono and Flux are? Check this &lt;a href="https://stackoverflow.com/questions/47988433/mono-vs-flux-in-reactive-stream" rel="noopener noreferrer"&gt;StackOverflow post&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;We also use the &lt;code&gt;.delayElements()&lt;/code&gt; method to simulate a delay between our responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consumer
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Not much have changed from our other request to the &lt;strong&gt;Producer&lt;/strong&gt;, clearly the &lt;code&gt;.route("greet-stream")&lt;/code&gt;. But if you see carefully, now our &lt;code&gt;@GetMapping&lt;/code&gt; produces a &lt;code&gt;text/event-stream&lt;/code&gt; and not the default &lt;code&gt;application/json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's check the result!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frnvju92cycxq5iagxkqr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frnvju92cycxq5iagxkqr.gif" alt="Greet Stream" width="498" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Closing thoughts
&lt;/h1&gt;

&lt;p&gt;So, that was it! I hope I gave you a clear explanation on how to use the new RSocket protocol!&lt;/p&gt;

&lt;p&gt;You can find the project here: &lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Petros0" rel="noopener noreferrer"&gt;
        Petros0
      &lt;/a&gt; / &lt;a href="https://github.com/Petros0/springboot-rsocket" rel="noopener noreferrer"&gt;
        springboot-rsocket
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Springboot RSocket&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://travis-ci.com/Petros0/springboot-rsocket" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/dcbbbc2c77e42a93602772d0c2a232ae1bd9ce65f059158569ebad5c23ecb33a/68747470733a2f2f7472617669732d63692e636f6d2f506574726f73302f737072696e67626f6f742d72736f636b65742e7376673f6272616e63683d6d6173746572" alt="Build Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This project aims to give an idea on how to work with the RSocket protocol with the Springboot framework.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting started&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;code&gt;./gradlew :producer:bootRun&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;./gradlew :consumer:bootRun&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Navigate to:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://localhost:8080/greet/%7BYourName%7D" rel="nofollow noopener noreferrer"&gt;http://localhost:8080/greet/{YourName}&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://localhost:8080/greet-stream/%7BYourName%7D" rel="nofollow noopener noreferrer"&gt;http://localhost:8080/greet-stream/{YourName}&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For more, check my getting started guide here: &lt;a href="https://dev.to/petros0/getting-started-with-rsocket-in-springboot-5889" rel="nofollow"&gt;https://dev.to/petros0/getting-started-with-rsocket-in-springboot-5889&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;



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


&lt;p&gt;Thanks for reading and have fun!&lt;/p&gt;

&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://rsocket.io/" rel="noopener noreferrer"&gt;RSocket&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=BxHqeq58xrE" rel="noopener noreferrer"&gt;SpringTips from Josh&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>java</category>
      <category>spring</category>
      <category>rsocket</category>
    </item>
    <item>
      <title>I wanna start learning about Machine Learning. From where should I start?</title>
      <dc:creator>Petros Stergioulas</dc:creator>
      <pubDate>Sun, 14 Oct 2018 14:57:04 +0000</pubDate>
      <link>https://dev.to/petros0/i-wanna-start-learning-about-machine-learning-from-where-should-i-start-21p6</link>
      <guid>https://dev.to/petros0/i-wanna-start-learning-about-machine-learning-from-where-should-i-start-21p6</guid>
      <description>

</description>
      <category>machinelearning</category>
      <category>dev</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
