<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Tien Nguyen</title>
    <description>The latest articles on Forem by Tien Nguyen (@tienbku).</description>
    <link>https://forem.com/tienbku</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%2F538076%2F7069aa26-0d66-40d4-9056-29af0d8d284f.png</url>
      <title>Forem: Tien Nguyen</title>
      <link>https://forem.com/tienbku</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tienbku"/>
    <language>en</language>
    <item>
      <title>Spring Data REST example</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Tue, 21 Nov 2023 04:38:26 +0000</pubDate>
      <link>https://forem.com/tienbku/spring-data-rest-example-ggg</link>
      <guid>https://forem.com/tienbku/spring-data-rest-example-ggg</guid>
      <description>&lt;p&gt;In this tutorial, we're gonna build a Spring Data REST example in Spring Boot CRUD REST API with Maven that uses Spring Data JPA to interact with H2 database without having to manually implement controller and handling HTTP requests. You'll know:&lt;/p&gt;

&lt;ul&gt;
        &lt;li&gt;How to configure Spring Data REST, JPA, Hibernate to work with Database&lt;/li&gt;
        &lt;li&gt;How to define Data Models and Repository interfaces&lt;/li&gt;
    &lt;li&gt;Way to use Spring Data JPA to interact with H2 Database&lt;/li&gt;
    &lt;li&gt;How to check CRUD operations with Postman&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Spring Data REST&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Purpose:&lt;/strong&gt; Spring Data REST builds on top of Spring Data repositories and exposes them as RESTful services. It automates the process of exposing JPA repositories as RESTful endpoints.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic generation of RESTful APIs for Spring Data repositories.&lt;/li&gt;
&lt;li&gt;Supports CRUD operations over HTTP (GET, POST, PUT, DELETE) for entities.&lt;/li&gt;
&lt;li&gt;Follows HATEOAS (Hypermedia as the Engine of Application State) principles, providing discoverable APIs.&lt;/li&gt;
&lt;li&gt;Customization of endpoints and response formats.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt; Spring Data REST is used when you want to quickly expose your Spring Data JPA repositories as RESTful services without having to manually implement controllers and handling HTTP requests. It's useful for rapidly building APIs over your data model.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;Spring Data REST example&lt;/h2&gt;

&lt;p&gt;We will build a Spring Boot Data REST example for a Tutorial application in that:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Each Tutorial has id, title, description, published status.&lt;/li&gt;
    &lt;li&gt;We can create, retrieve, update, delete Tutorials.&lt;/li&gt;
    &lt;li&gt;We have custom finder methods such as find by published status or by title.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are REST APIs that we provide:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Methods&lt;/th&gt;
&lt;th&gt;Urls&lt;/th&gt;
&lt;th&gt;Actions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/api/tutorials&lt;/td&gt;
&lt;td&gt;create new Tutorial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/api/tutorials&lt;/td&gt;
&lt;td&gt;retrieve all Tutorials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/api/tutorials/:id&lt;/td&gt;
&lt;td&gt;retrieve a Tutorial by &lt;code&gt;:id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;/api/tutorials/:id&lt;/td&gt;
&lt;td&gt;update a Tutorial by &lt;code&gt;:id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;/api/tutorials/:id&lt;/td&gt;
&lt;td&gt;delete a Tutorial by &lt;code&gt;:id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We also have APIs for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;filtering all published/unpublished Tutorials:&lt;br&gt;
&lt;code&gt;GET /api/tutorials/search/findByPublished?published=[status]&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;filtering all Tutorials which title contains &lt;code&gt;keyword&lt;/code&gt;&lt;br&gt;
&lt;code&gt;/api/tutorials/search/findByTitleContainingIgnoreCase?title=[keyword]&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Technology&lt;/h2&gt;

&lt;ul&gt;
        &lt;li&gt;Java 17 / 11 / 8&lt;/li&gt;
        &lt;li&gt;Spring Boot 3 / 2 (with Spring Data REST, Spring Data JPA)&lt;/li&gt;
        &lt;li&gt;H2 Database&lt;/li&gt;
        &lt;li&gt;Maven&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Project Structure&lt;/h2&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-project.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-project.png" alt="spring-data-rest-example-project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me explain it briefly.&lt;/p&gt;

&lt;p&gt;– &lt;code&gt;Tutorial&lt;/code&gt; data model class corresponds to entity and table &lt;em&gt;tutorials&lt;/em&gt;.&lt;br&gt;
– &lt;code&gt;TutorialRepository&lt;/code&gt; is an interface that extends &lt;a href="https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html" rel="noopener noreferrer"&gt;JpaRepository&lt;/a&gt; for CRUD methods and custom finder methods.&lt;br&gt;
– Configuration for Spring Data REST, Datasource, JPA &amp;amp; Hibernate in &lt;strong&gt;application.properties&lt;/strong&gt;.&lt;br&gt;
– &lt;strong&gt;pom.xml&lt;/strong&gt; contains dependencies for Spring Boot and H2.&lt;/p&gt;

&lt;p&gt;We can improve the example by adding Comments for each Tutorial. It is the One-to-Many Relationship and I write a tutorial for this at:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/jpa-one-to-many/" rel="noopener noreferrer"&gt;Spring Boot One To Many example with JPA, Hibernate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or add Tags with Many-to-Many Relationship:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/jpa-many-to-many/" rel="noopener noreferrer"&gt;Spring Boot Many to Many example with JPA, Hibernate&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Create &amp;amp; Setup Spring Boot project&lt;/h2&gt;

&lt;p&gt;Use &lt;a href="http://start.spring.io/" rel="noopener noreferrer"&gt;Spring web tool&lt;/a&gt; or your development tool (&lt;a href="https://spring.io/tools" rel="noopener noreferrer"&gt;Spring Tool Suite&lt;/a&gt;, Eclipse, &lt;a href="https://www.jetbrains.com/idea/download/" rel="noopener noreferrer"&gt;Intellij&lt;/a&gt;) to create a Spring Boot project.&lt;/p&gt;

&lt;p&gt;Then open &lt;strong&gt;pom.xml&lt;/strong&gt; and add these dependencies:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&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;org.springframework.boot&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;spring-boot-starter-data-jpa&lt;span class="nt"&gt;&amp;lt;/artifactId&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;org.springframework.boot&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;spring-boot-starter-data-rest&lt;span class="nt"&gt;&amp;lt;/artifactId&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;com.h2database&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;h2&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&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;h2&gt;Configure Spring Data REST, JPA, h2, Hibernate&lt;/h2&gt;

&lt;p&gt;Under &lt;strong&gt;src&lt;/strong&gt;/&lt;strong&gt;main&lt;/strong&gt;/&lt;strong&gt;resources&lt;/strong&gt; folder, open &lt;em&gt;application.properties&lt;/em&gt; and write these lines.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;spring.data.rest.basePath&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;api&lt;/span&gt;

&lt;span class="py"&gt;spring.h2.console.enabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="c"&gt;# default path: h2-console
&lt;/span&gt;&lt;span class="py"&gt;spring.h2.console.path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/h2-ui&lt;/span&gt;

&lt;span class="py"&gt;spring.datasource.url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;jdbc:h2:file:./testdb&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.driverClassName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;org.h2.Driver&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.username&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;sa&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.password&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;

&lt;span class="py"&gt;spring.jpa.show-sql&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;spring.jpa.properties.hibernate.dialect&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;org.hibernate.dialect.H2Dialect&lt;/span&gt;
&lt;span class="py"&gt;spring.jpa.hibernate.ddl-auto&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;update&lt;/span&gt;


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

&lt;/div&gt;

&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;spring.data.rest.basePath&lt;/code&gt;: the root URI for Spring Data REST&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;spring.datasource.url&lt;/code&gt;: &lt;code&gt;jdbc:h2:mem:[database-name]&lt;/code&gt; for In-memory database and &lt;code&gt;jdbc:h2:file:[path/database-name]&lt;/code&gt; for disk-based database.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;spring.datasource.username&lt;/code&gt; &amp;amp; &lt;code&gt;spring.datasource.password&lt;/code&gt; properties are the same as your database installation.&lt;/li&gt;
    &lt;li&gt;Spring Boot uses Hibernate for JPA implementation, we configure &lt;code&gt;H2Dialect&lt;/code&gt; for H2 Database&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;spring.jpa.hibernate.ddl-auto&lt;/code&gt; is used for database initialization. We set the value to &lt;code&gt;update&lt;/code&gt; value so that a table will be created in the database automatically corresponding to defined data model. Any change to the model will also trigger an update to the table. For production, this property should be &lt;code&gt;validate&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;spring.h2.console.enabled=true&lt;/code&gt; tells the Spring to start H2 Database administration tool and you can access this tool on the browser: &lt;code&gt;http://localhost:8080/h2-console&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;spring.h2.console.path=/h2-ui&lt;/code&gt; is for H2 console's url, so the default url &lt;code&gt;http://localhost:8080/h2-console&lt;/code&gt; will change to &lt;code&gt;http://localhost:8080/h2-ui&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also alter the following Spring Data REST properties (starting with &lt;code&gt;spring.data.rest.&lt;/code&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;defaultPageSize&lt;/code&gt;: change the default for the number of items served in a single page.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;maxPageSize&lt;/code&gt;: change the maximum number of items in a single page.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pageParamName&lt;/code&gt;: change the name of the query parameter for selecting pages.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;limitParamName&lt;/code&gt;: change the name of the query parameter for the number of items to show in a page.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sortParamName&lt;/code&gt;: change the name of the query parameter for sorting.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;defaultMediaType&lt;/code&gt;: change the default media type to use when none is specified.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;returnBodyOnCreate&lt;/code&gt;: change whether a body should be returned when creating a new entity.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;returnBodyOnUpdate&lt;/code&gt;: change whether a body should be returned when updating an entity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Define Data Model&lt;/h2&gt;

&lt;p&gt;Our Data model is Tutorial with four fields: id, title, description, published.&lt;br&gt;
In &lt;strong&gt;model&lt;/strong&gt; package, we define &lt;code&gt;Tutorial&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;model/Tutorial.java&lt;/em&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.data.rest.model&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;jakarta.persistence.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Entity&lt;/span&gt;
&lt;span class="nd"&gt;@Table&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;"tutorials"&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;Tutorial&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Id&lt;/span&gt;
  &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;AUTO&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;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;@Column&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;"title"&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;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Column&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;"description"&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;description&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Column&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;"published"&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;boolean&lt;/span&gt; &lt;span class="n"&gt;published&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;Tutorial&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="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Tutorial&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;title&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;description&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;published&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;title&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="k"&gt;this&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="n"&gt;description&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;published&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;published&lt;/span&gt;&lt;span class="o"&gt;;&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;ul&gt;
&lt;li&gt;
&lt;code&gt;@Entity&lt;/code&gt; annotation indicates that the class is a persistent Java class.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Table&lt;/code&gt; annotation provides the table that maps this entity.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Id&lt;/code&gt; annotation is for the primary key.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@GeneratedValue&lt;/code&gt; annotation is used to define generation strategy for the primary key. &lt;code&gt;GenerationType.AUTO&lt;/code&gt; means Auto Increment field.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Column&lt;/code&gt; annotation is used to define the column in database that maps annotated field.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Create Repository Interface&lt;/h2&gt;

&lt;p&gt;Let's create a repository to interact with Tutorials from the database.&lt;br&gt;
In &lt;strong&gt;repository&lt;/strong&gt; package, create &lt;code&gt;TutorialRepository&lt;/code&gt; interface that extends &lt;code&gt;JpaRepository&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;repository/TutorialRepository.java&lt;/em&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.data.rest.repository&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.data.jpa.repository.JpaRepository&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.data.rest.core.annotation.RepositoryRestResource&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.CrossOrigin&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;com.bezkoder.spring.data.rest.model.Tutorial&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@RepositoryRestResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"tutorials"&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;TutorialRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByPublished&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;published&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByTitleContainingIgnoreCase&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;title&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;To expose the repository as a RESTful resource, you annotate the repository interface with &lt;code&gt;@RepositoryRestResource&lt;/code&gt;. This annotation allows you to customize the RESTful endpoints and behavior, and &lt;code&gt;path&lt;/code&gt; defines the base URI path for the resource.&lt;/p&gt;

&lt;p&gt;We also define custom finder methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;findByPublished()&lt;/code&gt;: returns all Tutorials with &lt;code&gt;published&lt;/code&gt; having value as input &lt;code&gt;published&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;findByTitleContaining()&lt;/code&gt;: returns all Tutorials which title contains input &lt;code&gt;title&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The implementation is plugged in by &lt;a href="https://docs.spring.io/spring-data/jpa/docs/current/reference/html/" rel="noopener noreferrer"&gt;Spring Data JPA&lt;/a&gt; automatically.&lt;/p&gt;

&lt;p&gt;More Derived queries at:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/jpa-repository-query/" rel="noopener noreferrer"&gt;JPA Repository query example in Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Custom query with &lt;code&gt;@Query&lt;/code&gt; annotation:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-jpa-query/" rel="noopener noreferrer"&gt;Spring JPA @Query example: Custom query in Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can modify this Repository:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to work with Pagination, the instruction can be found at:
&lt;a href="https://www.bezkoder.com/spring-boot-pagination-filter-jpa-pageable/" rel="noopener noreferrer"&gt;Spring Boot Pagination &amp;amp; Filter example | Spring JPA, Pageable&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;or to sort/order by multiple fields with the tutorial:
&lt;a href="https://www.bezkoder.com/spring-data-sort-multiple-columns/" rel="noopener noreferrer"&gt;Spring Data JPA Sort/Order by multiple Columns | Spring Boot&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You also find way to write Unit Test for this JPA Repository at:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for JPA Repository with @DataJpaTest&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Configure CORS in Spring Data REST&lt;/h2&gt;

&lt;p&gt;We add a &lt;code&gt;@CrossOrigin&lt;/code&gt; annotation to the repository interface to enable CORS for the whole &lt;code&gt;TutorialRepository &lt;/code&gt;repository.&lt;/p&gt;

&lt;p&gt;By default, &lt;code&gt;@CrossOrigin &lt;/code&gt;allows all origins and HTTP methods.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;repository/TutorialRepository.java&lt;/em&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;// ...&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.CrossOrigin&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@CrossOrigin&lt;/span&gt;
&lt;span class="nd"&gt;@RepositoryRestResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"tutorials"&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;TutorialRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We can provide one origin, restricted to several HTTP methods with a specific max age.&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;@CrossOrigin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;origins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://yourdomain.example"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;methods&lt;/span&gt; &lt;span class="o"&gt;=&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;GET&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="nc"&gt;RequestMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;},&lt;/span&gt;
  &lt;span class="n"&gt;maxAge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@RepositoryRestResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"tutorials"&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;TutorialRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;h2&gt;Run &amp;amp; Test&lt;/h2&gt;

&lt;p&gt;Run Spring Boot application with command: &lt;code&gt;mvn spring-boot:run&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;tutorials&lt;/em&gt;&lt;/strong&gt; table will be automatically generated in Database.&lt;/p&gt;

&lt;p&gt;Let's open H2 console with url: &lt;code&gt;&lt;a href="http://localhost:8080/h2-ui" rel="noopener noreferrer"&gt;http://localhost:8080/h2-ui&lt;/a&gt;&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For In-memory database:&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-h2-console-in-memory.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-h2-console-in-memory.png" alt="spring-data-rest-example-h2-console-in-memory"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For on Disk database:&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-h2-console-on-disk.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-h2-console-on-disk.png" alt="spring-data-rest-example-h2-console-on-disk"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;Connect&lt;/strong&gt; button, then check H2 database, you can see things 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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-database-table.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-database-table.png" alt="spring-data-rest-example-database-table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create some Tutorials:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-create.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-create.png" alt="spring-data-rest-example-crud-create"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Retrieve all Tutorials:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-retrieve.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-retrieve.png" alt="spring-data-rest-example-crud-retrieve"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Retrieve a Tutorial by Id:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-retrieve-one.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-retrieve-one.png" alt="spring-data-rest-example-crud-retrieve-one"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update some Tutorials:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-update.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-update.png" alt="spring-data-rest-example-crud-update"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The table data is changed:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-update-database.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-update-database.png" alt="spring-data-rest-example-crud-update-database"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spring Data REST to filter all &lt;em&gt;&lt;strong&gt;published&lt;/strong&gt;&lt;/em&gt; Tutorials:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-filter-example.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-filter-example.png" alt="spring-data-rest-filter-example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Find all Tutorials which title contains string 'data':&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-search-example.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-search-example.png" alt="spring-data-rest-search-example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Delete a Tutorial:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-delete.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-delete.png" alt="spring-data-rest-example-crud-delete"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check database and it has been already deleted.&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-delete-table.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fspring-data-rest-example-crud-delete-table.png" alt="spring-data-rest-example-crud-delete-table"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Today we've built a Spring Boot Rest CRUD API using Spring Data REST example and make Spring Data JPA work with H2 Database.&lt;/p&gt;

&lt;p&gt;We also see that &lt;code&gt;JpaRepository&lt;/code&gt; supports a great way to make CRUD operations and custom finder methods without need of boilerplate code.&lt;/p&gt;

&lt;p&gt;Happy learning! See you again.&lt;/p&gt;

&lt;h2&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://docs.spring.io/spring-data/rest/reference/" rel="noopener noreferrer"&gt;Spring Data REST Reference Documentation&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://docs.spring.io/spring-data/jpa/reference/jpa.html" rel="noopener noreferrer"&gt;Spring Data JPA Reference Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fullstack CRUD App:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-thymeleaf-example/" rel="noopener noreferrer"&gt;Spring Boot Thymeleaf example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-vue-js-crud-example/" rel="noopener noreferrer"&gt;Vue + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-spring-boot-crud/" rel="noopener noreferrer"&gt;Angular 8 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-10-spring-boot-crud/" rel="noopener noreferrer"&gt;Angular 10 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-11-spring-boot-crud/" rel="noopener noreferrer"&gt;Angular 11 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-12-spring-boot-crud/" rel="noopener noreferrer"&gt;Angular 12 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-angular-13-crud/" rel="noopener noreferrer"&gt;Angular 13 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-angular-14-crud/" rel="noopener noreferrer"&gt;Angular 14 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-angular-15-crud/" rel="noopener noreferrer"&gt;Angular 15 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-angular-16-crud/" rel="noopener noreferrer"&gt;Angular 16 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/react-spring-boot-crud/" rel="noopener noreferrer"&gt;React + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to add Pagination to this Spring project, you can find the instruction at:&lt;br&gt;
&lt;a href="https://bezkoder.com/spring-boot-pagination-filter-jpa-pageable/" rel="noopener noreferrer"&gt;Spring Boot Pagination &amp;amp; Filter example | Spring JPA, Pageable&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To sort/order by multiple fields:&lt;br&gt;
&lt;a href="https://bezkoder.com/spring-data-sort-multiple-columns/" rel="noopener noreferrer"&gt;Spring Data JPA Sort/Order by multiple Columns | Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or way to write Unit Test:&lt;br&gt;
&lt;a href="https://bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for JPA Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can improve the example by adding Comments for each Tutorial. It is the One-to-Many Relationship and I write a tutorial for this at:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/jpa-one-to-many/" rel="noopener noreferrer"&gt;Spring Boot One To Many example with JPA, Hibernate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or add Tags with Many-to-Many Relationship:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/jpa-many-to-many/" rel="noopener noreferrer"&gt;Spring Boot Many to Many example with JPA, Hibernate&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Source Code&lt;/h2&gt;

&lt;p&gt;You can find the complete source code for this tutorial on &lt;a href="https://github.com/bezkoder/spring-data-rest-example" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With Rest Controller: &lt;a href="https://www.bezkoder.com/spring-boot-jpa-h2-example/" rel="noopener noreferrer"&gt;Spring Boot JPA + H2 example: Build a CRUD Rest APIs&lt;/a&gt;&lt;br&gt;
Or APIs with GraphQL:&lt;a href="https://www.bezkoder.com/spring-boot-graphql-example/" rel="noopener noreferrer"&gt;Spring Boot + GraphQL example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More JPA queries at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-jpa-query/" rel="noopener noreferrer"&gt;Spring JPA @Query example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/jpa-repository-query/" rel="noopener noreferrer"&gt;JPA Repository query example | Derived Query&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/jpa-native-query/" rel="noopener noreferrer"&gt;JPA Native Query example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Validation:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-boot-validate-request-body/" rel="noopener noreferrer"&gt;Validate Request Body in Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reactive with R2DBC:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-boot-r2dbc-h2/" rel="noopener noreferrer"&gt;Spring Boot R2DBC + H2 example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Documentation: &lt;a href="https://www.bezkoder.com/spring-boot-swagger-3/" rel="noopener noreferrer"&gt;Spring Boot + Swagger 3 example (with OpenAPI 3)&lt;/a&gt;&lt;br&gt;
Caching: &lt;a href="https://www.bezkoder.com/spring-boot-redis-cache-example/" rel="noopener noreferrer"&gt;Spring Boot Redis Cache example&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>springboot</category>
      <category>tutorial</category>
      <category>java</category>
    </item>
    <item>
      <title>Spring Boot + GraphQL example</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Wed, 15 Nov 2023 03:32:28 +0000</pubDate>
      <link>https://forem.com/tienbku/spring-boot-graphql-example-39d8</link>
      <guid>https://forem.com/tienbku/spring-boot-graphql-example-39d8</guid>
      <description>&lt;p&gt;GraphQL is a query language that offers an alternative model to developing APIs (REST, SOAP or gRPC) with detailed description.&lt;/p&gt;

&lt;p&gt;In this tutorial, we're gonna build a Spring Boot GraphQL example with H2 database that will expose CRUD APIs to create, read, update and delete objects with the help of &lt;code&gt;graphql-spring-boot-starter&lt;/code&gt; and &lt;a href="https://docs.spring.io/spring-data/jpa/docs/current/reference/html/"&gt;Spring Data JPA&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Related Post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-graphql-mysql-jpa/"&gt;Spring Boot + GraphQL + MySQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-graphql-postgresql/"&gt;Spring Boot + GraphQL + PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-graphql-mongodb-example-graphql-java/"&gt;Spring Boot + GraphQL + MongoDB example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-3-rest-api/"&gt;Spring Boot 3 Rest API example: CRUD Application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-security-login-jwt/"&gt;Spring Boot Security: Login and Registration example with JWT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-thymeleaf-example/"&gt;Spring Boot Thymeleaf CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Documentation: &lt;a href="https://www.bezkoder.com/spring-boot-swagger-3/"&gt;Spring Boot Swagger 3 example&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Unit Test: &lt;a href="https://www.bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/"&gt;@DataJpaTest example for Spring Data Repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Caching: &lt;a href="https://www.bezkoder.com/spring-boot-redis-cache-example/"&gt;Spring Boot Redis Cache example&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Spring Boot GraphQL example&lt;/h2&gt;

&lt;h3&gt;Overview&lt;/h3&gt;

&lt;p&gt;We have two data models: Author and Tutorial.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="err"&gt;Author&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Long&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Tutorial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Long&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Author&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;One Author will have many Tutorials, so it is One-to-Many relationship.&lt;/p&gt;

&lt;p&gt;The goal of this example is to build a GraphQL APIs to do CRUD operations with H2 database using only one endpoint: &lt;code&gt;/apis/graphql&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The Spring Boot GraphQL Starter will make GraphQL server running in a short time. &lt;/p&gt;

&lt;h3&gt;CRUD GraphQL APIs&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create an Author:
GraphQL
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;createAuthor(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;name:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bezkoder"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;age:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="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;Response&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"createAuthor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bezkoder"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;ul&gt;
&lt;li&gt;Create a Tutorial:
GraphQL: we want response including Tutorial id, title and author (name)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;createTutorial&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;title:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tutorial #1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;description:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Description for Tut#1"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;author:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;author&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"createTutorial"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tutorial #1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bezkoder"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Read all Authors:
GraphQL
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;findAllAuthors&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;age&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="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;Response&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"findAllAuthors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="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="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bezkoder"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="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="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"zKoder"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Read all Tutorials:
GraphQL
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;findAllTutorials&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;description&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;author&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"findAllTutorials"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="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="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tutorial #1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Description for Tut#1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bezkoder"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tutorial #2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Description for Tut#2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bezkoder"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tutorial #3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Description for Tut#3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"zKoder"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;ul&gt;
&lt;li&gt;Update a Tutorial:
GraphQL
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;updateTutorial&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;id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;description:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"updated Desc Tut#2"&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;description&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;author&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"updateTutorial"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tutorial #2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"updated Desc Tut#2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bezkoder"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Delete a Tutorial:
GraphQL
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;deleteTutorial(id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deleteTutorial"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;ul&gt;
&lt;li&gt;Count number of Tutorials:
GraphQL
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;countTutorials&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;Response&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"countTutorials"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="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;If you check H2 database, it will have 2 tables: &lt;strong&gt;author&lt;/strong&gt; and &lt;strong&gt;tutorial&lt;/strong&gt;.&lt;br&gt;
The content inside these tables looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H7QHT7dF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/01p3oyiruekyrfw4eno8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H7QHT7dF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/01p3oyiruekyrfw4eno8.png" alt="spring-boot-graphql-example-table" width="300" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Step by step to build Spring Boot GraphQL example&lt;/h2&gt;

&lt;h3&gt;Technology&lt;/h3&gt;

&lt;p&gt;Our Spring Boot application will use:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Java 17 / 11 / 8&lt;/li&gt;
    &lt;li&gt;Spring Boot 3 / 2 (with Spring Web, Spring Data JPA)&lt;/li&gt;
    &lt;li&gt;graphql-spring-boot-starter 15.0.0&lt;/li&gt;
    &lt;li&gt;graphql-java-tools 5.2.4&lt;/li&gt;
    &lt;li&gt;Maven 3.6.1&lt;/li&gt;
    &lt;li&gt;H2 database&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;This is folders &amp;amp; files structure for our Spring Boot + GraphQL application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hsGToF7k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/81l0z2exiouyscs8u9uv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hsGToF7k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/81l0z2exiouyscs8u9uv.png" alt="spring-boot-graphql-example-project" width="280" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;resources/graphql&lt;/strong&gt; contains &lt;code&gt;.graphqls&lt;/code&gt; files that define GraphQL chemas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;model&lt;/strong&gt; holds two Entities: &lt;code&gt;Author&lt;/code&gt; and &lt;code&gt;Tutorial&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;repository&lt;/strong&gt; contains Repository interfaces to interact with H2 database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;resolver&lt;/strong&gt; resolves values for query &amp;amp; mutation requests by implementing some &lt;code&gt;Resolver&lt;/code&gt; interfaces from GraphQL Java Tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;application.properties&lt;/strong&gt; configures Spring Datasource, Spring Data JPA and GraphQL base Url.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pom.xml&lt;/strong&gt; includes dependencies for the whole project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Set up the project&lt;/h3&gt;

&lt;p&gt;Create new Spring Boot project using &lt;a href="https://spring.io/tools3/sts/"&gt;Spring Tool Suite&lt;/a&gt; or going to &lt;a href="https://start.spring.io/"&gt;&lt;/a&gt;&lt;a href="https://start.spring.io/"&gt;https://start.spring.io/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then add these dependencies to &lt;strong&gt;pom.xml&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&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;org.springframework.boot&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;spring-boot-starter-data-jpa&lt;span class="nt"&gt;&amp;lt;/artifactId&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;org.springframework.boot&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;spring-boot-starter-web&lt;span class="nt"&gt;&amp;lt;/artifactId&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;com.graphql-java-kickstart&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;graphql-spring-boot-starter&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;15.0.0&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;com.graphql-java&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;graphql-java-tools&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;5.2.4&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;com.graphql-java&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;graphql-java-extended-scalars&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;21.0&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;com.h2database&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;h2&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&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;h3&gt;Configure Spring Datasource, JPA, GraphQL&lt;/h3&gt;

&lt;p&gt;Open &lt;strong&gt;application.properties&lt;/strong&gt; and add the following configuration.&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="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nl"&gt;path:&lt;/span&gt; &lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;console&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;console&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ui&lt;/span&gt;

&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nl"&gt;jdbc:h2:file:&lt;/span&gt;&lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="n"&gt;testdb&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;driverClassName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Driver&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sa&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;

&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jpa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jpa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hibernate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dialect&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hibernate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dialect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;H2Dialect&lt;/span&gt;
&lt;span class="n"&gt;spring&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jpa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hibernate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ddl&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nc"&gt;Graphql&lt;/span&gt;
&lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;servlet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapping&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apis&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;graphql&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;spring.datasource.url&lt;/code&gt;: &lt;code&gt;jdbc:h2:mem:[database-name]&lt;/code&gt; for In-memory database and &lt;code&gt;jdbc:h2:file:[path/database-name]&lt;/code&gt; for disk-based database.&lt;/li&gt;
    &lt;li&gt;We configure &lt;code&gt;H2Dialect&lt;/code&gt; for H2 Database&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;spring.h2.console.enabled=true&lt;/code&gt; tells the Spring to start H2 Database administration tool and you can access this tool on the browser: &lt;code&gt;http://localhost:8080/h2-console&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;spring.h2.console.path=/h2-ui&lt;/code&gt; is for H2 console's url, so the default url &lt;code&gt;http://localhost:8080/h2-console&lt;/code&gt; will change to &lt;code&gt;http://localhost:8080/h2-ui&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By default, Spring Boot GraphQL starter exposes the GraphQL Service on &lt;code&gt;/graphql&lt;/code&gt; endpoint for HTTP POST requests containing the GraphQL payload. In the code above, we config the endpoint with new base url: &lt;code&gt;/apis/graphql&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Extend Scalars for graphql-java Long type&lt;/h3&gt;

&lt;p&gt;The implementation of GraphQL Java doesn't provide a Long scalar type by default. So we need to use the &lt;code&gt;graphql-java-extended-scalars&lt;/code&gt; package that provides a &lt;code&gt;GraphQLLong&lt;/code&gt; scalar type definition which represents &lt;code&gt;java.lang.Long&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Open &lt;em&gt;SpringBootGraphqlApplication.java&lt;/em&gt; and add a Bean named &lt;code&gt;extendedScalarLong()&lt;/code&gt;:&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;@SpringBootApplication&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;SpringBootGraphqlApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c1"&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="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GraphQLScalarType&lt;/span&gt; &lt;span class="nf"&gt;extendedScalarLong&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;graphql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scalars&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ExtendedScalars&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GraphQLLong&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;h3&gt;Create GraphQL Schema&lt;/h3&gt;

&lt;p&gt;We're gonna split up your schema into two &lt;code&gt;.graphqls&lt;/code&gt; files. The Spring Boot GraphQL starter will automatically find these schema files.&lt;/p&gt;

&lt;p&gt;Under &lt;strong&gt;src/main/resources&lt;/strong&gt; folder, create &lt;em&gt;author.graphqls&lt;/em&gt; and &lt;em&gt;tutorial.graphqls&lt;/em&gt; files.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;author.graphqls&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;scalar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Long&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Author&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;name:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;String!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;age:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Root&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;findAllAuthors:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;Author&lt;/span&gt;&lt;span class="p"&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;countAuthors:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Long!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Root&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;createAuthor(name:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;String!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;age:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Int):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Author!&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;GraphQL accepts only one root &lt;code&gt;Query&lt;/code&gt; and one root &lt;code&gt;Mutation&lt;/code&gt; types, so we need to bring all the query and mutation operations into the root Types. But in the schemas above, we want to split the logic for each model. How to do this? We extend the &lt;code&gt;Query&lt;/code&gt; and &lt;code&gt;Mutation&lt;/code&gt; types.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;tutorial.graphqls&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Tutorial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;title:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;String!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;description:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;author:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Author&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;extend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;findAllTutorials:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;Tutorial&lt;/span&gt;&lt;span class="p"&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;countTutorials:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Long!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;extend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;createTutorial(title:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;String!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;description:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;author:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Tutorial!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;updateTutorial(id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;title:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;description:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;String):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Tutorial!&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;deleteTutorial(id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Boolean&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 "!" at the end of some fields indicates non-nullable type. If we don't use it, GraphQL accepts &lt;code&gt;null&lt;/code&gt; value in the response.&lt;/p&gt;

&lt;h3&gt;Define Data Models&lt;/h3&gt;

&lt;p&gt;Now we define twom main models with One-to-Many Relationship in &lt;strong&gt;model&lt;/strong&gt; package:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Author: id, name, age&lt;/li&gt;
    &lt;li&gt;Tutorial: id, title, description, author_id&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Author.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.graphql.model&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// import javax.persistence.*;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// for Spring Boot 3&lt;/span&gt;

&lt;span class="nd"&gt;@Entity&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;Author&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Id&lt;/span&gt;
  &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;AUTO&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;@Column&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;"name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&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="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="nd"&gt;@Column&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;"age"&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;age&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;Author&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="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;(&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="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;id&lt;/span&gt; &lt;span class="o"&gt;=&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="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Author&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;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;age&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;name&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="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;;&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;Long&lt;/span&gt; &lt;span class="nf"&gt;getId&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;id&lt;/span&gt;&lt;span class="o"&gt;;&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;String&lt;/span&gt; &lt;span class="nf"&gt;getName&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;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setName&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;name&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;name&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="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="nf"&gt;getAge&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;age&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setAge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;age&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;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&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;String&lt;/span&gt; &lt;span class="nf"&gt;toString&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="s"&gt;"User [id="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", name="&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;", age="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;age&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="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;&lt;em&gt;Tutorial.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.graphql.model&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// import javax.persistence.*;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// for Spring Boot 3&lt;/span&gt;

&lt;span class="nd"&gt;@Entity&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;Tutorial&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Id&lt;/span&gt;
  &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;AUTO&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;@Column&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;"title"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&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="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Column&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;"description"&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;description&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@ManyToOne&lt;/span&gt;
  &lt;span class="nd"&gt;@JoinColumn&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;"author_id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&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="n"&gt;updatable&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="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt; &lt;span class="n"&gt;author&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;Tutorial&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="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Tutorial&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;title&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;description&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt; &lt;span class="n"&gt;author&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;title&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="k"&gt;this&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="n"&gt;description&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;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="nf"&gt;getId&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;id&lt;/span&gt;&lt;span class="o"&gt;;&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;String&lt;/span&gt; &lt;span class="nf"&gt;getTitle&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;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setTitle&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;title&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;title&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="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getDescription&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;description&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setDescription&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;description&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;description&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="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt; &lt;span class="nf"&gt;getAuthor&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;author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setAuthor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Author&lt;/span&gt; &lt;span class="n"&gt;author&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;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="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;String&lt;/span&gt; &lt;span class="nf"&gt;toString&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="s"&gt;"Tutorial [id="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", title="&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;", description="&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;", author="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"]"&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;h3&gt;Create Repositories&lt;/h3&gt;

&lt;p&gt;In &lt;strong&gt;repository&lt;/strong&gt; package, create two interfaces that implement &lt;code&gt;JpaRepository&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AuthorRepository.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.graphql.repository&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.data.jpa.repository.JpaRepository&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;com.bezkoder.spring.graphql.model.Author&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;AuthorRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;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;&lt;em&gt;TutorialRepository.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.graphql.repository&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.data.jpa.repository.JpaRepository&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;com.bezkoder.spring.graphql.model.Tutorial&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;TutorialRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;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;Once we extends the &lt;code&gt;JpaRepository&lt;/code&gt;, Spring Data JPA will automatically generate implementation with find, save, delete, count methods for the entities.&lt;/p&gt;

&lt;h3&gt;Implement GraphQL Root Query Resolver&lt;/h3&gt;

&lt;p&gt;Every field in the schema root query should have a method in the Query Resolver class with the same name.&lt;/p&gt;

&lt;p&gt;Now look back to the schemas we defined above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# author.graphqls&lt;/span&gt;
&lt;span class="nb"&gt;type &lt;/span&gt;Query &lt;span class="o"&gt;{&lt;/span&gt;
    findAllAuthors: &lt;span class="o"&gt;[&lt;/span&gt;Author]!
    countAuthors: Long!
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# tutorial.graphqls&lt;/span&gt;
extend &lt;span class="nb"&gt;type &lt;/span&gt;Query &lt;span class="o"&gt;{&lt;/span&gt;
    findAllTutorials: &lt;span class="o"&gt;[&lt;/span&gt;Tutorial]!
    countTutorials: Long!
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;Query&lt;/code&gt; class implements &lt;code&gt;GraphQLQueryResolver&lt;/code&gt;. We don't want to use &lt;code&gt;GraphQLLong&lt;/code&gt; for &lt;code&gt;countAuthors&lt;/code&gt; and &lt;code&gt;countTutorials&lt;/code&gt; return type, so we alias it by using &lt;code&gt;newAliasedScalar("Long")&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;resolver/Query.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.graphql.resolver&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.beans.factory.annotation.Autowired&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.stereotype.Component&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;com.bezkoder.spring.graphql.model.Author&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;com.bezkoder.spring.graphql.model.Tutorial&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;com.bezkoder.spring.graphql.repository.AuthorRepository&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;com.bezkoder.spring.graphql.repository.TutorialRepository&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;graphql.kickstart.tools.GraphQLQueryResolver&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;graphql.scalars.ExtendedScalars&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;graphql.schema.GraphQLScalarType&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Component&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;Query&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;GraphQLQueryResolver&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;AuthorRepository&lt;/span&gt; &lt;span class="n"&gt;authorRepository&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;TutorialRepository&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;GraphQLScalarType&lt;/span&gt; &lt;span class="n"&gt;longScalar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ExtendedScalars&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newAliasedScalar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Long"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;aliasedScalar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ExtendedScalars&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GraphQLLong&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="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Query&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AuthorRepository&lt;/span&gt; &lt;span class="n"&gt;authorRepository&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TutorialRepository&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&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;authorRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;authorRepository&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;tutorialRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;;&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;Iterable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findAllAuthors&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;authorRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findAll&lt;/span&gt;&lt;span class="o"&gt;();&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;Iterable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findAllTutorials&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;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findAll&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="nf"&gt;countAuthors&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;authorRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="nf"&gt;countTutorials&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;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;count&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;h3&gt;Implement GraphQL Root Mutation Resolver&lt;/h3&gt;

&lt;p&gt;Mutation class will implement &lt;code&gt;GraphQLMutationResolver&lt;/code&gt;.&lt;br&gt;
Just like Query Resolver, every field in the schema mutation query should have a method in the Mutation Resolver class with the same name.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;resolver/Mutation.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.graphql.resolver&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.beans.factory.annotation.Autowired&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.stereotype.Component&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;com.bezkoder.spring.graphql.model.Author&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;com.bezkoder.spring.graphql.model.Tutorial&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;com.bezkoder.spring.graphql.repository.AuthorRepository&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;com.bezkoder.spring.graphql.repository.TutorialRepository&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;graphql.kickstart.tools.GraphQLMutationResolver&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;jakarta.persistence.EntityNotFoundException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Component&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;Mutation&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;GraphQLMutationResolver&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;AuthorRepository&lt;/span&gt; &lt;span class="n"&gt;authorRepository&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;TutorialRepository&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Mutation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AuthorRepository&lt;/span&gt; &lt;span class="n"&gt;authorRepository&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TutorialRepository&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&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;authorRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;authorRepository&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;tutorialRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;;&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;Author&lt;/span&gt; &lt;span class="nf"&gt;createAuthor&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;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Author&lt;/span&gt; &lt;span class="n"&gt;author&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;Author&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setName&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="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;authorRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;;&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;Tutorial&lt;/span&gt; &lt;span class="nf"&gt;createTutorial&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;title&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;description&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;authorId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAuthor&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;Author&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authorId&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTitle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDescription&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="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&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;tutorial&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;deleteTutorial&lt;/span&gt;&lt;span class="o"&gt;(&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="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&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;Tutorial&lt;/span&gt; &lt;span class="nf"&gt;updateTutorial&lt;/span&gt;&lt;span class="o"&gt;(&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="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&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;description&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;EntityNotFoundException&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;optTutorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optTutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isPresent&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;optTutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;if&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="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTitle&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="k"&gt;if&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="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDescription&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="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&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;tutorial&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;EntityNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not found Tutorial to update!"&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;h3&gt;Implement GraphQL Field Resolver&lt;/h3&gt;

&lt;p&gt;For complex fields like &lt;code&gt;author&lt;/code&gt; in &lt;code&gt;Tutorial&lt;/code&gt;, we have to resolve the value of those fields.&lt;br&gt;
&lt;code&gt;TutorialResolver&lt;/code&gt; implements &lt;code&gt;GraphQLResolver&lt;/code&gt; interface and has &lt;code&gt;getAuthor()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;resolver/TutorialResolver.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.graphql.resolver&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.beans.factory.annotation.Autowired&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.stereotype.Component&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;com.bezkoder.spring.graphql.model.Author&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;com.bezkoder.spring.graphql.model.Tutorial&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;com.bezkoder.spring.graphql.repository.AuthorRepository&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;graphql.kickstart.tools.GraphQLResolver&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Component&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;TutorialResolver&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;GraphQLResolver&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;AuthorRepository&lt;/span&gt; &lt;span class="n"&gt;authorRepository&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;TutorialResolver&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AuthorRepository&lt;/span&gt; &lt;span class="n"&gt;authorRepository&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;authorRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;authorRepository&lt;/span&gt;&lt;span class="o"&gt;;&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;Author&lt;/span&gt; &lt;span class="nf"&gt;getAuthor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&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;authorRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAuthor&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;If the client want to get a &lt;code&gt;Tutorial&lt;/code&gt; without &lt;code&gt;author&lt;/code&gt; field, the GraphQL Server will never do the work to retrieve it. So the &lt;code&gt;getAuthor()&lt;/code&gt; method above will never be executed.&lt;/p&gt;

&lt;h2&gt;Run &amp;amp; Check result&lt;/h2&gt;

&lt;p&gt;Run Spring Boot application with command: &lt;code&gt;mvn spring-boot:run&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Tables will be automatically generated in Database.&lt;br&gt;
If you check H2 database (by open browser with url: &lt;code&gt;&lt;a href="http://localhost:8080/h2-ui/"&gt;http://localhost:8080/h2-ui/&lt;/a&gt;&lt;/code&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z8A7Nkg---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/974u9zcnchjywm821i9z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z8A7Nkg---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/974u9zcnchjywm821i9z.png" alt="spring-boot-graphql-example-database" width="450" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on Connect button, and you can see them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1W2MPRuP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wdu1wb5ea3160y3n6gsy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1W2MPRuP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wdu1wb5ea3160y3n6gsy.png" alt="spring-boot-graphql-example-h2-database" width="180" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For checking result, you can use &lt;strong&gt;Postman&lt;/strong&gt; to make HTTP POST request to &lt;code&gt;&lt;a href="http://localhost:8080/apis/graphql"&gt;http://localhost:8080/apis/graphql&lt;/a&gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MR4vIE9b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38tpfgg1t7th70d1ifrd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MR4vIE9b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/38tpfgg1t7th70d1ifrd.png" alt="spring-boot-graphql-example" width="420" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span id="Conclusion"&gt;Conclusion&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;As an alternative approach to REST APIs, GraphQL minimize complexity between client &amp;amp; server.&lt;/p&gt;

&lt;p&gt;Today we've learned how to use Spring Boot GraphQL Starter and the GraphQL Java Tools to build GraphQL Apis. Our Spring Boot project also can communicate with H2 database using Spring Data JPA.&lt;/p&gt;

&lt;p&gt;Happy learning! See you again.&lt;/p&gt;

&lt;h2&gt;&lt;span id="Further_Reading"&gt;Further Reading&lt;/span&gt;&lt;/h2&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://graphql.org/learn/"&gt;GraphQL documentation&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://www.graphql-java.com/tutorials/getting-started-with-spring-boot/"&gt;https://www.graphql-java.com/tutorials/getting-started-with-spring-boot/&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://github.com/graphql-java/graphql-java"&gt;graphql-java Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Source Code&lt;/h2&gt;

&lt;p&gt;You can find the complete source code for this tutorial on &lt;a href="https://github.com/bezkoder/spring-boot-graphql-example"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Other databases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-graphql-mysql-jpa/"&gt;Spring Boot + GraphQL + MySQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-graphql-postgresql/"&gt;Spring Boot + GraphQL + PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-graphql-mongodb-example-graphql-java/"&gt;Spring Boot + GraphQL + MongoDB example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security: &lt;a href="https://www.bezkoder.com/spring-boot-security-login-jwt/"&gt;Spring Boot Security: Login and Registration example with JWT&lt;/a&gt;&lt;br&gt;
Unit Test: &lt;a href="https://www.bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/"&gt;@DataJpaTest example for Spring Data Repository&lt;/a&gt;&lt;br&gt;
Documentation: &lt;a href="https://www.bezkoder.com/spring-boot-swagger-3/"&gt;Spring Boot + Swagger 3 example (with OpenAPI 3)&lt;/a&gt;&lt;br&gt;
Caching: &lt;a href="https://www.bezkoder.com/spring-boot-redis-cache-example/"&gt;Spring Boot Redis Cache example&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>springboot</category>
      <category>graphql</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>Docker Compose: MongoDB and Spring Boot example</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Sat, 04 Nov 2023 02:27:51 +0000</pubDate>
      <link>https://forem.com/tienbku/docker-compose-mongodb-and-spring-boot-example-4808</link>
      <guid>https://forem.com/tienbku/docker-compose-mongodb-and-spring-boot-example-4808</guid>
      <description>&lt;p&gt;&lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; provides lightweight containers to run services in isolation from our infrastructure so we can deliver software quickly. In this tutorial, I will show you how to dockerize Spring Boot and MongoDB example using &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker Compose&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Related Posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-mongodb-crud/" rel="noopener noreferrer"&gt;Spring Boot and MongoDB CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-mongodb-reactive/" rel="noopener noreferrer"&gt;Spring Boot Reactive + MongoDB example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-jwt-auth-mongodb/" rel="noopener noreferrer"&gt;Spring Boot, Spring Security, MongoDB: JWT Authentication example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Documentation: &lt;a href="https://www.bezkoder.com/spring-boot-swagger-3/" rel="noopener noreferrer"&gt;Spring Boot Swagger 3 example&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Caching: &lt;a href="https://www.bezkoder.com/spring-boot-redis-cache-example/" rel="noopener noreferrer"&gt;Spring Boot Redis Cache example&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Assume that we have a Spring Boot Application working with MongoDB database.&lt;br&gt;
The problem is to containerize a system that requires more than one Docker container:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Spring Boot for Rest API&lt;/li&gt;
    &lt;li&gt;MongoDB for database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker Compose helps us setup the system more easily and efficiently than with only Docker. We're gonna following these steps:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Create Spring Boot App working with MongoDB database.&lt;/li&gt;
    &lt;li&gt;Create Dockerfile for Spring Boot App.&lt;/li&gt;
    &lt;li&gt;Write Docker Compose configurations in YAML file.&lt;/li&gt;
    &lt;li&gt;Set Spring Boot Docker Compose Environment variables.&lt;/li&gt;
    &lt;li&gt;Run the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Directory Structure:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fos00s1zgyqa4xs5rhtza.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fos00s1zgyqa4xs5rhtza.png" alt="mongodb-docker-compose-spring-boot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Create Spring Boot App&lt;/h2&gt;

&lt;p&gt;You can read and get Github source code from one of following tutorials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-mongodb-crud/" rel="noopener noreferrer"&gt;Spring Boot and MongoDB CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-mongodb-reactive/" rel="noopener noreferrer"&gt;Spring Boot Reactive + MongoDB example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-jwt-auth-mongodb/" rel="noopener noreferrer"&gt;Spring Boot, Spring Security, MongoDB: JWT Authentication example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the code base above, we put the Spring Boot project in &lt;strong&gt;bezkoder-app&lt;/strong&gt; folder without the need of &lt;strong&gt;resources&lt;/strong&gt;/&lt;em&gt;application.properties&lt;/em&gt;. It is because Environment variables will be exported to &lt;em&gt;.env&lt;/em&gt; file.&lt;/p&gt;

&lt;h2&gt;Create Dockerfile for Spring Boot App&lt;/h2&gt;

&lt;p&gt;Dockerfile defines a list of commands that Docker uses for setting up the Spring Boot application environment. So we put the file in &lt;strong&gt;bezkoder-app&lt;/strong&gt; folder.&lt;/p&gt;

&lt;p&gt;Because we will use Docker Compose, we won't define all the configuration commands in this Dockerfile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bezkoder-app&lt;/strong&gt;/&lt;em&gt;Dockerfile&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# FROM maven:3.8.2-jdk-8 # for Java 8
&lt;/span&gt;&lt;span class="err"&gt;FROM&lt;/span&gt; &lt;span class="py"&gt;maven&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;3.8.5-openjdk-17&lt;/span&gt;

&lt;span class="err"&gt;WORKDIR&lt;/span&gt; &lt;span class="err"&gt;/bezkoder-app&lt;/span&gt;
&lt;span class="err"&gt;COPY&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;RUN&lt;/span&gt; &lt;span class="err"&gt;mvn&lt;/span&gt; &lt;span class="err"&gt;clean&lt;/span&gt; &lt;span class="err"&gt;install&lt;/span&gt;

&lt;span class="err"&gt;CMD&lt;/span&gt; &lt;span class="err"&gt;mvn&lt;/span&gt; &lt;span class="py"&gt;spring-boot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain some points:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;FROM&lt;/code&gt;: install the image of the Maven - JDK version.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;WORKDIR&lt;/code&gt;: path of the working directory.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;COPY&lt;/code&gt;: copy all the files inside the project directory to the container.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;RUN&lt;/code&gt;: execute a command-line inside the container: &lt;code&gt;mvn clean install&lt;/code&gt; to install the dependencies in &lt;em&gt;pom.xml&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;CMD&lt;/code&gt;: run script &lt;code&gt;mvn spring-boot:run&lt;/code&gt; after the image is built.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Write Docker Compose configurations&lt;/h2&gt;

&lt;p&gt;On the root of the project directory, we're gonna create the &lt;em&gt;docker-compose.yml&lt;/em&gt; file. Follow &lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/" rel="noopener noreferrer"&gt;version 3&lt;/a&gt; syntax defined by Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"3.8"&lt;/span&gt;

&lt;span class="py"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="py"&gt;mongo_db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:5.0.2&lt;/span&gt;
    &lt;span class="py"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="py"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.env&lt;/span&gt;
    &lt;span class="py"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;MONGO_INITDB_ROOT_USERNAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_USER&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;MONGO_INITDB_ROOT_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_PASSWORD&lt;/span&gt;
    &lt;span class="py"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;MONGODB_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;/data/db&lt;/span&gt;
  &lt;span class="py"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;mongo_db&lt;/span&gt;
    &lt;span class="py"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./bezkoder-app&lt;/span&gt;
    &lt;span class="py"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;on-failure&lt;/span&gt;
    &lt;span class="py"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.env&lt;/span&gt;
    &lt;span class="py"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;SPRING_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;$SPRING_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="py"&gt;SPRING_APPLICATION_JSON&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'{&lt;/span&gt;
          &lt;span class="err"&gt;"spring.data.mongodb.uri"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="py"&gt;mongodb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;//$MONGODB_USER:$MONGODB_PASSWORD@mongo_db:$MONGODB_DOCKER_PORT/$MONGODB_DATABASE?authSource=admin"&lt;/span&gt;
        &lt;span class="err"&gt;}'&lt;/span&gt;
    &lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;.m2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;/root/.m2&lt;/span&gt;
    &lt;span class="py"&gt;stdin_open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
    &lt;span class="py"&gt;tty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="py"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;mongo_db&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;image&lt;/code&gt;: official Docker image&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;restart&lt;/code&gt;: configure the &lt;a href="https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy" rel="noopener noreferrer"&gt;restart policy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;env_file&lt;/code&gt;: specify our &lt;em&gt;.env&lt;/em&gt; path that we will create later&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment&lt;/code&gt;: provide setting using environment variables&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ports&lt;/code&gt;: specify ports will be used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;volumes&lt;/code&gt;: map volume folders&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#depends_on" rel="noopener noreferrer"&gt;depends_on&lt;/a&gt;&lt;/code&gt;: dependency order, &lt;strong&gt;mongo_db&lt;/strong&gt; is started before &lt;strong&gt;app&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt;: configuration options that are applied at build time that we defined in the &lt;em&gt;Dockerfile&lt;/em&gt; with relative path&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment&lt;/code&gt;: environmental variables that Spring Boot application uses&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stdin_open&lt;/code&gt; and &lt;code&gt;tty&lt;/code&gt;: keep open the terminal after building container&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;You should note that the host port (&lt;code&gt;LOCAL_PORT&lt;/code&gt;) and the container port (&lt;code&gt;DOCKER_PORT&lt;/code&gt;) is different. Networked service-to-service communication uses the container port, and the outside uses the host port.&lt;/p&gt;

&lt;h2&gt;Docker Compose Environment variables&lt;/h2&gt;

&lt;p&gt;In the service configuration, we used environmental variables defined inside the &lt;em&gt;.env&lt;/em&gt; file. Now we start writing it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;.env&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;MONGODB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;123456&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_DATABASE&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;bezkoder_db&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;7017&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;27017&lt;/span&gt;

&lt;span class="py"&gt;SPRING_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;6868&lt;/span&gt;
&lt;span class="py"&gt;SPRING_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;Run the Spring Boot microservice with Docker Compose&lt;/h2&gt;

&lt;p&gt;We can easily run the whole with only a single command:&lt;br&gt;
&lt;code&gt;docker compose up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Docker will pull the MongoDB and Maven images (if our machine does not have it before).&lt;/p&gt;

&lt;p&gt;The services can be run on the background with command:&lt;br&gt;
&lt;code&gt;docker compose up -d&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;+] Running 11/11
 ✔ mongodb 10 layers &lt;span class="o"&gt;[&lt;/span&gt;⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                    
   ✔ 35807b77a593 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                     
   ✔ 664b0ebdcc07 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                    
   ✔ d598f4d3c081 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                      
   ✔ 291455135b00 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                              
   ✔ b46409342f13 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                      
   ✔ ff2b9c6e6f3a Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                              
   ✔ 149f6335fc27 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                    
   ✔ baeb6f3bec76 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                        
   ✔ 8617caab2de5 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                       
   ✔ 067d70de7828 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                             
&lt;span class="o"&gt;[&lt;/span&gt;+] Building 87.9s &lt;span class="o"&gt;(&lt;/span&gt;9/9&lt;span class="o"&gt;)&lt;/span&gt; FINISHED                                                                                                                                                                               docker:default
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load .dockerignore                                                                                                                                                         
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring context: 2B                                                                                                                                                                        
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load build definition from Dockerfile                                                                                                                                                
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring dockerfile: 238B                                                                                                                                                        
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load metadata &lt;span class="k"&gt;for &lt;/span&gt;docker.io/library/maven:3.8.5-openjdk-17                                                                                                                            
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 1/4] FROM docker.io/library/maven:3.8.5-openjdk-17@sha256:3a9c30b3af6278a8ae0007d3a3bf00fff80ec3ed7ae4eb9bfa1772853101549b                                                                     
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load build context                                                                                                                                                                            
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring context: 31.57kB                                                                                                                                                             
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; CACHED &lt;span class="o"&gt;[&lt;/span&gt;app 2/4] WORKDIR /bezkoder-app                                                                                                                                                           
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 3/4] COPY &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;                                                                                                                                                                         
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 4/4] RUN mvn clean &lt;span class="nb"&gt;install&lt;/span&gt;                                                                                                                                                                  
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app] exporting to image                                                                                                                                                                                 
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; exporting layers                                                                                                                                                                              
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; writing image sha256:c2f10209e87c064f039545b2e6812c9c15a405120d595d7e1ff888bd3cce267f                                                                                                            
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; naming to docker.io/library/spring-boot-mongodb-app                                                                                                                                          
&lt;span class="o"&gt;[&lt;/span&gt;+] Running 4/4                                                                                                                                                                                                                
 ✔ Network spring-boot-mongodb_default      Created                                                                                                                                            
 ✔ Volume &lt;span class="s2"&gt;"spring-boot-mongodb_db"&lt;/span&gt;          Created                                                                                                                                                     
 ✔ Container spring-boot-mongodb-mongodb-1  Started                                                                                                                                                  
 ✔ Container spring-boot-mongodb-app-1      Started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can check the current working containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker ps
CONTAINER ID   IMAGE                     COMMAND                  CREATED         STATUS         PORTS                                         NAMES
88af893b2a53   spring-boot-mongodb-app   &lt;span class="s2"&gt;"/usr/local/bin/mvn-…"&lt;/span&gt;   2 minutes ago   Up 2 minutes   0.0.0.0:6868-&amp;gt;8080/tcp, :::6868-&amp;gt;8080/tcp     spring-boot-mongodb-app-1
4ef8f9734878   mongo:5.0.2               &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   2 minutes ago   Up 2 minutes   0.0.0.0:7017-&amp;gt;27017/tcp, :::7017-&amp;gt;27017/tcp   spring-boot-mongodb-mongodb-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And Docker images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker images
REPOSITORY                 TAG       IMAGE ID       CREATED         SIZE
spring-boot-mongodb-app    latest    c2f10209e87c   2 minutes ago   912MB
mongo                      5.0.2     0bcbeb494bed   2 years ago     684MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Send a HTTP request to the Spring Boot - MongoDB system:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdt914lpbpq125a087dbd.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdt914lpbpq125a087dbd.png" alt="mongodb-docker-compose-spring-boot-api"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check MongoDB Database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-ti&lt;/span&gt; spring-boot-mongodb-mongodb-1 /bin/bash
root@2d71784ae3a9:/# mongo &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; 123456 &lt;span class="nt"&gt;--authenticationDatabase&lt;/span&gt; admin
MongoDB shell version v5.0.2
connecting to: mongodb://127.0.0.1:27017/?authSource&lt;span class="o"&gt;=&lt;/span&gt;admin&amp;amp;compressors&lt;span class="o"&gt;=&lt;/span&gt;disabled&amp;amp;gssapiServiceName&lt;span class="o"&gt;=&lt;/span&gt;mongodb
Implicit session: session &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"id"&lt;/span&gt; : UUID&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"742022a6-49ed-42dd-9a53-0fd156f234ec"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
MongoDB server version: 5.0.2

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; show dbs
admin        0.000GB
bezkoder_db  0.000GB
config       0.000GB
&lt;span class="nb"&gt;local        &lt;/span&gt;0.000GB
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; use bezkoder_db
switched to db bezkoder_db
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; show collections
tutorials
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.tutorials.find&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"_id"&lt;/span&gt; : ObjectId&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"6541dff55fa4083bdb3d0422"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="s2"&gt;"title"&lt;/span&gt; : &lt;span class="s2"&gt;"Docker Compose MongoDB Spring Boot"&lt;/span&gt;, &lt;span class="s2"&gt;"description"&lt;/span&gt; : &lt;span class="s2"&gt;"Tut#1 Description"&lt;/span&gt;, &lt;span class="s2"&gt;"published"&lt;/span&gt; : &lt;span class="nb"&gt;false&lt;/span&gt;, &lt;span class="s2"&gt;"_class"&lt;/span&gt; : &lt;span class="s2"&gt;"com.bezkoder.spring.data.mongodb.model.Tutorial"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;Stop the Application&lt;/h2&gt;

&lt;p&gt;Stopping all the running containers is also simple with a single command:&lt;br&gt;
&lt;code&gt;docker compose down&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose down
 ✔ Container spring-boot-mongodb-app-1       Removed
 ✔ Container spring-boot-mongodb-mongo_db-1  Removed
 ✔ Network spring-boot-mongodb_default       Removed    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to stop and remove all containers, networks, and all images used by any service in &lt;em&gt;docker-compose.yml&lt;/em&gt; file, use the command:&lt;br&gt;
&lt;code&gt;docker compose down --rmi all&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose down &lt;span class="nt"&gt;--rmi&lt;/span&gt; all
&lt;span class="o"&gt;[&lt;/span&gt;+] Running 5/5
 ✔ Container spring-boot-mongodb-app-1       Removed
 ✔ Container spring-boot-mongodb-mongo_db-1  Removed
 ✔ Image spring-boot-mongodb-app:latest      Removed
 ✔ Image mongo:5.0.2                         Removed
 ✔ Network spring-boot-mongodb_default       Removed     
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Today we've successfully created Docker Compose file for MongoDB and Spring Boot example. Now we can connect Spring Boot to MongoDB with Docker on a very simple way: &lt;em&gt;docker-compose.yml&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can apply this way to one of following project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-mongodb-crud/" rel="noopener noreferrer"&gt;Spring Boot and MongoDB CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-mongodb-reactive/" rel="noopener noreferrer"&gt;Spring Boot Reactive + MongoDB example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-jwt-auth-mongodb/" rel="noopener noreferrer"&gt;Spring Boot, Spring Security, MongoDB: JWT Authentication example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Learning! See you again.&lt;/p&gt;

&lt;h2&gt;Source Code&lt;/h2&gt;

&lt;p&gt;The source code for this tutorial can be found at &lt;a href="https://github.com/bezkoder/docker-compose-spring-boot-mongodb" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Documentation: &lt;a href="https://www.bezkoder.com/spring-boot-swagger-3/" rel="noopener noreferrer"&gt;Spring Boot + Swagger 3 example (with OpenAPI 3)&lt;/a&gt;&lt;br&gt;
Caching: &lt;a href="https://www.bezkoder.com/spring-boot-redis-cache-example/" rel="noopener noreferrer"&gt;Spring Boot Redis Cache example&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>webdev</category>
      <category>java</category>
      <category>devops</category>
    </item>
    <item>
      <title>Dockerize Nodejs and Postgres example</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Thu, 19 Oct 2023 02:35:36 +0000</pubDate>
      <link>https://forem.com/tienbku/dockerize-nodejs-and-postgres-example-4k2j</link>
      <guid>https://forem.com/tienbku/dockerize-nodejs-and-postgres-example-4k2j</guid>
      <description>&lt;p&gt;&lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; provides lightweight containers to run services in isolation from our infrastructure so we can deliver software quickly. In this tutorial, I will show you how to dockerize Nodejs Express and Postgres example using &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker Compose&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Related Posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-express-sequelize-postgresql/" rel="noopener noreferrer"&gt;Node.js Express &amp;amp; PostgreSQL Rest APIs example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-pagination-postgresql/" rel="noopener noreferrer"&gt;Node.js Express Pagination with PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/typescript-orm-postgres/" rel="noopener noreferrer"&gt;Node.js Typescript Rest API with Postgres example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-jwt-authentication-postgresql/" rel="noopener noreferrer"&gt;Node.js JWT Authentication &amp;amp; Authorization with PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-csv-postgresql/" rel="noopener noreferrer"&gt;Import CSV data into PostgreSQL using Node.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-export-postgresql-csv-file/" rel="noopener noreferrer"&gt;Export PostgreSQL data to CSV file using Node.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Dockerizing Node.js and Postgres Overview&lt;/h2&gt;

&lt;p&gt;Assume that we have a Nodejs Application working with Postgres database.&lt;br&gt;
The problem is to containerize a system that requires more than one Docker container:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Node.js Express for API&lt;/li&gt;
    &lt;li&gt;PostgreSQL for database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker Compose helps us setup the system more easily and efficiently than with only Docker. We're gonna following these steps:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Create Nodejs App working with Postgres database.&lt;/li&gt;
    &lt;li&gt;Create Dockerfile for Nodejs App.&lt;/li&gt;
    &lt;li&gt;Write Docker Compose configurations in YAML file.&lt;/li&gt;
    &lt;li&gt;Set Environment variables for Docker Compose&lt;/li&gt;
    &lt;li&gt;Run the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Directory Structure:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fdocker-compose-nodejs-postgres-example.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fdocker-compose-nodejs-postgres-example.png" alt="docker-compose-nodejs-postgres-example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Create Nodejs App&lt;/h2&gt;

&lt;p&gt;You can read and get Github source code from one of following tutorials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-express-sequelize-postgresql/" rel="noopener noreferrer"&gt;Node.js Express &amp;amp; PostgreSQL Rest APIs example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-pagination-postgresql/" rel="noopener noreferrer"&gt;Node.js Express Pagination with PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/typescript-orm-postgres/" rel="noopener noreferrer"&gt;Node.js Typescript Rest API with Postgres example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-jwt-authentication-postgresql/" rel="noopener noreferrer"&gt;Node.js JWT Authentication &amp;amp; Authorization with PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-csv-postgresql/" rel="noopener noreferrer"&gt;Import CSV data into PostgreSQL using Node.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-export-postgresql-csv-file/" rel="noopener noreferrer"&gt;Export PostgreSQL data to CSV file using Node.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the code base above, we put the Nodejs project in &lt;strong&gt;bezkoder-app&lt;/strong&gt; folder and modify some files to work with environment variables.&lt;/p&gt;

&lt;p&gt;Firstly, let's add &lt;code&gt;dotenv&lt;/code&gt; module into &lt;em&gt;package.json&lt;/em&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dotenv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^10.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="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;Next we import &lt;code&gt;dotenv&lt;/code&gt; in &lt;em&gt;server.js&lt;/em&gt; and use &lt;code&gt;process.env&lt;/code&gt; for setting port.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;..&lt;/span&gt;
&lt;span class="c1"&gt;// set port, listen for requests&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_DOCKER_PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is running on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Then we change modify database configuration and initialization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;app&lt;/strong&gt;/&lt;strong&gt;config&lt;/strong&gt;/&lt;em&gt;db.config.js&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;HOST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;dialect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgres&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;acquire&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;idle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;app&lt;/strong&gt;/&lt;strong&gt;models&lt;/strong&gt;/&lt;em&gt;index.js&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../config/db.config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Sequelize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sequelize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sequelize&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;Sequelize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dbConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PASSWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;dialect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dialect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;operatorsAliases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;acquire&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;acquire&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;idle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dbConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;idle&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We also need to make a &lt;em&gt;.env&lt;/em&gt; sample file that shows all necessary arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bezkoder-app&lt;/strong&gt;/&lt;em&gt;.env.sample&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;localhost&lt;/span&gt;
&lt;span class="py"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;span class="py"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;123456&lt;/span&gt;
&lt;span class="py"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;bezkoder_db&lt;/span&gt;
&lt;span class="py"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5432&lt;/span&gt;

&lt;span class="py"&gt;NODE_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;


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

&lt;/div&gt;

&lt;h2&gt;Create Dockerfile for Nodejs App&lt;/h2&gt;

&lt;p&gt;Dockerfile defines a list of commands that Docker uses for setting up the Node.js application environment. So we put the file in &lt;strong&gt;bezkoder-app&lt;/strong&gt; folder.&lt;/p&gt;

&lt;p&gt;Because we will use Docker Compose, we won't define all the configuration commands in this Dockerfile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bezkoder-app&lt;/strong&gt;/&lt;em&gt;Dockerfile&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="err"&gt;FROM&lt;/span&gt; &lt;span class="py"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;14&lt;/span&gt;

&lt;span class="err"&gt;WORKDIR&lt;/span&gt; &lt;span class="err"&gt;/bezkoder-app&lt;/span&gt;
&lt;span class="err"&gt;COPY&lt;/span&gt; &lt;span class="err"&gt;package.json&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;RUN&lt;/span&gt; &lt;span class="err"&gt;npm&lt;/span&gt; &lt;span class="err"&gt;install&lt;/span&gt;
&lt;span class="err"&gt;COPY&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;CMD&lt;/span&gt; &lt;span class="err"&gt;npm&lt;/span&gt; &lt;span class="err"&gt;start&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Let me explain some points:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;FROM&lt;/code&gt;: install the image of the Node.js version.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;WORKDIR&lt;/code&gt;: path of the working directory.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;COPY&lt;/code&gt;: copy &lt;em&gt;package.json&lt;/em&gt; file to the container, then the second one copies all the files inside the project directory.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;RUN&lt;/code&gt;: execute a command-line inside the container: &lt;code&gt;npm install&lt;/code&gt; to install the dependencies in &lt;em&gt;package.json&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;CMD&lt;/code&gt;: run script &lt;code&gt;npm start&lt;/code&gt; after the image is built.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Write Docker Compose configurations&lt;/h2&gt;

&lt;p&gt;Let's make Nodejs connect with PostgreSQL using Docker.&lt;/p&gt;

&lt;p&gt;On the root of the project directory, we're gonna create the &lt;em&gt;docker-compose.yml&lt;/em&gt; file. Follow &lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/" rel="noopener noreferrer"&gt;version 3&lt;/a&gt; syntax defined by Docker:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'3.8'&lt;/span&gt;

&lt;span class="py"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="s"&gt;postgresdb:&lt;/span&gt;
    &lt;span class="py"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;


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

&lt;/div&gt;

&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;version&lt;/code&gt;: Docker Compose file format version will be used.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;services&lt;/code&gt;: individual services in isolated containers. Our application has two services: &lt;code&gt;app&lt;/code&gt; (Nodejs) and &lt;code&gt;postgresdb&lt;/code&gt; (Postgres database).&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;&lt;a href="https://docs.docker.com/storage/volumes/" rel="noopener noreferrer"&gt;volumes&lt;/a&gt;&lt;/code&gt;: named volumes that keeps our data alive after restart.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's implement the details.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;docker-compose.yml&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'3.8'&lt;/span&gt;

&lt;span class="py"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="py"&gt;postgresdb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="py"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="py"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.env&lt;/span&gt;
    &lt;span class="py"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_USER&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_ROOT_PASSWORD&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_DATABASE&lt;/span&gt;
    &lt;span class="py"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;POSTGRESDB_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;/var/lib/postgres&lt;/span&gt;
  &lt;span class="py"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;postgresdb&lt;/span&gt;
    &lt;span class="py"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./bezkoder-app&lt;/span&gt;
    &lt;span class="py"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="py"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.env&lt;/span&gt;
    &lt;span class="py"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;NODE_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;$NODE_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgresdb&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_USER&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_ROOT_PASSWORD&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_DATABASE&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;stdin_open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
    &lt;span class="py"&gt;tty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
  &lt;span class="s"&gt;db:&lt;/span&gt;


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;postgresdb&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;image&lt;/code&gt;: official Docker image&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;restart&lt;/code&gt;: configure the &lt;a href="https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy" rel="noopener noreferrer"&gt;restart policy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;env_file&lt;/code&gt;: specify our &lt;em&gt;.env&lt;/em&gt; path that we will create later&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment&lt;/code&gt;: provide setting using environment variables&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ports&lt;/code&gt;: specify ports will be used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;volumes&lt;/code&gt;: map volume folders&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#depends_on" rel="noopener noreferrer"&gt;depends_on&lt;/a&gt;&lt;/code&gt;: dependency order, &lt;strong&gt;postgresdb&lt;/strong&gt; is started before &lt;strong&gt;app&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt;: configuration options that are applied at build time that we defined in the &lt;em&gt;Dockerfile&lt;/em&gt; with relative path&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment&lt;/code&gt;: environmental variables that Node application uses&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stdin_open&lt;/code&gt; and &lt;code&gt;tty&lt;/code&gt;: keep open the terminal after building container&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;You should note that the host port (&lt;code&gt;LOCAL_PORT&lt;/code&gt;) and the container port (&lt;code&gt;DOCKER_PORT&lt;/code&gt;) is different. Networked service-to-service communication uses the container port, and the outside uses the host port.&lt;/p&gt;

&lt;h2&gt;Docker Compose Environment variables with Postgres&lt;/h2&gt;

&lt;p&gt;In the service configuration, we used environmental variables defined inside the &lt;em&gt;.env&lt;/em&gt; file. Now we start writing it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;.env&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;POSTGRESDB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;span class="py"&gt;POSTGRESDB_ROOT_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;123456&lt;/span&gt;
&lt;span class="py"&gt;POSTGRESDB_DATABASE&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;bezkoder_db&lt;/span&gt;
&lt;span class="py"&gt;POSTGRESDB_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5433&lt;/span&gt;
&lt;span class="py"&gt;POSTGRESDB_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5432&lt;/span&gt;

&lt;span class="py"&gt;NODE_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;6868&lt;/span&gt;
&lt;span class="py"&gt;NODE_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;


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

&lt;/div&gt;

&lt;h2&gt;Run Nodejs Postgres with Docker Compose&lt;/h2&gt;

&lt;p&gt;We can easily run the whole with only a single command:&lt;br&gt;
&lt;code&gt;docker compose up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Docker will pull the PostgreSQL and Node.js images (if our machine does not have it before).&lt;/p&gt;

&lt;p&gt;The services can be run on the background with command:&lt;br&gt;
&lt;code&gt;docker compose up -d&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;+] Running 14/14
 ✔ postgresdb 13 layers &lt;span class="o"&gt;[&lt;/span&gt;⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                              
   ✔ a378f10b3218 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ 2ebc5690e391 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ 8fe57f734687 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ a2ddbb09cd9a Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                             
   ✔ 5a2499e87ab8 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                             
   ✔ a45f5c4adf1b Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                             
   ✔ 178017fd978e Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                             
   ✔ 428dff1cb77d Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                             
   ✔ 4667364adfc4 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                             
   ✔ 4eea1f5281a9 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                             
   ✔ 369467411787 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                             
   ✔ 51184495a2bc Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                             
   ✔ d3e246f01410 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                             
&lt;span class="o"&gt;[&lt;/span&gt;+] Building 77.4s &lt;span class="o"&gt;(&lt;/span&gt;10/10&lt;span class="o"&gt;)&lt;/span&gt; FINISHED                                                                                                                                                                                docker:default
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load build definition from Dockerfile                                                                                                                                                                     
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring dockerfile: 179B                                                                                                                                                                                         
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load .dockerignore                                                                                                                                                                                        
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring context: 2B                                                                                                                                                                                              
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load metadata &lt;span class="k"&gt;for &lt;/span&gt;docker.io/library/node:14                                                                                                                                                              
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 1/5] FROM docker.io/library/node:14@sha256:a158d3b9b4e3fa813fa6c8c590b8f0a860e015ad4e59bbce5744d2f6fd8461aa                                                                                                        
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; resolve docker.io/library/node:14@sha256:a158d3b9b4e3fa813fa6c8c590b8f0a860e015ad4e59bbce5744d2f6fd8461aa                                                                                                             
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; sha256:3d2201bd995cccf12851a50820de03d34a17011dcbb9ac9fdf3a50c952cbb131 10.00MB / 10.00MB                                                                                                                             
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; sha256:2cafa3fbb0b6529ee4726b4f599ec27ee557ea3dea7019182323b3779959927f 2.21kB / 2.21kB                                                                                                                               ...
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; extracting sha256:0c8cc2f24a4dcb64e602e086fc9446b0a541e8acd9ad72d2e90df3ba22f158b3                                                                                                                                    
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; extracting sha256:0d27a8e861329007574c6766fba946d48e20d2c8e964e873de352603f22c4ceb                                                                                                                                    
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load build context                                                                                                                                                                                        
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring context: 17.47kB                                                                                                                                                                                         
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 2/5] WORKDIR /bezkoder-app                                                                                                                                                                                          
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 3/5] COPY package.json &lt;span class="nb"&gt;.&lt;/span&gt;                                                                                                                                                                                            
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 4/5] RUN npm &lt;span class="nb"&gt;install&lt;/span&gt;                                                                                                                                                                                               
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 5/5] COPY &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;                                                                                                                                                                                                       
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app] exporting to image                                                                                                                                                                                                 
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; exporting layers                                                                                                                                                                                                      
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; writing image sha256:4571b91ea16b395b5e00833cc5770695f07250627ebceee1d5125660b93abd00                                                                                                                                 
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; naming to docker.io/library/node-postgres-app                                                                                                                                                                         
&lt;span class="o"&gt;[&lt;/span&gt;+] Running 4/4
 ✔ Network node-postgres_default         Created                                                                                                                                                                             
 ✔ Volume &lt;span class="s2"&gt;"node-postgres_db"&lt;/span&gt;             Created                                                                                                                                                                             
 ✔ Container node-postgres-postgresdb-1  Started                                                                                                                                                                             
 ✔ Container node-postgres-app-1         Started     


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

&lt;/div&gt;

&lt;p&gt;Now you can check the current working containers:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker ps
CONTAINER ID   IMAGE               COMMAND                  CREATED         STATUS         PORTS                                       NAMES
4b781fa774f6   node-postgres-app   &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   2 minutes ago   Up 2 minutes   0.0.0.0:6868-&amp;gt;8080/tcp, :::6868-&amp;gt;8080/tcp   node-postgres-app-1
d268e1be7e80   postgres            &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   2 minutes ago   Up 2 minutes   0.0.0.0:5433-&amp;gt;5432/tcp, :::5433-&amp;gt;5432/tcp   node-postgres-postgresdb-1


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

&lt;/div&gt;

&lt;p&gt;And Docker images:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
node-postgres-app     latest    4571b91ea16b   3 minutes ago   943MB
postgres              latest    f7d9a0d4223b   4 weeks ago     417MB


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

&lt;/div&gt;

&lt;p&gt;Send a HTTP request to the Nodejs - Postgres application:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fdocker-compose-nodejs-postgres.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fdocker-compose-nodejs-postgres.png" alt="docker-compose-nodejs-postgres"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check Postgres Database:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-ti&lt;/span&gt; node-postgres-postgresdb-1 /bin/bash
root@eba893d13a10:/# psql bezkoder_db postgres
psql &lt;span class="o"&gt;(&lt;/span&gt;16.0 &lt;span class="o"&gt;(&lt;/span&gt;Debian 16.0-1.pgdg120+1&lt;span class="o"&gt;))&lt;/span&gt;
Type &lt;span class="s2"&gt;"help"&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;help.

&lt;span class="nv"&gt;bezkoder_db&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="c"&gt;# SELECT * FROM tutorials;&lt;/span&gt;
 &lt;span class="nb"&gt;id&lt;/span&gt; |          title          |    description    | published |         createdAt          |         updatedAt          
&lt;span class="nt"&gt;----&lt;/span&gt;+-------------------------+-------------------+-----------+----------------------------+----------------------------
  1 | Docker Postgres Express | Tut#1 Description | f         | 2023-10-14 10:13:17.432+00 | 2023-10-14 10:13:17.432+00
&lt;span class="o"&gt;(&lt;/span&gt;1 row&lt;span class="o"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;h2&gt;Stop the Application&lt;/h2&gt;

&lt;p&gt;Stopping all the running containers is also simple with a single command:&lt;br&gt;
&lt;code&gt;docker compose down&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose down
 ✔ Container node-postgres-app-1         Removed                                                                                                                                                                  
 ✔ Container node-postgres-postgresdb-1  Removed                                                                                                                                                                   
 ✔ Network node-postgres_default         Removed     


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

&lt;/div&gt;

&lt;p&gt;If you need to stop and remove all containers, networks, and all images used by any service in &lt;em&gt;docker-compose.yml&lt;/em&gt; file, use the command:&lt;br&gt;
&lt;code&gt;docker compose down --rmi all&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;Today we've successfully created Docker Compose file for Postgres and Nodejs application. Now we can deploy Nodejs Express and Postgres with Docker on a very simple way: &lt;em&gt;docker-compose.yml&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can apply this way to one of following project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-express-sequelize-postgresql/" rel="noopener noreferrer"&gt;Node.js Express &amp;amp; PostgreSQL Rest APIs example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-pagination-postgresql/" rel="noopener noreferrer"&gt;Node.js Express Pagination with PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/typescript-orm-postgres/" rel="noopener noreferrer"&gt;Node.js Typescript Rest API with Postgres example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-jwt-authentication-postgresql/" rel="noopener noreferrer"&gt;Node.js JWT Authentication &amp;amp; Authorization with PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Learning! See you again.&lt;/p&gt;

&lt;h2&gt;Source Code&lt;/h2&gt;

&lt;p&gt;The source code for this tutorial can be found at &lt;a href="https://github.com/bezkoder/docker-compose-nodejs-postgres" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to add Comments for each Tutorial. It is the One-to-Many Relationship there is a tutorial:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/sequelize-associate-one-to-many/" rel="noopener noreferrer"&gt;Node.js Sequelize Associations: One-to-Many example&lt;/a&gt;&lt;br&gt;
(the tutorial uses MySQL but you can easily change the configuration for PostgreSQL)&lt;/p&gt;

&lt;p&gt;Or you can add Tags for each Tutorial and add Tutorials to Tag (Many-to-Many Relationship):&lt;br&gt;
&lt;a href="https://www.bezkoder.com/sequelize-associate-many-to-many/" rel="noopener noreferrer"&gt;Node.js Sequelize Associations: Many-to-Many example&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>devops</category>
      <category>webdev</category>
      <category>docker</category>
    </item>
    <item>
      <title>Global Exception Handler in Spring Boot</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Wed, 11 Oct 2023 03:23:00 +0000</pubDate>
      <link>https://forem.com/tienbku/global-exception-handler-in-spring-boot-3mbp</link>
      <guid>https://forem.com/tienbku/global-exception-handler-in-spring-boot-3mbp</guid>
      <description>&lt;p&gt;In this tutorial, we're gonna look at an Spring Boot example that uses &lt;code&gt;@ControllerAdvice&lt;/code&gt; and &lt;code&gt;@ExceptionHandler&lt;/code&gt; for global exception handling in Spring Boot.&lt;/p&gt;

&lt;p&gt;Related Posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-restcontrolleradvice/" rel="noopener noreferrer"&gt;@RestControllerAdvice example in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-jpa-crud-rest-api/" rel="noopener noreferrer"&gt;Spring Boot, Spring Data JPA – Rest CRUD API example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-pagination-filter-jpa-pageable/" rel="noopener noreferrer"&gt;Spring Boot Pagination &amp;amp; Filter example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-data-sort-multiple-columns/" rel="noopener noreferrer"&gt;Spring Boot Sort/Order by multiple Columns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Documentation: &lt;a href="https://www.bezkoder.com/spring-boot-swagger-3/" rel="noopener noreferrer"&gt;Spring Boot Swagger 3 example&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Caching: &lt;a href="https://www.bezkoder.com/spring-boot-redis-cache-example/" rel="noopener noreferrer"&gt;Spring Boot Redis Cache example&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Validation: &lt;a href="https://www.bezkoder.com/spring-boot-validate-request-body/" rel="noopener noreferrer"&gt;Validate Request Body in Spring Boot&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More Practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-file-upload/" rel="noopener noreferrer"&gt;Spring Boot Multipart File upload example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-jwt-authentication/" rel="noopener noreferrer"&gt;Spring Boot Token based Authentication with Spring Security &amp;amp; JWT&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unit Test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for JPA Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-webmvctest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for Rest Controller&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Exception handling Problem&lt;/h2&gt;

&lt;p&gt;We've created Rest Controller for CRUD Operations and finder method.&lt;br&gt;
Let look at the code:&lt;br&gt;
(step by step to build the Rest APIs is in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-jpa-h2-example/" rel="noopener noreferrer"&gt;Spring Boot Data JPA + H2 CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-jpa-crud-rest-api/" rel="noopener noreferrer"&gt;Spring Boot Data JPA + MySQL CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-postgresql-example/" rel="noopener noreferrer"&gt;Spring Boot Data JPA + PostgreSQL CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-sql-server/" rel="noopener noreferrer"&gt;Spring Boot Data JPA + SQL Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-hibernate-oracle/" rel="noopener noreferrer"&gt;Spring Boot Data JPA + Oracle example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-mongodb-crud/" rel="noopener noreferrer"&gt;Spring Boot MongoDB CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://bezkoder.com/spring-boot-cassandra-crud/" rel="noopener noreferrer"&gt;Spring Boot Cassandra CRUD example&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&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;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TutorialController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="nc"&gt;TutorialRepository&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&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;"/tutorials"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getAllTutorials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestParam&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;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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="n"&gt;tutorials&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="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&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="kc"&gt;null&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;INTERNAL_SERVER_ERROR&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;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tutorials/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getTutorialById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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="kt"&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="o"&gt;{&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tutorialData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorialData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isPresent&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="n"&gt;tutorialData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&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="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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_FOUND&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;@PutMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tutorials/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;updateTutorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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="kt"&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;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;)&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tutorialData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorialData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isPresent&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="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="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_tutorial&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="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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_FOUND&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="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;"/tutorials/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;deleteTutorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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="kt"&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="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&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;NO_CONTENT&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&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;INTERNAL_SERVER_ERROR&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;@DeleteMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tutorials"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;deleteAllTutorials&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// try and catch&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;"/tutorials/published"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByPublished&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// try and catch&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;You can see that we use try/catch many times for similar exception (&lt;strong&gt;INTERNAL_SERVER_ERROR&lt;/strong&gt;), and there are also many cases that return &lt;strong&gt;NOT_FOUND&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Is there any way to keep them simple, any way to attach the error response message smartly and flexibility?&lt;br&gt;
Let's solve the problem now.&lt;/p&gt;

&lt;h2&gt;Exception Handler with Controller Advice in Spring&lt;/h2&gt;

&lt;p&gt;Spring supports exception handling by a global Exception Handler (&lt;a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html" rel="noopener noreferrer"&gt;@ExceptionHandler&lt;/a&gt;) with Controller Advice (&lt;a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html" rel="noopener noreferrer"&gt;@ControllerAdvice&lt;/a&gt;). This enables a mechanism that makes &lt;code&gt;ResponseEntity&lt;/code&gt; work with the type safety and flexibility of &lt;code&gt;@ExceptionHandler&lt;/code&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;@ControllerAdvice&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;ControllerExceptionHandler&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@ExceptionHandler&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="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CertainException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ErrorMessage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;resourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;WebRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ErrorMessage&lt;/span&gt; &lt;span class="n"&gt;message&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;ErrorMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&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="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;&lt;/span&gt;&lt;span class="nc"&gt;ErrorMessage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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;NOT_FOUND&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;The &lt;code&gt;@ControllerAdvice&lt;/code&gt; annotation is specialization of &lt;code&gt;@Component&lt;/code&gt; annotation so that it is auto-detected via classpath scanning. A Controller Advice is a kind of interceptor that surrounds the logic in our Controllers and allows us to apply some common logic to them. &lt;/p&gt;

&lt;p&gt;Its methods (annotated with &lt;code&gt;@ExceptionHandler&lt;/code&gt;) are shared globally across multiple &lt;code&gt;@Controller&lt;/code&gt; components to capture exceptions and translate them to HTTP responses. The &lt;code&gt;@ExceptionHandler&lt;/code&gt; annotation indicates which type of Exception we want to handle. The &lt;code&gt;exception&lt;/code&gt; instance and the &lt;code&gt;request&lt;/code&gt; will be injected via method arguments.&lt;/p&gt;

&lt;p&gt;By using two annotations together, we can:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;control the body of the response along with status code&lt;/li&gt;
    &lt;li&gt;handle several exceptions in the same method&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;@ResponseStatus&lt;/h2&gt;

&lt;p&gt;In the example above, we use &lt;code&gt;@ControllerAdvice&lt;/code&gt; for REST web services and return &lt;code&gt;ResponseEntity&lt;/code&gt; object additionally.&lt;/p&gt;

&lt;p&gt;Spring also provides &lt;code&gt;@ResponseBody&lt;/code&gt; annotation which tells a controller that the object returned is automatically serialized into JSON and passed it to the &lt;code&gt;HttpResponse&lt;/code&gt; object. This way does not require &lt;code&gt;ResponseEntity&lt;/code&gt; but you need to use &lt;code&gt;@ResponseStatus&lt;/code&gt; to set the HTTP status code for that exception.&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;@ControllerAdvice&lt;/span&gt;
&lt;span class="nd"&gt;@ResponseBody&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;ControllerExceptionHandler&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@ExceptionHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;value&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;NOT_FOUND&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;ErrorMessage&lt;/span&gt; &lt;span class="nf"&gt;resourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;WebRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ErrorMessage&lt;/span&gt; &lt;span class="n"&gt;message&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;ErrorMessage&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;message&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;h2&gt;Setup Spring Boot Project&lt;/h2&gt;

&lt;p&gt;You can follow step by step, or get source code in one of following posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-jpa-h2-example/" rel="noopener noreferrer"&gt;Spring Boot Data JPA + H2 CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-jpa-crud-rest-api/" rel="noopener noreferrer"&gt;Spring Boot Data JPA + MySQL CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-postgresql-example/" rel="noopener noreferrer"&gt;Spring Boot Data JPA + PostgreSQL CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-sql-server/" rel="noopener noreferrer"&gt;Spring Boot Data JPA + SQL Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-hibernate-oracle/" rel="noopener noreferrer"&gt;Spring Boot Data JPA + Oracle example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-mongodb-crud/" rel="noopener noreferrer"&gt;Spring Boot MongoDB CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-cassandra-crud/" rel="noopener noreferrer"&gt;Spring Boot Cassandra CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Spring Project contains structure that we only need to add some changes to make the pagination work well.&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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2019%2F12%2Fspring-boot-data-jpa-crud-example-project-structure.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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2019%2F12%2Fspring-boot-data-jpa-crud-example-project-structure.png" alt="spring-boot-data-jpa-crud-example-project-structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or you can get the new Github source code at the end of this tutorial.&lt;/p&gt;

&lt;p&gt;The final project structure will be 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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2019%2F10%2Fspring-boot-controlleradvice-exceptionhandler-example-project-structure.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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2019%2F10%2Fspring-boot-controlleradvice-exceptionhandler-example-project-structure.png" alt="spring-boot-controlleradvice-exceptionhandler-example-project-structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Define Error Response Message&lt;/h2&gt;

&lt;p&gt;We want to create a our own message response structure instead of using default error response provided by Spring Boot.&lt;br&gt;
Let's define a specific error response structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;exception&lt;/strong&gt;/&lt;em&gt;ErrorMessage.java&lt;/em&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.exhandling.exception&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.Date&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;ErrorMessage&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;statusCode&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;Date&lt;/span&gt; &lt;span class="n"&gt;timestamp&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="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;description&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;ErrorMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;statusCode&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt; &lt;span class="n"&gt;timestamp&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;message&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;description&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;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;statusCode&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;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timestamp&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;message&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="k"&gt;this&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="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getStatusCode&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;statusCode&lt;/span&gt;&lt;span class="o"&gt;;&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;Date&lt;/span&gt; &lt;span class="nf"&gt;getTimestamp&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;timestamp&lt;/span&gt;&lt;span class="o"&gt;;&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;String&lt;/span&gt; &lt;span class="nf"&gt;getMessage&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;message&lt;/span&gt;&lt;span class="o"&gt;;&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;String&lt;/span&gt; &lt;span class="nf"&gt;getDescription&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;description&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;h2&gt;Create Custom Exception&lt;/h2&gt;

&lt;p&gt;We're gonna throw an exception for Resource not found in Spring Boot controller.&lt;br&gt;
Lets create a &lt;code&gt;ResourceNotFoundException&lt;/code&gt; class that extends &lt;code&gt;RuntimeException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;exception&lt;/strong&gt;/&lt;em&gt;ResourceNotFoundException.java&lt;/em&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.exhandling.exception&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;ResourceNotFoundException&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;RuntimeException&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;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;serialVersionUID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1L&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;ResourceNotFoundException&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;msg&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&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;h2&gt;Create Controller Advice with @ExceptionHandler&lt;/h2&gt;

&lt;p&gt;Now we're gonna create a special class which is annotated by &lt;code&gt;@ControllerAdvice&lt;/code&gt; annotation. This class handles specific exception (&lt;code&gt;ResoureNotFoundException&lt;/code&gt;) and global Exception in only one place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;exception&lt;/strong&gt;/&lt;em&gt;ControllerExceptionHandler.java&lt;/em&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.exhandling.exception&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.Date&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.http.HttpStatus&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.http.ResponseEntity&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.ControllerAdvice&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.ExceptionHandler&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.context.request.WebRequest&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;com.bezkoder.spring.exhandling.exception.ErrorMessage&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;com.bezkoder.spring.exhandling.exception.ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ControllerAdvice&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;ControllerExceptionHandler&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@ExceptionHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ErrorMessage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;resourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;WebRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ErrorMessage&lt;/span&gt; &lt;span class="n"&gt;message&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;ErrorMessage&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;NOT_FOUND&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDescription&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="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;&lt;/span&gt;&lt;span class="nc"&gt;ErrorMessage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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;NOT_FOUND&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@ExceptionHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ErrorMessage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;globalExceptionHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;WebRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ErrorMessage&lt;/span&gt; &lt;span class="n"&gt;message&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;ErrorMessage&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;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDescription&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="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;&lt;/span&gt;&lt;span class="nc"&gt;ErrorMessage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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;INTERNAL_SERVER_ERROR&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;h2&gt;Modify Controller for using @ControllerAdvice&lt;/h2&gt;

&lt;p&gt;Our Rest Controller now doesn't have try/catch block, and it will throw &lt;code&gt;ResourceNotFoundException&lt;/code&gt; where we want to send NOT_FOUND notification in response message.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;controller&lt;/strong&gt;/&lt;em&gt;TutorialController.java&lt;/em&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.exhandling.controller&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.ArrayList&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.beans.factory.annotation.Autowired&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.http.HttpStatus&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.http.ResponseEntity&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.CrossOrigin&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.DeleteMapping&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.PostMapping&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.PutMapping&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.RequestBody&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.RequestParam&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;com.bezkoder.spring.exhandling.exception.ResourceNotFoundException&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;com.bezkoder.spring.exhandling.model.Tutorial&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;com.bezkoder.spring.exhandling.repository.TutorialRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@CrossOrigin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;origins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://localhost:8081"&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;"/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;class&lt;/span&gt; &lt;span class="nc"&gt;TutorialController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="nc"&gt;TutorialRepository&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&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;"/tutorials"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getAllTutorials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestParam&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;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;)&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tutorials&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;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if&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="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findAll&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;tutorials:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByTitleContaining&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="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;tutorials:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorials&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&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;NO_CONTENT&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="n"&gt;tutorials&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="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;"/tutorials/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getTutorialById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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="kt"&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="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&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="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not found Tutorial with id = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&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="n"&gt;tutorial&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="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tutorials"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;createTutorial&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;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;_tutorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTitle&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDescription&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="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="n"&gt;_tutorial&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="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;"/tutorials/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;updateTutorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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="kt"&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;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;_tutorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&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="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not found Tutorial with id = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="n"&gt;_tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTitle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTitle&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;_tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDescription&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDescription&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;_tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPublished&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isPublished&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="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_tutorial&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="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;"/tutorials/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;deleteTutorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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="kt"&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="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&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;NO_CONTENT&lt;/span&gt;&lt;span class="o"&gt;);&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;"/tutorials"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;deleteAllTutorials&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteAll&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;NO_CONTENT&lt;/span&gt;&lt;span class="o"&gt;);&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;"/tutorials/published"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByPublished&lt;/span&gt;&lt;span class="o"&gt;()&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tutorials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByPublished&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorials&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&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;NO_CONTENT&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="n"&gt;tutorials&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="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;h2&gt;Run and Test&lt;/h2&gt;

&lt;p&gt;We finish implementing CRUD REST APIs and exception handling for it.&lt;br&gt;
Run Spring Boot application with command: &lt;code&gt;mvn spring-boot:run&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get a non-existent tutorial:&lt;/li&gt;
&lt;/ul&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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fspring-boot-controlleradvice-exceptionhandler-example-demo-get-404.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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fspring-boot-controlleradvice-exceptionhandler-example-demo-get-404.png" alt="spring-boot-controlleradvice-exceptionhandler-example-demo-get-404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update a non-existent tutorial:&lt;/li&gt;
&lt;/ul&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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fspring-boot-controlleradvice-exceptionhandler-example-demo-update-404.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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fspring-boot-controlleradvice-exceptionhandler-example-demo-update-404.png" alt="spring-boot-controlleradvice-exceptionhandler-example-demo-update-404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create tutorial with wrong fields:&lt;/li&gt;
&lt;/ul&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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fspring-boot-controlleradvice-exceptionhandler-example-demo-create-500.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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fspring-boot-controlleradvice-exceptionhandler-example-demo-create-500.png" alt="spring-boot-controlleradvice-exceptionhandler-example-demo-create-500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete a non-existent tutorial:&lt;/li&gt;
&lt;/ul&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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fspring-boot-controlleradvice-exceptionhandler-example-demo-delete-500.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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2020%2F08%2Fspring-boot-controlleradvice-exceptionhandler-example-demo-delete-500.png" alt="spring-boot-controlleradvice-exceptionhandler-example-demo-delete-500"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Today we've built Global Exception Handling class for Spring Boot Rest APIs using &lt;code&gt;@ControllerAdvice&lt;/code&gt; and &lt;code&gt;@ExceptionHandler&lt;/code&gt;. Now you can create your own custom exception handler class or handle global exception in single place at ease.&lt;/p&gt;

&lt;p&gt;If you want to add Pagination to this Spring project, you can find the instruction at:&lt;br&gt;
&lt;a href="https://bezkoder.com/spring-boot-pagination-filter-jpa-pageable/" rel="noopener noreferrer"&gt;Spring Boot Pagination &amp;amp; Filter example | Spring JPA, Pageable&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To sort/order by multiple fields:&lt;br&gt;
&lt;a href="https://bezkoder.com/spring-data-sort-multiple-columns/" rel="noopener noreferrer"&gt;Spring Data JPA Sort/Order by multiple Columns | Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or way to write Unit Test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for JPA Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-webmvctest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for Rest Controller&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also know how to deploy this Spring Boot App on AWS (for free) with &lt;a href="https://bezkoder.com/deploy-spring-boot-aws-eb/" rel="noopener noreferrer"&gt;this tutorial&lt;/a&gt;.&lt;br&gt;
Dockerize with &lt;a href="https://www.bezkoder.com/docker-compose-spring-boot-mysql/" rel="noopener noreferrer"&gt;Docker Compose: Spring Boot and MySQL example&lt;/a&gt;&lt;br&gt;
Or: &lt;a href="https://www.bezkoder.com/docker-compose-spring-boot-postgres/" rel="noopener noreferrer"&gt;Docker Compose: Spring Boot and Postgres example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy learning! See you again.&lt;/p&gt;

&lt;h2&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-jwt-authentication/" rel="noopener noreferrer"&gt;Secure Spring Boot App with Spring Security &amp;amp; JWT Authentication&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#reference" rel="noopener noreferrer"&gt;Spring Data JPA Reference Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Source Code&lt;/h2&gt;

&lt;p&gt;You can find the complete source code for this tutorial on &lt;a href="https://github.com/bezkoder/spring-boot-exception-handling" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also use &lt;a href="https://bezkoder.com/spring-boot-restcontrolleradvice/" rel="noopener noreferrer"&gt;@RestControllerAdvice in Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Documentation: &lt;a href="https://www.bezkoder.com/spring-boot-swagger-3/" rel="noopener noreferrer"&gt;Spring Boot + Swagger 3 example (with OpenAPI 3)&lt;/a&gt;&lt;br&gt;
Caching: &lt;a href="https://www.bezkoder.com/spring-boot-redis-cache-example/" rel="noopener noreferrer"&gt;Spring Boot Redis Cache example&lt;/a&gt;&lt;br&gt;
Validation: &lt;a href="https://www.bezkoder.com/spring-boot-validate-request-body/" rel="noopener noreferrer"&gt;Validate Request Body in Spring Boot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>springboot</category>
      <category>java</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Docker Compose: Spring Boot and Postgres example</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Sun, 08 Oct 2023 02:53:56 +0000</pubDate>
      <link>https://forem.com/tienbku/docker-compose-spring-boot-and-postgres-example-4l82</link>
      <guid>https://forem.com/tienbku/docker-compose-spring-boot-and-postgres-example-4l82</guid>
      <description>&lt;p&gt;&lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; provides lightweight containers to run services in isolation from our infrastructure so we can deliver software quickly. In this tutorial, I will show you how to dockerize Spring Boot microservice and Postgres example using &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker Compose&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Related Posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-postgresql-example/" rel="noopener noreferrer"&gt;Spring Boot and PostgreSQL CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-r2dbc-postgresql/" rel="noopener noreferrer"&gt;Spring Boot R2DBC + PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-security-postgresql-jwt-authentication/" rel="noopener noreferrer"&gt;Spring Boot, Spring Security, PostgreSQL: JWT Authentication example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Documentation: &lt;a href="https://www.bezkoder.com/spring-boot-swagger-3/" rel="noopener noreferrer"&gt;Spring Boot Swagger 3 example&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Caching: &lt;a href="https://www.bezkoder.com/spring-boot-redis-cache-example/" rel="noopener noreferrer"&gt;Spring Boot Redis Cache example&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Assume that we have a Spring Boot Application working with Postgres database.&lt;br&gt;
The problem is to containerize a system that requires more than one Docker container:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Spring Boot for Rest API&lt;/li&gt;
    &lt;li&gt;Postgres for database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker Compose helps us setup the system more easily and efficiently than with only Docker. We're gonna following these steps:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Create Spring Boot App working with Postgres database.&lt;/li&gt;
    &lt;li&gt;Create Dockerfile for Spring Boot App.&lt;/li&gt;
    &lt;li&gt;Write Docker Compose configurations in YAML file.&lt;/li&gt;
    &lt;li&gt;Set Spring Boot Docker Compose Environment variables.&lt;/li&gt;
    &lt;li&gt;Run the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Directory Structure:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fdocker-compose-spring-boot-postgres.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fdocker-compose-spring-boot-postgres.png" alt="docker-compose-spring-boot-postgres"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Create Spring Boot App&lt;/h2&gt;

&lt;p&gt;You can read and get Github source code from one of following tutorials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-postgresql-example/" rel="noopener noreferrer"&gt;Spring Boot and PostgreSQL CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-r2dbc-postgresql/" rel="noopener noreferrer"&gt;Spring Boot R2DBC + PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-security-postgresql-jwt-authentication/" rel="noopener noreferrer"&gt;Spring Boot, Spring Security, PostgreSQL: JWT Authentication example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the code base above, we put the Spring Boot project in &lt;strong&gt;bezkoder-app&lt;/strong&gt; folder without the need of &lt;strong&gt;resources&lt;/strong&gt;/&lt;em&gt;application.properties&lt;/em&gt;. It is because Environment variables will be exported to &lt;em&gt;.env&lt;/em&gt; file.&lt;/p&gt;

&lt;h2&gt;Create Dockerfile for Spring Boot App&lt;/h2&gt;

&lt;p&gt;Dockerfile defines a list of commands that Docker uses for setting up the Spring Boot application environment. So we put the file in &lt;strong&gt;bezkoder-app&lt;/strong&gt; folder.&lt;/p&gt;

&lt;p&gt;Because we will use Docker Compose, we won't define all the configuration commands in this Dockerfile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bezkoder-app&lt;/strong&gt;/&lt;em&gt;Dockerfile&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="c"&gt;# FROM maven:3.8.2-jdk-8 # for Java 8
&lt;/span&gt;&lt;span class="err"&gt;FROM&lt;/span&gt; &lt;span class="py"&gt;maven&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;3.8.5-openjdk-17&lt;/span&gt;

&lt;span class="err"&gt;WORKDIR&lt;/span&gt; &lt;span class="err"&gt;/bezkoder-app&lt;/span&gt;
&lt;span class="err"&gt;COPY&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;RUN&lt;/span&gt; &lt;span class="err"&gt;mvn&lt;/span&gt; &lt;span class="err"&gt;clean&lt;/span&gt; &lt;span class="err"&gt;install&lt;/span&gt;

&lt;span class="err"&gt;CMD&lt;/span&gt; &lt;span class="err"&gt;mvn&lt;/span&gt; &lt;span class="py"&gt;spring-boot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;run&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Let me explain some points:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;FROM&lt;/code&gt;: install the image of the Maven - JDK version.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;WORKDIR&lt;/code&gt;: path of the working directory.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;COPY&lt;/code&gt;: copy all the files inside the project directory to the container.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;RUN&lt;/code&gt;: execute a command-line inside the container: &lt;code&gt;mvn clean install&lt;/code&gt; to install the dependencies in &lt;em&gt;pom.xml&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;CMD&lt;/code&gt;: run script &lt;code&gt;mvn spring-boot:run&lt;/code&gt; after the image is built.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Write Docker Compose configurations&lt;/h2&gt;

&lt;p&gt;On the root of the project directory, we're gonna create the &lt;em&gt;docker-compose.yml&lt;/em&gt; file. Follow &lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/" rel="noopener noreferrer"&gt;version 3&lt;/a&gt; syntax defined by Docker:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'3.8'&lt;/span&gt;

&lt;span class="py"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="s"&gt;postgresdb:&lt;/span&gt;
    &lt;span class="py"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;


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

&lt;/div&gt;

&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;version&lt;/code&gt;: Docker Compose file format version will be used.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;services&lt;/code&gt;: individual services in isolated containers. Our application has two services: &lt;code&gt;app&lt;/code&gt; (Spring Boot) and &lt;code&gt;postgresdb&lt;/code&gt; (PostgreSQL database).&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;&lt;a href="https://docs.docker.com/storage/volumes/" rel="noopener noreferrer"&gt;volumes&lt;/a&gt;&lt;/code&gt;: named volumes that keeps our data alive after restart.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's implement the details.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;docker-compose.yml&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"3.8"&lt;/span&gt;

&lt;span class="py"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="py"&gt;postgresdb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="py"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="py"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.env&lt;/span&gt;
    &lt;span class="py"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_USER&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_ROOT_PASSWORD&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_DATABASE&lt;/span&gt;
    &lt;span class="py"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;POSTGRESDB_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;$POSTGRESDB_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;/var/lib/postgres&lt;/span&gt;
  &lt;span class="py"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;postgresdb&lt;/span&gt;
    &lt;span class="py"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./bezkoder-app&lt;/span&gt;
    &lt;span class="py"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;on-failure&lt;/span&gt;
    &lt;span class="py"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.env&lt;/span&gt;
    &lt;span class="py"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;SPRING_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;$SPRING_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="py"&gt;SPRING_APPLICATION_JSON&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'{&lt;/span&gt;
        &lt;span class="err"&gt;"spring.datasource.url"&lt;/span&gt;  &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="py"&gt;jdbc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;postgresql://postgresdb:$POSTGRESDB_DOCKER_PORT/$POSTGRESDB_DATABASE",&lt;/span&gt;
        &lt;span class="err"&gt;"spring.datasource.username"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;"$POSTGRESDB_USER",&lt;/span&gt;
        &lt;span class="err"&gt;"spring.datasource.password"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;"$POSTGRESDB_ROOT_PASSWORD",&lt;/span&gt;
        &lt;span class="err"&gt;"spring.jpa.properties.hibernate.dialect"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;"org.hibernate.dialect.PostgreSQLDialect",&lt;/span&gt;
        &lt;span class="err"&gt;"spring.jpa.hibernate.ddl-auto"&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;"update"&lt;/span&gt;
      &lt;span class="err"&gt;}'&lt;/span&gt;
    &lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;.m2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;/root/.m2&lt;/span&gt;
    &lt;span class="py"&gt;stdin_open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
    &lt;span class="py"&gt;tty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="py"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;postgresdb&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;image&lt;/code&gt;: official Docker image&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;restart&lt;/code&gt;: configure the &lt;a href="https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy" rel="noopener noreferrer"&gt;restart policy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;env_file&lt;/code&gt;: specify our &lt;em&gt;.env&lt;/em&gt; path that we will create later&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment&lt;/code&gt;: provide setting using environment variables&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ports&lt;/code&gt;: specify ports will be used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;volumes&lt;/code&gt;: map volume folders&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#depends_on" rel="noopener noreferrer"&gt;depends_on&lt;/a&gt;&lt;/code&gt;: dependency order, &lt;strong&gt;postgresdb&lt;/strong&gt; is started before &lt;strong&gt;app&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt;: configuration options that are applied at build time that we defined in the &lt;em&gt;Dockerfile&lt;/em&gt; with relative path&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment&lt;/code&gt;: environmental variables that Spring Boot application uses&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stdin_open&lt;/code&gt; and &lt;code&gt;tty&lt;/code&gt;: keep open the terminal after building container&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;You should note that the host port (&lt;code&gt;LOCAL_PORT&lt;/code&gt;) and the container port (&lt;code&gt;DOCKER_PORT&lt;/code&gt;) is different. Networked service-to-service communication uses the container port, and the outside uses the host port.&lt;/p&gt;

&lt;h2&gt;Docker Compose Environment variables&lt;/h2&gt;

&lt;p&gt;In the service configuration, we used environmental variables defined inside the &lt;em&gt;.env&lt;/em&gt; file. Now we start writing it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;.env&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;POSTGRESDB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;span class="py"&gt;POSTGRESDB_ROOT_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;123456&lt;/span&gt;
&lt;span class="py"&gt;POSTGRESDB_DATABASE&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;bezkoder_db&lt;/span&gt;
&lt;span class="py"&gt;POSTGRESDB_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5433&lt;/span&gt;
&lt;span class="py"&gt;POSTGRESDB_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5432&lt;/span&gt;

&lt;span class="py"&gt;SPRING_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;6868&lt;/span&gt;
&lt;span class="py"&gt;SPRING_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;


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

&lt;/div&gt;

&lt;h2&gt;Run the Spring Boot microservice with Docker Compose&lt;/h2&gt;

&lt;p&gt;We can easily run the whole with only a single command:&lt;br&gt;
&lt;code&gt;docker compose up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Docker will pull the PostgreSQL and Maven images (if our machine does not have it before).&lt;/p&gt;

&lt;p&gt;The services can be run on the background with command:&lt;br&gt;
&lt;code&gt;docker compose up -d&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;+] Running 14/14
 ✔ postgresdb 13 layers &lt;span class="o"&gt;[&lt;/span&gt;⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                               30.0s 
   ✔ a803e7c4b030 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                               
   ✔ 009c876521a0 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                               
   ✔ 9c412905cca2 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                               
   ✔ 6463d4bf467a Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ bd8b983728ed Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ febc167f3560 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ d73c81c4ade3 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ 34b3b0ac6e9e Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ 9bd86d074f4e Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ 406f63329750 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ ec40772694b7 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ 7d3dfa1637e9 Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
   ✔ e217ca41159f Pull &lt;span class="nb"&gt;complete&lt;/span&gt;                                                                                                                                                                                              
&lt;span class="o"&gt;[&lt;/span&gt;+] Building 2.9s &lt;span class="o"&gt;(&lt;/span&gt;9/9&lt;span class="o"&gt;)&lt;/span&gt; FINISHED                                                                                                                                                                                    
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load build definition from Dockerfile                                                                                                                                                                      
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring dockerfile: 231B                                                                                                                                                                                          
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load .dockerignore                                                                                                                                                                                         
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring context: 2B                                                                                                                                                                                               
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load metadata &lt;span class="k"&gt;for &lt;/span&gt;docker.io/library/maven:3.8.5-openjdk-17                                                                                                                                                 
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 1/4] FROM docker.io/library/maven:3.8.5-openjdk-17@sha256:3a9c30b3af6278a8ae0007d3a3bf00fff80ec3ed7ae4eb9bfa1772853101549b                                                                                           
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app internal] load build context                                                                                                                                                                                         
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring context: 1.94kB                                                                                                                                                                                           
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 2/4] WORKDIR /bezkoder-app                                                                                                                                                                                    
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 3/4] COPY &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;                                                                                                                                                                                                 
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app 4/4] RUN mvn clean &lt;span class="nb"&gt;install&lt;/span&gt;                                                                                                                                                                                    
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;app] exporting to image                                                                                                                                                                                                  
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; exporting layers                                                                                                                                                                                                       
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; writing image sha256:bb65745b652009fa4bf508b771c9abc5e90f257f9efde63251df8c0a74c672d7                                                                                                                                  
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; naming to docker.io/library/spring-boot-postgres-app                                                                                                                                                                   
&lt;span class="o"&gt;[&lt;/span&gt;+] Running 2/1
 ✔ Container spring-boot-postgres-postgresdb-1  Created                                                                                                                                                                       
 ✔ Container spring-boot-postgres-app-1         Created                                                                                                                                                                       
Attaching to spring-boot-postgres-app-1, spring-boot-postgres-postgresdb-1
...
spring-boot-postgres-postgresdb-1  | PostgreSQL init process &lt;span class="nb"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; ready &lt;span class="k"&gt;for &lt;/span&gt;start up.
spring-boot-postgres-postgresdb-1  | 
spring-boot-postgres-postgresdb-1  | 
spring-boot-postgres-postgresdb-1  | 2023-10-03 03:35:18.102 UTC &lt;span class="o"&gt;[&lt;/span&gt;1] LOG:  starting PostgreSQL 16.0 &lt;span class="o"&gt;(&lt;/span&gt;Debian 16.0-1.pgdg120+1&lt;span class="o"&gt;)&lt;/span&gt; on x86_64-pc-linux-gnu, compiled by gcc &lt;span class="o"&gt;(&lt;/span&gt;Debian 12.2.0-14&lt;span class="o"&gt;)&lt;/span&gt; 12.2.0, 64-bit
spring-boot-postgres-postgresdb-1  | 2023-10-03 03:35:18.102 UTC &lt;span class="o"&gt;[&lt;/span&gt;1] LOG:  listening on IPv4 address &lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;, port 5432
spring-boot-postgres-postgresdb-1  | 2023-10-03 03:35:18.102 UTC &lt;span class="o"&gt;[&lt;/span&gt;1] LOG:  listening on IPv6 address &lt;span class="s2"&gt;"::"&lt;/span&gt;, port 5432
spring-boot-postgres-postgresdb-1  | 2023-10-03 03:35:18.105 UTC &lt;span class="o"&gt;[&lt;/span&gt;1] LOG:  listening on Unix socket &lt;span class="s2"&gt;"/var/run/postgresql/.s.PGSQL.5432"&lt;/span&gt;
spring-boot-postgres-postgresdb-1  | 2023-10-03 03:35:18.109 UTC &lt;span class="o"&gt;[&lt;/span&gt;64] LOG:  database system was shut down at 2023-10-03 03:35:18 UTC
spring-boot-postgres-postgresdb-1  | 2023-10-03 03:35:18.113 UTC &lt;span class="o"&gt;[&lt;/span&gt;1] LOG:  database system is ready to accept connections
spring-boot-postgres-app-1         | &lt;span class="o"&gt;[&lt;/span&gt;INFO] Scanning &lt;span class="k"&gt;for &lt;/span&gt;projects...
spring-boot-postgres-app-1         | &lt;span class="o"&gt;[&lt;/span&gt;INFO] 
spring-boot-postgres-app-1         | &lt;span class="o"&gt;[&lt;/span&gt;INFO] &lt;span class="nt"&gt;--------------&lt;/span&gt;&amp;lt; com.bezkoder:spring-boot-jpa-postgresql &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;---------------&lt;/span&gt;
spring-boot-postgres-app-1         | &lt;span class="o"&gt;[&lt;/span&gt;INFO] Building spring-boot-jpa-postgresql 0.0.1-SNAPSHOT
spring-boot-postgres-app-1         | &lt;span class="o"&gt;[&lt;/span&gt;INFO] &lt;span class="nt"&gt;--------------------------------&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt; jar &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nt"&gt;---------------------------------&lt;/span&gt;
spring-boot-postgres-app-1         | &lt;span class="o"&gt;[&lt;/span&gt;INFO] 
spring-boot-postgres-app-1         | &lt;span class="o"&gt;[&lt;/span&gt;INFO] &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; spring-boot-maven-plugin:3.1.0:run &lt;span class="o"&gt;(&lt;/span&gt;default-cli&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; test-compile @ spring-boot-jpa-postgresql &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
...
spring-boot-postgres-app-1         | 2023-10-03T03:41:46.545Z  INFO 59 &lt;span class="nt"&gt;---&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;: 8080 &lt;span class="o"&gt;(&lt;/span&gt;http&lt;span class="o"&gt;)&lt;/span&gt; with context path &lt;span class="s1"&gt;''&lt;/span&gt;
spring-boot-postgres-app-1         | 2023-10-03T03:41:46.551Z  INFO 59 &lt;span class="nt"&gt;---&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;           main] s.j.p.SpringBootJpaPostgresqlApplication : Started SpringBootJpaPostgresqlApplication &lt;span class="k"&gt;in &lt;/span&gt;2.188 seconds &lt;span class="o"&gt;(&lt;/span&gt;process running &lt;span class="k"&gt;for &lt;/span&gt;2.354&lt;span class="o"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now you can check the current working containers:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker ps
CONTAINER ID   IMAGE                      COMMAND                  CREATED         STATUS         PORTS                                       NAMES
9c3d10422b09   spring-boot-postgres-app   &lt;span class="s2"&gt;"/usr/local/bin/mvn-…"&lt;/span&gt;   2 minutes ago   Up 2 minutes   0.0.0.0:6868-&amp;gt;8080/tcp, :::6868-&amp;gt;8080/tcp   spring-boot-postgres-app-1
ed0b41f7f1c8   postgres                   &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   2 minutes ago   Up 2 minutes   0.0.0.0:5433-&amp;gt;5432/tcp, :::5433-&amp;gt;5432/tcp   spring-boot-postgres-postgresdb-1


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

&lt;/div&gt;

&lt;p&gt;And Docker images:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker images
REPOSITORY                 TAG            IMAGE ID       CREATED         SIZE
spring-boot-postgres-app   latest         bb65745b6520   5 minutes ago   962MB
postgres                   latest         2d74f8a2591c   6 minutes ago   417MB


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

&lt;/div&gt;

&lt;p&gt;Send a HTTP request to the Spring Boot - Postgres system:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fdocker-compose-spring-boot-postgres-test-api.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fdocker-compose-spring-boot-postgres-test-api.png" alt="docker-compose-spring-boot-postgres-test-api"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check Postgres Database:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-ti&lt;/span&gt; spring-boot-postgres-postgresdb-1 /bin/bash
root@8869979fbd27:/# psql bezkoder_db postgres
psql &lt;span class="o"&gt;(&lt;/span&gt;16.0 &lt;span class="o"&gt;(&lt;/span&gt;Debian 16.0-1.pgdg120+1&lt;span class="o"&gt;))&lt;/span&gt;
Type &lt;span class="s2"&gt;"help"&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;help.

&lt;span class="nv"&gt;bezkoder_db&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="c"&gt;# SELECT * FROM tutorials;&lt;/span&gt;
 &lt;span class="nb"&gt;id&lt;/span&gt; |    description    | published |                title                 
&lt;span class="nt"&gt;----&lt;/span&gt;+-------------------+-----------+--------------------------------------
  1 | Tut#1 Description | f         | bezkoder Docker Spring Boot Postgres
&lt;span class="o"&gt;(&lt;/span&gt;1 row&lt;span class="o"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;h2&gt;Stop the Application&lt;/h2&gt;

&lt;p&gt;Stopping all the running containers is also simple with a single command:&lt;br&gt;
&lt;code&gt;docker compose down&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose down
 ✔ Container spring-boot-postgres-app-1         Removed                                                                                                                                                      
 ✔ Container spring-boot-postgres-postgresdb-1  Removed                                                                                                                                                      
 ✔ Network spring-boot-postgres_default         Removed     


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

&lt;/div&gt;

&lt;p&gt;If you need to stop and remove all containers, networks, and all images used by any service in &lt;em&gt;docker-compose.yml&lt;/em&gt; file, use the command:&lt;br&gt;
&lt;code&gt;docker compose down --rmi all&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;Today we've successfully created Docker Compose file for Spring Boot application and Postgres. Now we can connect Spring Boot to PostgreSQL with Docker on a very simple way: &lt;em&gt;docker-compose.yml&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can apply this way to one of following project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-postgresql-example/" rel="noopener noreferrer"&gt;Spring Boot and PostgreSQL CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-r2dbc-postgresql/" rel="noopener noreferrer"&gt;Spring Boot R2DBC + PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-security-postgresql-jwt-authentication/" rel="noopener noreferrer"&gt;Spring Boot, Spring Security, PostgreSQL: JWT Authentication example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to deploy the system on AWS, please visit:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/deploy-spring-boot-aws-eb/" rel="noopener noreferrer"&gt;Deploy Spring Boot App on AWS – Elastic Beanstalk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy Learning! See you again.&lt;/p&gt;

&lt;h2&gt;Source Code&lt;/h2&gt;

&lt;p&gt;The source code for this tutorial can be found at &lt;a href="https://github.com/bezkoder/docker-compose-spring-boot-postgres" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Documentation: &lt;a href="https://www.bezkoder.com/spring-boot-swagger-3/" rel="noopener noreferrer"&gt;Spring Boot + Swagger 3 example (with OpenAPI 3)&lt;/a&gt;&lt;br&gt;
Caching: &lt;a href="https://www.bezkoder.com/spring-boot-redis-cache-example/" rel="noopener noreferrer"&gt;Spring Boot Redis Cache example&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>docker</category>
      <category>java</category>
    </item>
    <item>
      <title>Docker Node.js and MongoDB example</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Mon, 11 Sep 2023 03:57:51 +0000</pubDate>
      <link>https://forem.com/tienbku/docker-nodejs-and-mongodb-example-doc</link>
      <guid>https://forem.com/tienbku/docker-nodejs-and-mongodb-example-doc</guid>
      <description>&lt;p&gt;&lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; provides lightweight containers to run services in isolation from our infrastructure so we can deliver software quickly. In this tutorial, I will show you how to dockerize Nodejs Express and MongoDB example using &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker Compose&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Related Posts:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-express-mongodb-crud-rest-api/" rel="noopener noreferrer"&gt;Node.js Express Rest API with MongoDb&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-js-mongodb-pagination/" rel="noopener noreferrer"&gt;Node.js Express Pagination with Mongoose and MongoDB&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-js-mongodb-auth-jwt/" rel="noopener noreferrer"&gt;Node.js + MongoDB: User Authentication &amp;amp; Authorization&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-js-upload-store-images-mongodb/" rel="noopener noreferrer"&gt;Upload/store images in MongoDB using Node.js, Express &amp;amp; Multer&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/mongoose-one-to-one-relationship-example/" rel="noopener noreferrer"&gt;MongoDB One-to-One relationship tutorial with Mongoose example&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/mongoose-one-to-many-relationship/" rel="noopener noreferrer"&gt;MongoDB One-to-Many Relationship tutorial with Mongoose examples&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/mongodb-many-to-many-mongoose/" rel="noopener noreferrer"&gt;MongoDB Many-to-Many Relationship with Mongoose examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dockerize fullstack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/docker-mern/" rel="noopener noreferrer"&gt;Docker Compose: React + Node.js Express + MongoDB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Node.js Express and MongoDB with Docker Overview&lt;/h2&gt;

&lt;p&gt;Assume that we have a Nodejs Application working with MongoDB database.&lt;br&gt;
The problem is to containerize a system that requires more than one Docker container:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Node.js Express for API&lt;/li&gt;
    &lt;li&gt;MongoDB for database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker Compose helps us setup the system more easily and efficiently than with only Docker. We're gonna following these steps:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Create Nodejs App working with MongoDB database.&lt;/li&gt;
    &lt;li&gt;Create Dockerfile for Nodejs App.&lt;/li&gt;
    &lt;li&gt;Write Docker Compose configurations in YAML file.&lt;/li&gt;
    &lt;li&gt;Set Environment variables for Docker Compose&lt;/li&gt;
    &lt;li&gt;Run the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Directory Structure:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2F2021%2F08%2Fdocker-compose-nodejs-mongodb-example-structure.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2F2021%2F08%2Fdocker-compose-nodejs-mongodb-example-structure.png" alt="docker-compose-nodejs-mongodb-example-structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Create Nodejs App&lt;/h2&gt;

&lt;p&gt;You can read and get Github source code from one of following tutorials:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-express-mongodb-crud-rest-api/" rel="noopener noreferrer"&gt;Node.js Express Rest API with MongoDb&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-js-mongodb-pagination/" rel="noopener noreferrer"&gt;Node.js Express Pagination with Mongoose and MongoDB&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-js-mongodb-auth-jwt/" rel="noopener noreferrer"&gt;Node.js + MongoDB: User Authentication &amp;amp; Authorization&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-js-upload-store-images-mongodb/" rel="noopener noreferrer"&gt;Upload/store images in MongoDB using Node.js, Express &amp;amp; Multer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the code base above, we put the Nodejs project in &lt;strong&gt;bezkoder-app&lt;/strong&gt; folder and modify some files to work with environment variables.&lt;/p&gt;

&lt;p&gt;Firstly, let's add &lt;code&gt;dotenv&lt;/code&gt; module into &lt;em&gt;package.json&lt;/em&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dotenv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^10.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="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;Next we import &lt;code&gt;dotenv&lt;/code&gt; in &lt;em&gt;server.js&lt;/em&gt; and use &lt;code&gt;process.env&lt;/code&gt; for setting port.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;..&lt;/span&gt;
&lt;span class="c1"&gt;// set port, listen for requests&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_DOCKER_PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is running on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Then we change modify database configuration and initialization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;app&lt;/strong&gt;/&lt;strong&gt;config&lt;/strong&gt;/&lt;em&gt;db.config.js&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`mongodb://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?authSource=admin`&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We also need to make a &lt;em&gt;.env&lt;/em&gt; sample file that shows all necessary arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bezkoder-app&lt;/strong&gt;/&lt;em&gt;.env.sample&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;localhost&lt;/span&gt;
&lt;span class="py"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;
&lt;span class="py"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;123456&lt;/span&gt;
&lt;span class="py"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;bezkoder_db&lt;/span&gt;
&lt;span class="py"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;27017&lt;/span&gt;

&lt;span class="py"&gt;NODE_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;


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

&lt;/div&gt;

&lt;h2&gt;Create Dockerfile for Nodejs App&lt;/h2&gt;

&lt;p&gt;Dockerfile defines a list of commands that Docker uses for setting up the Node.js application environment. So we put the file in &lt;strong&gt;bezkoder-app&lt;/strong&gt; folder.&lt;/p&gt;

&lt;p&gt;Because we will use Docker Compose, we won't define all the configuration commands in this Dockerfile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bezkoder-app&lt;/strong&gt;/&lt;em&gt;Dockerfile&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="err"&gt;FROM&lt;/span&gt; &lt;span class="py"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;14&lt;/span&gt;

&lt;span class="err"&gt;WORKDIR&lt;/span&gt; &lt;span class="err"&gt;/bezkoder-app&lt;/span&gt;
&lt;span class="err"&gt;COPY&lt;/span&gt; &lt;span class="err"&gt;package.json&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;RUN&lt;/span&gt; &lt;span class="err"&gt;npm&lt;/span&gt; &lt;span class="err"&gt;install&lt;/span&gt;
&lt;span class="err"&gt;COPY&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;CMD&lt;/span&gt; &lt;span class="err"&gt;npm&lt;/span&gt; &lt;span class="err"&gt;start&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Let me explain some points:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;FROM&lt;/code&gt;: install the image of the Node.js version.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;WORKDIR&lt;/code&gt;: path of the working directory.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;COPY&lt;/code&gt;: copy &lt;em&gt;package.json&lt;/em&gt; file to the container, then the second one copies all the files inside the project directory.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;RUN&lt;/code&gt;: execute a command-line inside the container: &lt;code&gt;npm install&lt;/code&gt; to install the dependencies in &lt;em&gt;package.json&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;CMD&lt;/code&gt;: run script &lt;code&gt;npm start&lt;/code&gt; after the image is built.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Write Docker Compose configurations&lt;/h2&gt;

&lt;p&gt;On the root of the project directory, we're gonna create the &lt;em&gt;docker-compose.yml&lt;/em&gt; file. Follow &lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/" rel="noopener noreferrer"&gt;version 3&lt;/a&gt; syntax defined by Docker:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'3.8'&lt;/span&gt;

&lt;span class="py"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="s"&gt;mongodb:&lt;/span&gt;
    &lt;span class="py"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;


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

&lt;/div&gt;

&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;version&lt;/code&gt;: Docker Compose file format version will be used.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;services&lt;/code&gt;: individual services in isolated containers. Our application has two services: &lt;code&gt;app&lt;/code&gt; (Nodejs) and &lt;code&gt;mongodb&lt;/code&gt; (MongoDB database).&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;&lt;a href="https://docs.docker.com/storage/volumes/" rel="noopener noreferrer"&gt;volumes&lt;/a&gt;&lt;/code&gt;: named volumes that keeps our data alive after restart.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's implement the details.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;docker-compose.yml&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"3.8"&lt;/span&gt;

&lt;span class="py"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="py"&gt;mongodb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:5.0.2&lt;/span&gt;
    &lt;span class="py"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="py"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.env&lt;/span&gt;
    &lt;span class="py"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;MONGO_INITDB_ROOT_USERNAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_USER&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;MONGO_INITDB_ROOT_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_PASSWORD&lt;/span&gt;
    &lt;span class="py"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;MONGODB_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;/data/db&lt;/span&gt;
  &lt;span class="py"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;mongodb&lt;/span&gt;
    &lt;span class="py"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./bezkoder-app&lt;/span&gt;
    &lt;span class="py"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="py"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.env&lt;/span&gt;
    &lt;span class="py"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;NODE_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;$NODE_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;mongodb&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_USER&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_PASSWORD&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_DATABASE&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;stdin_open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
    &lt;span class="py"&gt;tty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="py"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;mongodb&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;image&lt;/code&gt;: official Docker image&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;restart&lt;/code&gt;: configure the &lt;a href="https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy" rel="noopener noreferrer"&gt;restart policy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;env_file&lt;/code&gt;: specify our &lt;em&gt;.env&lt;/em&gt; path that we will create later&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment&lt;/code&gt;: provide setting using environment variables&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ports&lt;/code&gt;: specify ports will be used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;volumes&lt;/code&gt;: map volume folders&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#depends_on" rel="noopener noreferrer"&gt;depends_on&lt;/a&gt;&lt;/code&gt;: dependency order, &lt;strong&gt;mongodb&lt;/strong&gt; is started before &lt;strong&gt;app&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt;: configuration options that are applied at build time that we defined in the &lt;em&gt;Dockerfile&lt;/em&gt; with relative path&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment&lt;/code&gt;: environmental variables that Node application uses&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stdin_open&lt;/code&gt; and &lt;code&gt;tty&lt;/code&gt;: keep open the terminal after building container&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;You should note that the host port (&lt;code&gt;LOCAL_PORT&lt;/code&gt;) and the container port (&lt;code&gt;DOCKER_PORT&lt;/code&gt;) is different. Networked service-to-service communication uses the container port, and the outside uses the host port.&lt;/p&gt;

&lt;h2&gt;Docker Compose Environment variables with MongoDB&lt;/h2&gt;

&lt;p&gt;In the service configuration, we used environmental variables defined inside the &lt;em&gt;.env&lt;/em&gt; file. Now we start writing it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;.env&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;

&lt;span class="py"&gt;MONGODB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;123456&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_DATABASE&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;bezkoder_db&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;7017&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;27017&lt;/span&gt;

&lt;span class="py"&gt;NODE_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;6868&lt;/span&gt;
&lt;span class="py"&gt;NODE_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;


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

&lt;/div&gt;

&lt;h2&gt;Run Nodejs MongoDB with Docker Compose&lt;/h2&gt;

&lt;p&gt;We can easily run the whole with only a single command:&lt;br&gt;
&lt;code&gt;docker compose up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Docker will pull the MongoDB and Node.js images (if our machine does not have it before).&lt;/p&gt;

&lt;p&gt;The services can be run on the background with command:&lt;br&gt;
&lt;code&gt;docker compose up -d&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
Creating network &lt;span class="s2"&gt;"node-mongodb_default"&lt;/span&gt; with the default driver
Creating volume &lt;span class="s2"&gt;"node-mongodb_db"&lt;/span&gt; with default driver
Pulling mongodb &lt;span class="o"&gt;(&lt;/span&gt;mongo:5.0.2&lt;span class="o"&gt;)&lt;/span&gt;...
5.0.2: Pulling from library/mongo
16ec32c2132b: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;6335cf672677: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;cbc70ccc8ebe: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;0d1a3c6bd417: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;960f3b9b27d3: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;aff995a136b4: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;4249be7550a8: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;cc105ff5aa3c: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;82819807d07a: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;81447d2c233f: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;Digest: sha256:54d24682d00278f64bf21ff62b7ee62b59dae50f65139831a884b345922b0f8a
Status: Downloaded newer image &lt;span class="k"&gt;for &lt;/span&gt;mongo:5.0.2
Building app
Sending build context to Docker daemon  19.46kB
Step 1/6 : FROM node:14
14: Pulling from library/node
eb18d230e067: Pull &lt;span class="nb"&gt;complete 
&lt;/span&gt;83600c1b4583: Pull &lt;span class="nb"&gt;complete 
&lt;/span&gt;4ae15c65bfa0: Pull &lt;span class="nb"&gt;complete 
&lt;/span&gt;c19c058edda5: Pull &lt;span class="nb"&gt;complete 
&lt;/span&gt;05cdaa0fd103: Pull &lt;span class="nb"&gt;complete 
&lt;/span&gt;8461dcff50c4: Pull &lt;span class="nb"&gt;complete 
&lt;/span&gt;84be4117f79d: Pull &lt;span class="nb"&gt;complete 
&lt;/span&gt;4ccb803887fd: Pull &lt;span class="nb"&gt;complete 
&lt;/span&gt;ab52680a5469: Pull &lt;span class="nb"&gt;complete 
&lt;/span&gt;Digest: sha256:c1fa7759eeff3f33ba08ff600ffaca4558954722a4345653ed1a0d87dffed9aa
Status: Downloaded newer image &lt;span class="k"&gt;for &lt;/span&gt;node:14
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 256d6360f157
Step 2/6 : WORKDIR /bezkoder-app
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;71b4b2e9dd6c
Removing intermediate container 71b4b2e9dd6c
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 194372d3695c
Step 3/6 : COPY package.json &lt;span class="nb"&gt;.&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 093f866b404a
Step 4/6 : RUN npm &lt;span class="nb"&gt;install&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;025f0f0365a9
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN node-express-mongodb@1.0.0 No repository field.

added 81 packages from 128 contributors and audited 81 packages &lt;span class="k"&gt;in &lt;/span&gt;6.902s

2 packages are looking &lt;span class="k"&gt;for &lt;/span&gt;funding
  run &lt;span class="sb"&gt;`&lt;/span&gt;npm fund&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;details

found 0 vulnerabilities

Removing intermediate container 025f0f0365a9
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 2f04aeaa93b1
Step 5/6 : COPY &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 50e31a045a02
Step 6/6 : CMD npm start
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;7353ac17fa02
Removing intermediate container 7353ac17fa02
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; bd9d66054ea2
Successfully built bd9d66054ea2
Successfully tagged node-mongodb_app:latest
WARNING: Image &lt;span class="k"&gt;for &lt;/span&gt;service app was built because it did not already exist. To rebuild this image you must use &lt;span class="sb"&gt;`&lt;/span&gt;docker compose build&lt;span class="sb"&gt;`&lt;/span&gt; or &lt;span class="sb"&gt;`&lt;/span&gt;docker compose up &lt;span class="nt"&gt;--build&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Creating node-mongodb_mongodb_1 ... &lt;span class="k"&gt;done
&lt;/span&gt;Creating node-mongodb_app_1     ... &lt;span class="k"&gt;done&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now you can check the current working containers:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED         STATUS         PORTS                                         NAMES
42b9271dd73f   node-mongodb_app   &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   2 minutes ago   Up 2 minutes   0.0.0.0:6868-&amp;gt;8080/tcp, :::6868-&amp;gt;8080/tcp     node-mongodb_app_1
e17bf545c0ba   mongo:5.0.2        &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   2 minutes ago   Up 2 minutes   0.0.0.0:7017-&amp;gt;27017/tcp, :::7017-&amp;gt;27017/tcp   node-mongodb_mongodb_1


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

&lt;/div&gt;

&lt;p&gt;And Docker images:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker images
REPOSITORY            TAG            IMAGE ID       CREATED         SIZE
node-mongodb_app      latest         bd9d66054ea2   5 minutes ago   960MB
node                  14             256d6360f157   6 minutes ago   944MB
mongo                 5.0.2          269b735e72cb   6 minutes ago   682MB


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

&lt;/div&gt;

&lt;p&gt;Let's send an HTTP request to check the Express Rest API:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2F2021%2F08%2Fdocker-compose-nodejs-mongodb-example-test-api.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2F2021%2F08%2Fdocker-compose-nodejs-mongodb-example-test-api.png" alt="docker-compose-nodejs-mongodb-example-test-api"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the MongoDB database also:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2F2021%2F08%2Fdocker-compose-nodejs-mongodb-example-test-database.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2F2021%2F08%2Fdocker-compose-nodejs-mongodb-example-test-database.png" alt="docker-compose-nodejs-mongodb-example-test-database"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Stop the Application&lt;/h2&gt;

&lt;p&gt;Stopping all the running containers is also simple with a single command:&lt;br&gt;
&lt;code&gt;docker compose down&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose down
Stopping node-mongodb_app_1     ... &lt;span class="k"&gt;done
&lt;/span&gt;Stopping node-mongodb_mongodb_1 ... &lt;span class="k"&gt;done
&lt;/span&gt;Removing node-mongodb_app_1     ... &lt;span class="k"&gt;done
&lt;/span&gt;Removing node-mongodb_mongodb_1 ... &lt;span class="k"&gt;done
&lt;/span&gt;Removing network node-mongodb_default


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

&lt;/div&gt;

&lt;p&gt;If you need to stop and remove all containers, networks, and all images used by any service in &lt;em&gt;docker-compose.yml&lt;/em&gt; file, use the command:&lt;br&gt;
&lt;code&gt;docker compose down --rmi all&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose down &lt;span class="nt"&gt;--rmi&lt;/span&gt; all
Stopping node-mongodb_app_1     ... &lt;span class="k"&gt;done
&lt;/span&gt;Stopping node-mongodb_mongodb_1 ... &lt;span class="k"&gt;done
&lt;/span&gt;Removing node-mongodb_app_1     ... &lt;span class="k"&gt;done
&lt;/span&gt;Removing node-mongodb_mongodb_1 ... &lt;span class="k"&gt;done
&lt;/span&gt;Removing network node-mongodb_default
Removing image mongo:5.0.2
Removing image node-mongodb_app


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

&lt;/div&gt;

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

&lt;p&gt;Today we've successfully created Docker Compose file for Nodejs and MongoDB application. Now we can deploy Nodejs Express and MongoDB with Docker on a very simple way: &lt;em&gt;docker-compose.yml&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can apply this way to one of following project:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-express-mongodb-crud-rest-api/" rel="noopener noreferrer"&gt;Node.js Express Rest API with MongoDb&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-js-mongodb-pagination/" rel="noopener noreferrer"&gt;Node.js Express Pagination with Mongoose and MongoDB&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-js-mongodb-auth-jwt/" rel="noopener noreferrer"&gt;Node.js + MongoDB: User Authentication &amp;amp; Authorization&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/node-js-upload-store-images-mongodb/" rel="noopener noreferrer"&gt;Upload/store images in MongoDB using Node.js, Express &amp;amp; Multer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or Dockerize fullstack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/docker-mern/" rel="noopener noreferrer"&gt;Docker Compose: React + Node.js Express + MongoDB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Learning! See you again.&lt;/p&gt;

&lt;h2&gt;Source Code&lt;/h2&gt;

&lt;p&gt;The source code for this tutorial can be found at &lt;a href="https://github.com/bezkoder/docker-compose-nodejs-mongodb" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Further Reading&lt;/h2&gt;

&lt;p&gt;Associations:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/mongoose-one-to-one-relationship-example/" rel="noopener noreferrer"&gt;MongoDB One-to-One relationship tutorial with Mongoose example&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/mongoose-one-to-many-relationship/" rel="noopener noreferrer"&gt;MongoDB One-to-Many Relationship tutorial with Mongoose examples&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://bezkoder.com/mongodb-many-to-many-mongoose/" rel="noopener noreferrer"&gt;MongoDB Many-to-Many Relationship with Mongoose examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>devops</category>
    </item>
    <item>
      <title>Spring Boot Thymeleaf File Upload example</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Thu, 31 Aug 2023 01:17:41 +0000</pubDate>
      <link>https://forem.com/tienbku/spring-boot-thymeleaf-file-upload-example-30gm</link>
      <guid>https://forem.com/tienbku/spring-boot-thymeleaf-file-upload-example-30gm</guid>
      <description>&lt;p&gt;In this tutorial, I will show you how to implement file upload with Thymeleaf and Bootstrap in a Spring Boot project. We also use Spring Web &lt;code&gt;MultipartFile&lt;/code&gt; interface to handle HTTP &lt;a href="https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html" rel="noopener noreferrer"&gt;multi-part&lt;/a&gt; requests.&lt;/p&gt;

&lt;p&gt;Related Posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-image-upload-thymeleaf/" rel="noopener noreferrer"&gt;Spring Boot upload Image and Display with Thymeleaf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-thymeleaf-example/" rel="noopener noreferrer"&gt;Spring Boot Thymeleaf CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/thymeleaf-pagination-and-sorting-example/" rel="noopener noreferrer"&gt;Spring Boot Thymeleaf Pagination and Sorting example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/thymeleaf-multiple-file-upload/" rel="noopener noreferrer"&gt;Spring Boot Thymeleaf Multiple File upload&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-controlleradvice-exceptionhandler/" rel="noopener noreferrer"&gt;Spring Boot @ControllerAdvice &amp;amp; @ExceptionHandler example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-restcontrolleradvice/" rel="noopener noreferrer"&gt;@RestControllerAdvice example in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for JPA Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-webmvctest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for Rest Controller&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/deploy-spring-boot-aws-eb/" rel="noopener noreferrer"&gt;Deploy Spring Boot App on AWS – Elastic Beanstalk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fullstack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-14-spring-boot-file-upload/" rel="noopener noreferrer"&gt;Angular + Spring Boot: File upload example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/react-file-upload-spring-boot/" rel="noopener noreferrer"&gt;React + Spring Boot: File upload example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Associations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/jpa-one-to-one/" rel="noopener noreferrer"&gt;Spring Boot One To One example with JPA, Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/jpa-one-to-many/" rel="noopener noreferrer"&gt;Spring Boot One To Many example with JPA, Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/jpa-many-to-many/" rel="noopener noreferrer"&gt;Spring Boot Many to Many example with JPA, Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;span id="Overview"&gt;Thymeleaf File Upload Overview&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;Our Spring Boot + Thymeleaf File Upload example will have following features:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;uploading File to a static folder in the Server&lt;/li&gt;
    &lt;li&gt;downloading File from server with the link&lt;/li&gt;
    &lt;li&gt;getting list of Files' information (file name &amp;amp; url)&lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
&lt;li&gt;Here is the File Upload Form:&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-example.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-example.png" alt="thymeleaf-file-upload-example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the File exceeds specific maximum size:&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-exception.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-exception.png" alt="thymeleaf-file-upload-exception"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This is the static folder that stores all uploaded files:&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-folder.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-folder.png" alt="thymeleaf-file-upload-folder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can see list of uploaded files with download links:&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-spring-boot.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-spring-boot.png" alt="thymeleaf-file-upload-spring-boot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial, I don't explain way to delete File. If you want to know that, just visit:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-boot-delete-file-thymeleaf/" rel="noopener noreferrer"&gt;Spring Boot Delete File example with Thymeleaf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or adding Pagination with following tutorial:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/thymeleaf-pagination/" rel="noopener noreferrer"&gt;Spring Boot Thymeleaf Pagination example&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span id="Project_Structure"&gt;Project Structure&lt;/span&gt;&lt;/h2&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-spring-boot-project.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-spring-boot-project.png" alt="thymeleaf-file-upload-spring-boot-project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me explain it briefly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;FileInfo&lt;/code&gt; contains information of the uploaded file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FilesStorageService&lt;/code&gt; helps us to initialize storage, save new file, load file, get list of Files' info, delete files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FileController&lt;/code&gt; uses &lt;code&gt;FilesStorageService&lt;/code&gt; to handle file upload/download and template requests.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FileUploadExceptionAdvice&lt;/code&gt; handles exception when the controller processes file upload.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;template&lt;/code&gt; stores HTML template files for the project.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;application.properties&lt;/em&gt; contains configuration for Servlet Multipart.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;uploads&lt;/em&gt; is the static folder for storing files.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;pom.xml&lt;/em&gt; for Spring Boot dependency.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;span id="Setup"&gt;Create &amp;amp; Setup Spring Boot project&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;Use &lt;a href="http://start.spring.io/" rel="noopener noreferrer"&gt;Spring web tool&lt;/a&gt; or your development tool (&lt;a href="https://spring.io/tools" rel="noopener noreferrer"&gt;Spring Tool Suite&lt;/a&gt;, Eclipse, &lt;a href="https://www.jetbrains.com/idea/download/" rel="noopener noreferrer"&gt;Intellij&lt;/a&gt;) to create a Spring Boot project.&lt;/p&gt;

&lt;p&gt;Then open &lt;strong&gt;pom.xml&lt;/strong&gt; and add dependencies for Spring Web, Thymeleaf, Bootstrap, Jquery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&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;org.springframework.boot&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;spring-boot-starter-web&lt;span class="nt"&gt;&amp;lt;/artifactId&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;org.springframework.boot&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;spring-boot-starter-thymeleaf&lt;span class="nt"&gt;&amp;lt;/artifactId&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;org.webjars&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;bootstrap&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.6.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;org.webjars&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;jquery&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;3.6.1&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;org.webjars&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;webjars-locator-core&lt;span class="nt"&gt;&amp;lt;/artifactId&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;h2&gt;&lt;span id="Create_Service"&gt;Create Service for File Storage&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;First we need an interface that will be autowired in the Controller.&lt;br&gt;
In &lt;em&gt;service&lt;/em&gt; folder, create &lt;code&gt;FilesStorageService&lt;/code&gt; interface like following code:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;service/FilesStorageService.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.thymeleaf.file.upload.service&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.nio.file.Path&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.stream.Stream&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.core.io.Resource&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.multipart.MultipartFile&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;FilesStorageService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MultipartFile&lt;/span&gt; &lt;span class="n"&gt;file&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;Resource&lt;/span&gt; &lt;span class="nf"&gt;load&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;filename&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;deleteAll&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;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;loadAll&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;Now we create implementation of the interface.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;service/FilesStorageServiceImpl.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.thymeleaf.file.upload.service&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.io.IOException&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.net.MalformedURLException&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.nio.file.FileAlreadyExistsException&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.nio.file.Files&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.nio.file.Path&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.nio.file.Paths&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.stream.Stream&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.core.io.Resource&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.core.io.UrlResource&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.stereotype.Service&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.util.FileSystemUtils&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.multipart.MultipartFile&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&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;FilesStorageServiceImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;FilesStorageService&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;Path&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Paths&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./uploads"&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Files&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createDirectories&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not initialize folder for upload!"&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MultipartFile&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Files&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputStream&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;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOriginalFilename&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;FileAlreadyExistsException&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A file of that name already exists."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&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;Resource&lt;/span&gt; &lt;span class="nf"&gt;load&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;filename&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Path&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="nc"&gt;Resource&lt;/span&gt; &lt;span class="n"&gt;resource&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;UrlResource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toUri&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exists&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isReadable&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;resource&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not read the file!"&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="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MalformedURLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;deleteAll&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;FileSystemUtils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteRecursively&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toFile&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;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;loadAll&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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;Files&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;walk&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;root&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&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;root&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;map&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;root&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;relativize&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not load the files!"&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="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;&lt;span id="Create_Controller"&gt;Create Controller for File Upload&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;controller&lt;/strong&gt; package, we create &lt;code&gt;FileController&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;controller/FileController.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.thymeleaf.file.upload.controller&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.thymeleaf.file.upload.service.FilesStorageService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Controller&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;FileController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="nc"&gt;FilesStorageService&lt;/span&gt; &lt;span class="n"&gt;storageService&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;"/"&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;String&lt;/span&gt; &lt;span class="nf"&gt;homepage&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="s"&gt;"redirect:/files"&lt;/span&gt;&lt;span class="o"&gt;;&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;"/files/new"&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;String&lt;/span&gt; &lt;span class="nf"&gt;newFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;model&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="s"&gt;"upload_form"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/files/upload"&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;String&lt;/span&gt; &lt;span class="nf"&gt;uploadFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;@RequestParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;MultipartFile&lt;/span&gt; &lt;span class="n"&gt;file&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="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"upload_form"&lt;/span&gt;&lt;span class="o"&gt;;&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;"/files"&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;String&lt;/span&gt; &lt;span class="nf"&gt;getListFiles&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;model&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="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"files"&lt;/span&gt;&lt;span class="o"&gt;;&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;"/files/{filename:.+}"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getFile&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;filename&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="c1"&gt;// return File&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;ul&gt;
&lt;li&gt;
&lt;code&gt;@Controller&lt;/code&gt; annotation is used to define a controller.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@GetMapping&lt;/code&gt; and &lt;code&gt;@PostMapping&lt;/code&gt; annotation is for mapping HTTP GET &amp;amp; POST requests onto specific handler methods and returning appropriate template files.&lt;/li&gt;
&lt;li&gt;We use &lt;code&gt;@Autowired&lt;/code&gt; to inject implementation of &lt;code&gt;FilesStorageService&lt;/code&gt; bean to local variable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;span id="Setup_template"&gt;Setup the Template&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;src&lt;/strong&gt;/&lt;strong&gt;main&lt;/strong&gt;/&lt;strong&gt;resources&lt;/strong&gt; folder, create folder and file as following structure:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-example-template.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fthymeleaf-file-upload-example-template.png" alt="thymeleaf-file-upload-example-template"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Header and Footer&lt;/h3&gt;

&lt;p&gt;We will use Thymeleaf Fragments (&lt;code&gt;th:fragment&lt;/code&gt;) to reuse some common parts such as header and footer.&lt;br&gt;
Let's write HTML code for them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;fragments&lt;/strong&gt;/&lt;em&gt;footer.html&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;footer&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-center"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Copyright &lt;span class="ni"&gt;&amp;amp;copy;&lt;/span&gt; BezKoder
&lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And header that contains the navigation bar:&lt;br&gt;
&lt;strong&gt;fragments&lt;/strong&gt;/&lt;em&gt;header.html&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;th:fragment=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar navbar-expand-md bg-dark navbar-dark mb-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-brand"&lt;/span&gt; &lt;span class="na"&gt;th:href=&lt;/span&gt;&lt;span class="s"&gt;"@{/files}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      BezKoder
    &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-toggler"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;data-toggle=&lt;/span&gt;&lt;span class="s"&gt;"collapse"&lt;/span&gt; &lt;span class="na"&gt;data-target=&lt;/span&gt;&lt;span class="s"&gt;"#topNavbar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-toggler-icon"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"collapse navbar-collapse"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"topNavbar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-nav"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-link"&lt;/span&gt; &lt;span class="na"&gt;th:href=&lt;/span&gt;&lt;span class="s"&gt;"@{/files/new}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Upload&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-link"&lt;/span&gt; &lt;span class="na"&gt;th:href=&lt;/span&gt;&lt;span class="s"&gt;"@{/files}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Files&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to create HTML files, then import Thymeleaf fragments, Bootstrap, jQuery and Font Awesome.&lt;/p&gt;

&lt;h3&gt;File Upload Form&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;upload_form.html&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;xmlns:th=&lt;/span&gt;&lt;span class="s"&gt;"http://www.thymeleaf.org"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"text/html; charset=UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width,initial-scale=1.0,minimum-scale=1.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;BezKoder - Thymeleaf File Upload example&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="na"&gt;th:href=&lt;/span&gt;&lt;span class="s"&gt;"@{/webjars/bootstrap/css/bootstrap.min.css}"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;th:src=&lt;/span&gt;&lt;span class="s"&gt;"@{/webjars/jquery/jquery.min.js}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;th:src=&lt;/span&gt;&lt;span class="s"&gt;"@{/webjars/bootstrap/js/bootstrap.min.js}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;th:replace=&lt;/span&gt;&lt;span class="s"&gt;"fragments/header :: header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  -- file upload form --

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;th:replace=&lt;/span&gt;&lt;span class="s"&gt;"fragments/footer :: footer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;List of Files&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;files.html&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;xmlns:th=&lt;/span&gt;&lt;span class="s"&gt;"http://www.thymeleaf.org"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"text/html; charset=UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width,initial-scale=1.0,minimum-scale=1.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;BezKoder - Thymeleaf File Upload example&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="na"&gt;th:href=&lt;/span&gt;&lt;span class="s"&gt;"@{/webjars/bootstrap/css/bootstrap.min.css}"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"&lt;/span&gt;
    &lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;"sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A=="&lt;/span&gt;
    &lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;"anonymous"&lt;/span&gt; &lt;span class="na"&gt;referrerpolicy=&lt;/span&gt;&lt;span class="s"&gt;"no-referrer"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;th:src=&lt;/span&gt;&lt;span class="s"&gt;"@{/webjars/jquery/jquery.min.js}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;th:src=&lt;/span&gt;&lt;span class="s"&gt;"@{/webjars/bootstrap/js/bootstrap.min.js}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;th:replace=&lt;/span&gt;&lt;span class="s"&gt;"fragments/header :: header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  -- list of files display --

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;th:replace=&lt;/span&gt;&lt;span class="s"&gt;"fragments/footer :: footer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;&lt;span id="Implement_File_Upload"&gt;Implement File Upload function&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;We use &lt;code&gt;@GetMapping&lt;/code&gt; and &lt;code&gt;@PostMapping&lt;/code&gt; annotation is for mapping HTTP GET &amp;amp; POST requests onto specific handler methods:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;GET /files/new: &lt;code&gt;newFile()&lt;/code&gt; - return &lt;em&gt;upload_form.html&lt;/em&gt; template&lt;/li&gt;
    &lt;li&gt;POST /files/upload: &lt;code&gt;uploadFile()&lt;/code&gt; - upload a File&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;FileController.java&lt;/em&gt;&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;com.bezkoder.spring.thymeleaf.file.upload.service.FilesStorageService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Controller&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;FileController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="nc"&gt;FilesStorageService&lt;/span&gt; &lt;span class="n"&gt;storageService&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;"/files/new"&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;String&lt;/span&gt; &lt;span class="nf"&gt;newFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;model&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="s"&gt;"upload_form"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/files/upload"&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;String&lt;/span&gt; &lt;span class="nf"&gt;uploadFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;@RequestParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;MultipartFile&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;)&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;message&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="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;storageService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&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;"Uploaded the file successfully: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOriginalFilename&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAttribute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"message"&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="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&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;"Could not upload the file: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOriginalFilename&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;". Error: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAttribute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"message"&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="o"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"upload_form"&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;&lt;em&gt;upload_form.html&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"max-width: 500px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mb-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Thymeleaf File Upload example&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt;
    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"uploadForm"&lt;/span&gt;
    &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt;
    &lt;span class="na"&gt;th:action=&lt;/span&gt;&lt;span class="s"&gt;"@{/files/upload}"&lt;/span&gt;
    &lt;span class="na"&gt;enctype=&lt;/span&gt;&lt;span class="s"&gt;"multipart/form-data"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"input-file"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-sm btn-outline-success float-right"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Upload
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
    &lt;span class="na"&gt;th:if=&lt;/span&gt;&lt;span class="s"&gt;"${message != null}"&lt;/span&gt;
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-secondary alert-dismissible fade show text-center message mt-3"&lt;/span&gt;
    &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    [[${message}]]
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"close btn-sm"&lt;/span&gt; &lt;span class="na"&gt;data-dismiss=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Close"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ni"&gt;&amp;amp;times;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;&lt;span id="Display_List_Files"&gt;Display List of Files&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;Firstly, we need to create &lt;code&gt;FileInfo&lt;/code&gt; model which has fields: &lt;code&gt;name&lt;/code&gt; &amp;amp; &lt;code&gt;url&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;model/FileInfo.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.thymeleaf.file.upload.model&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;FileInfo&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="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;url&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;FileInfo&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;name&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;url&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;name&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="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;url&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="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getName&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;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setName&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;name&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;name&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="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getUrl&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;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setUrl&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;url&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;url&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="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;In the Controller, we will return List of &lt;code&gt;FileInfo&lt;/code&gt; objects as model Attribute. &lt;br&gt;
&lt;code&gt;@GetMapping&lt;/code&gt; and &lt;code&gt;@PostMapping&lt;/code&gt; annotation is for mapping HTTP GET &amp;amp; POST requests onto specific handler methods:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;GET /files: &lt;code&gt;getListFiles()&lt;/code&gt; - return &lt;em&gt;files.html&lt;/em&gt; template&lt;/li&gt;
    &lt;li&gt;GET /files/[filename]: &lt;code&gt;getFile()&lt;/code&gt; - download a File by &lt;code&gt;filename&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;FileController.java&lt;/em&gt;&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;com.bezkoder.spring.thymeleaf.file.upload.model.FileInfo&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;com.bezkoder.spring.thymeleaf.file.upload.service.FilesStorageService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Controller&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;FileController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="nc"&gt;FilesStorageService&lt;/span&gt; &lt;span class="n"&gt;storageService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="c1"&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;"/"&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;String&lt;/span&gt; &lt;span class="nf"&gt;homepage&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="s"&gt;"redirect:/files"&lt;/span&gt;&lt;span class="o"&gt;;&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;"/files"&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;String&lt;/span&gt; &lt;span class="nf"&gt;getListFiles&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;)&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;FileInfo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fileInfos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storageService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadAll&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&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;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFileName&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MvcUriComponentsBuilder&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromMethodName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FileController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"getFile"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFileName&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&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="na"&gt;toString&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;FileInfo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&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="o"&gt;}).&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAttribute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"files"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileInfos&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"files"&lt;/span&gt;&lt;span class="o"&gt;;&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;"/files/{filename:.+}"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getFile&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;filename&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Resource&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storageService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&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;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="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="nc"&gt;HttpHeaders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONTENT_DISPOSITION&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"attachment; filename=\""&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFilename&lt;/span&gt;&lt;span class="o"&gt;()&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="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&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;&lt;em&gt;files.html&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container-fluid"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"max-width: 600px; margin: 0 auto;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-center"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;List of Files&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;th:if=&lt;/span&gt;&lt;span class="s"&gt;"${files.size() &amp;gt; 0}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"table table-hover"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;thead&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"thead-light"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;File Name&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Link&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Actions&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/thead&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;tbody&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;tr&lt;/span&gt; &lt;span class="na"&gt;th:each=&lt;/span&gt;&lt;span class="s"&gt;"file : ${files}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;[[${file.name}]]&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;th:href=&lt;/span&gt;&lt;span class="s"&gt;"@{${file.url}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Download&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;th:href=&lt;/span&gt;&lt;span class="s"&gt;"@{'/files/delete/' + ${file.name}}"&lt;/span&gt; &lt;span class="na"&gt;th:fileName=&lt;/span&gt;&lt;span class="s"&gt;"${file.name}"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"btnDelete"&lt;/span&gt;
              &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Delete this file"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fa-regular fa-trash-can icon-dark btn-delete"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/tbody&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;th:unless=&lt;/span&gt;&lt;span class="s"&gt;"${files.size() &amp;gt; 0}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;No files found!&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For deleting file, kindly visit following tutorial:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-boot-delete-file-thymeleaf/" rel="noopener noreferrer"&gt;Spring Boot Delete File example with Thymeleaf&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span id="Configure"&gt;Configure Multipart File for Servlet&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;Let's define the maximum file size that can be uploaded in &lt;em&gt;application.properties&lt;/em&gt; as following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;spring.servlet.multipart.max-file-size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1MB&lt;/span&gt;
&lt;span class="py"&gt;spring.servlet.multipart.max-request-size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1MB&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;– &lt;code&gt;spring.servlet.multipart.max-file-size&lt;/code&gt;: max file size for each request.&lt;br&gt;
– &lt;code&gt;spring.servlet.multipart.max-request-size&lt;/code&gt;: max request size for a multipart/form-data.&lt;/p&gt;

&lt;h2&gt;&lt;span id="Handle_Exception"&gt;Handle File Upload Exception&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;This is where we handle the case in that a request exceeds Max Upload Size. The system will throw &lt;code&gt;MaxUploadSizeExceededException&lt;/code&gt; and we're gonna use &lt;code&gt;@ControllerAdvice&lt;/code&gt; with &lt;code&gt;@ExceptionHandler&lt;/code&gt;annotation for handling the exceptions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;exception/FileUploadExceptionAdvice.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.thymeleaf.file.upload.exception&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.multipart.MaxUploadSizeExceededException&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.ui.Model&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.ControllerAdvice&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.ExceptionHandler&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ControllerAdvice&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;FileUploadExceptionAdvice&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@ExceptionHandler&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MaxUploadSizeExceededException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&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;String&lt;/span&gt; &lt;span class="nf"&gt;handleMaxSizeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;MaxUploadSizeExceededException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAttribute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"File is too large!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"upload_form"&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;h2&gt;&lt;span id="Initialize_Storage"&gt;Initialize Storage&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;We need to run &lt;code&gt;init()&lt;/code&gt; method of &lt;code&gt;FilesStorageService&lt;/code&gt; (and also &lt;code&gt;deleteAll()&lt;/code&gt; if necessary). So open &lt;em&gt;ThymeleafFileUploadApplication.java&lt;/em&gt; and implement &lt;code&gt;CommandLineRunner&lt;/code&gt; for &lt;code&gt;run()&lt;/code&gt; method 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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.thymeleaf.file.upload&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;javax.annotation.Resource&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.boot.CommandLineRunner&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.boot.SpringApplication&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.boot.autoconfigure.SpringBootApplication&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;com.bezkoder.spring.thymeleaf.file.upload.service.FilesStorageService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@SpringBootApplication&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;ThymeleafFileUploadApplication&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;CommandLineRunner&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Resource&lt;/span&gt;
  &lt;span class="nc"&gt;FilesStorageService&lt;/span&gt; &lt;span class="n"&gt;storageService&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;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ThymeleafFileUploadApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//    storageService.deleteAll();&lt;/span&gt;
    &lt;span class="n"&gt;storageService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;init&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;h2&gt;&lt;span id="Run"&gt;Run the Spring Boot File Upload example&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;Run Spring Boot application with command: &lt;code&gt;mvn spring-boot:run&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;&lt;span id="Source_Code"&gt;Source Code&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;You can find the complete source code for this tutorial on &lt;a href="https://github.com/bezkoder/thymeleaf-file-upload" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For deleting file:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-boot-delete-file-thymeleaf/" rel="noopener noreferrer"&gt;Spring Boot Delete File example with Thymeleaf&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span id="Conclusion"&gt;Conclusion&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;Today we've learned how to create Spring Boot Thymeleaf File Upload Application with multipart files and get files' information with static folder.&lt;/p&gt;

&lt;p&gt;For upload multiple Files at once:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/thymeleaf-multiple-file-upload/" rel="noopener noreferrer"&gt;Spring Boot Multiple File upload with Thymeleaf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or fullstack with frontend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-14-spring-boot-file-upload/" rel="noopener noreferrer"&gt;Angular + Spring Boot: File upload example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/react-file-upload-spring-boot/" rel="noopener noreferrer"&gt;React + Spring Boot: File upload example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also know way to upload an Excel/CSV file and store the content in MySQL database with the post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-upload-excel-file-database/" rel="noopener noreferrer"&gt;Spring Boot: Upload/Import Excel file data into MySQL Database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-upload-csv-file/" rel="noopener noreferrer"&gt;Spring Boot: Upload/Import CSV file data into MySQL Database&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to store files in database like this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2020%2F07%2Fspring-boot-upload-files-to-database-table-files.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%2Fbezkoder.com%2Fwp-content%2Fuploads%2F2020%2F07%2Fspring-boot-upload-files-to-database-table-files.png" alt="spring-boot-upload-files-to-database-table-files"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find instruction at:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-boot-upload-file-database/" rel="noopener noreferrer"&gt;Spring Boot Upload/Download File to/from Database example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy Learning! See you again.&lt;/p&gt;

&lt;h2&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-image-upload-thymeleaf/" rel="noopener noreferrer"&gt;Spring Boot upload Image and Display with Thymeleaf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-upload-multiple-files/" rel="noopener noreferrer"&gt;Spring Boot upload multiple files Rest API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-thymeleaf-example/" rel="noopener noreferrer"&gt;Spring Boot Thymeleaf CRUD example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/thymeleaf-pagination-and-sorting-example/" rel="noopener noreferrer"&gt;Spring Boot Thymeleaf Pagination and Sorting example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exception Handling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-controlleradvice-exceptionhandler/" rel="noopener noreferrer"&gt;Spring Boot @ControllerAdvice &amp;amp; @ExceptionHandler example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-restcontrolleradvice/" rel="noopener noreferrer"&gt;@RestControllerAdvice example in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unit Test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for JPA Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-webmvctest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for Rest Controller&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/deploy-spring-boot-aws-eb/" rel="noopener noreferrer"&gt;Deploy Spring Boot App on AWS – Elastic Beanstalk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Associations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/jpa-one-to-one/" rel="noopener noreferrer"&gt;Spring Boot One To One example with JPA, Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/jpa-one-to-many/" rel="noopener noreferrer"&gt;Spring Boot One To Many example with JPA, Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/jpa-many-to-many/" rel="noopener noreferrer"&gt;Spring Boot Many to Many example with JPA, Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>java</category>
      <category>springboot</category>
      <category>programming</category>
    </item>
    <item>
      <title>Docker MERN stack example</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Wed, 23 Aug 2023 03:22:26 +0000</pubDate>
      <link>https://forem.com/tienbku/docker-mern-stack-example-7j</link>
      <guid>https://forem.com/tienbku/docker-mern-stack-example-7j</guid>
      <description>&lt;p&gt;&lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt; provides lightweight containers to run services in isolation from our infrastructure so we can deliver software quickly. In this tutorial, I will show you how to dockerize MERN stack Application (React + Node.js + Express + MongoDB) example using &lt;a href="https://docs.docker.com/compose/"&gt;Docker Compose&lt;/a&gt; and &lt;a href="https://www.nginx.com/"&gt;Nginx&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Related Posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/react-node-express-mongodb-mern-stack/"&gt;React + Node.js + Express + MongoDB example: CRUD App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/react-node-mongodb-auth/"&gt;React + Node.js Express + MongoDB: User Authentication with JWT example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/integrate-react-express-same-server-port/"&gt;Integrate React with Node.js Express on same Server/Port&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;MERN stack Application with Docker Overview&lt;/h2&gt;

&lt;p&gt;Assume that we have a fullstack React + Nodejs Express + MongoDB Application (MERN stack).&lt;br&gt;
The problem is to containerize a system that requires more than one Docker container:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;React for UI&lt;/li&gt;
    &lt;li&gt;Node.js Express for API&lt;/li&gt;
    &lt;li&gt;MongoDB for database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker Compose helps us setup the system more easily and efficiently than with only Docker. We're gonna following these steps:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Setup Nodejs App working with MongoDB database.&lt;/li&gt;
    &lt;li&gt;Create Dockerfile for Nodejs App.&lt;/li&gt;
    &lt;li&gt;Setup React App.&lt;/li&gt;
    &lt;li&gt;Create Dockerfile for React App.&lt;/li&gt;
    &lt;li&gt;Write Docker Compose configurations in YAML file.&lt;/li&gt;
    &lt;li&gt;Set Environment variables for Docker Compose&lt;/li&gt;
    &lt;li&gt;Run the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Directory Structure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sjkRoToK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.bezkoder.com/wp-content/uploads/2021/05/docker-mern-nginx-example-structure.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sjkRoToK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.bezkoder.com/wp-content/uploads/2021/05/docker-mern-nginx-example-structure.png" alt="docker-mern-nginx-example-structure" width="240" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Setup Nodejs App&lt;/h2&gt;

&lt;p&gt;You can read and get Github source code from one of following tutorials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-express-mongodb-crud-rest-api/"&gt;Node.js, Express &amp;amp; MongoDb: Build a CRUD Rest Api example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-mongodb-auth-jwt/"&gt;Node.js + MongoDB: User Authentication &amp;amp; Authorization with JWT&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the code base above, we put the Nodejs project in &lt;strong&gt;bezkoder-api&lt;/strong&gt; folder and modify some files to work with environment variables.&lt;/p&gt;

&lt;p&gt;Firstly, let's add &lt;code&gt;dotenv&lt;/code&gt; module into &lt;em&gt;package.json&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dotenv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^10.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="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;Next we import &lt;code&gt;dotenv&lt;/code&gt; in &lt;em&gt;server.js&lt;/em&gt; and use &lt;code&gt;process.env&lt;/code&gt; for setting up CORS and port.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;corsOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLIENT_ORIGIN&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:8081&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;corsOptions&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;..&lt;/span&gt;
&lt;span class="c1"&gt;// set port, listen for requests&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_DOCKER_PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is running on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we change modify database configuration and initialization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;app&lt;/strong&gt;/&lt;strong&gt;config&lt;/strong&gt;/&lt;em&gt;db.config.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`mongodb://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?authSource=admin`&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also need to make a &lt;em&gt;.env&lt;/em&gt; sample file that shows all necessary arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bezkoder-api&lt;/strong&gt;/&lt;em&gt;.env.sample&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;localhost&lt;/span&gt;
&lt;span class="py"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;
&lt;span class="py"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;123456&lt;/span&gt;
&lt;span class="py"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;bezkoder_db&lt;/span&gt;
&lt;span class="py"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;27017&lt;/span&gt;

&lt;span class="py"&gt;NODE_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;

&lt;span class="py"&gt;CLIENT_ORIGIN&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://127.0.0.1:8081&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;Create Dockerfile for Nodejs App&lt;/h2&gt;

&lt;p&gt;Dockerfile defines a list of commands that Docker uses for setting up the Node.js application environment. So we put the file in &lt;strong&gt;bezkoder-api&lt;/strong&gt; folder.&lt;/p&gt;

&lt;p&gt;Because we will use Docker Compose, we won't define all the configuration commands in this Dockerfile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bezkoder-api&lt;/strong&gt;/&lt;em&gt;Dockerfile&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="err"&gt;FROM&lt;/span&gt; &lt;span class="py"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;14&lt;/span&gt;

&lt;span class="err"&gt;WORKDIR&lt;/span&gt; &lt;span class="err"&gt;/bezkoder-api&lt;/span&gt;
&lt;span class="err"&gt;COPY&lt;/span&gt; &lt;span class="err"&gt;package.json&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;RUN&lt;/span&gt; &lt;span class="err"&gt;npm&lt;/span&gt; &lt;span class="err"&gt;install&lt;/span&gt;
&lt;span class="err"&gt;COPY&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;CMD&lt;/span&gt; &lt;span class="err"&gt;npm&lt;/span&gt; &lt;span class="err"&gt;start&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain some points:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;FROM&lt;/code&gt;: install the image of the Node.js version.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;WORKDIR&lt;/code&gt;: path of the working directory.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;COPY&lt;/code&gt;: copy &lt;em&gt;package.json&lt;/em&gt; file to the container, then the second one copies all the files inside the project directory.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;RUN&lt;/code&gt;: execute a command-line inside the container: &lt;code&gt;npm install&lt;/code&gt; to install the dependencies in &lt;em&gt;package.json&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;CMD&lt;/code&gt;: run script &lt;code&gt;npm start&lt;/code&gt; after the image is built.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Setup React App&lt;/h2&gt;

&lt;p&gt;You can read and get Github source code from one of following tutorials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/react-crud-web-api/"&gt;React CRUD example to consume Web API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/react-typescript-axios/"&gt;React Typescript CRUD example to consume Web API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/react-redux-crud-example/"&gt;React Redux CRUD App example with Rest API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/react-hooks-crud-axios-api/"&gt;React Hooks CRUD example to consume Web API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/react-table-example-hooks-crud/"&gt;React Table example: CRUD App with react-table v7&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/react-material-ui-examples-crud/"&gt;React Material UI examples with a CRUD Application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/react-jwt-auth/"&gt;React JWT Authentication &amp;amp; Authorization example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/react-redux-jwt-auth/"&gt;React + Redux: JWT Authentication &amp;amp; Authorization example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the code base above, we put the React project in &lt;strong&gt;bezkoder-ui&lt;/strong&gt; folder and do some work.&lt;/p&gt;

&lt;p&gt;Firstly, let's remove &lt;em&gt;.env&lt;/em&gt; file because we're gonna work with environment variable from Docker.&lt;/p&gt;

&lt;p&gt;Then we open &lt;em&gt;http-common.js&lt;/em&gt; for updating &lt;code&gt;baseURL&lt;/code&gt; of axios instance with &lt;code&gt;process.env.REACT_APP_API_BASE_URL&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REACT_APP_API_BASE_URL&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:8080/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;Create Dockerfile for React App&lt;/h2&gt;

&lt;p&gt;We're gonna deploy the React app behind an Nginx server.&lt;/p&gt;

&lt;p&gt;Same as Nodejs, we put Dockerfile inside &lt;strong&gt;bezkoder-ui&lt;/strong&gt; folder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bezkoder-upi&lt;/strong&gt;/&lt;em&gt;Dockerfile&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stage 1
&lt;/span&gt;&lt;span class="err"&gt;FROM&lt;/span&gt; &lt;span class="py"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;14 as build-stage&lt;/span&gt;

&lt;span class="err"&gt;WORKDIR&lt;/span&gt; &lt;span class="err"&gt;/bezkoder-ui&lt;/span&gt;
&lt;span class="err"&gt;COPY&lt;/span&gt; &lt;span class="err"&gt;package.json&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;RUN&lt;/span&gt; &lt;span class="err"&gt;npm&lt;/span&gt; &lt;span class="err"&gt;install&lt;/span&gt;
&lt;span class="err"&gt;COPY&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;

&lt;span class="err"&gt;ARG&lt;/span&gt; &lt;span class="err"&gt;REACT_APP_API_BASE_URL&lt;/span&gt;
&lt;span class="err"&gt;ENV&lt;/span&gt; &lt;span class="py"&gt;REACT_APP_API_BASE_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$REACT_APP_API_BASE_URL&lt;/span&gt;

&lt;span class="err"&gt;RUN&lt;/span&gt; &lt;span class="err"&gt;npm&lt;/span&gt; &lt;span class="err"&gt;run&lt;/span&gt; &lt;span class="err"&gt;build&lt;/span&gt;

&lt;span class="c"&gt;# Stage 2
&lt;/span&gt;&lt;span class="err"&gt;FROM&lt;/span&gt; &lt;span class="py"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;1.17.0-alpine&lt;/span&gt;

&lt;span class="err"&gt;COPY&lt;/span&gt; &lt;span class="py"&gt;--from&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;build-stage /bezkoder-ui/build /usr/share/nginx/html&lt;/span&gt;
&lt;span class="err"&gt;EXPOSE&lt;/span&gt; &lt;span class="err"&gt;$REACT_DOCKER_PORT&lt;/span&gt;

&lt;span class="err"&gt;CMD&lt;/span&gt; &lt;span class="err"&gt;nginx&lt;/span&gt; &lt;span class="err"&gt;-g&lt;/span&gt; &lt;span class="err"&gt;'daemon&lt;/span&gt; &lt;span class="err"&gt;off;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two stage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Stage 1: Build the React application&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;FROM&lt;/code&gt;: install the image of the Node.js version.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WORKDIR&lt;/code&gt;: path of the working directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;COPY&lt;/code&gt;: copy &lt;em&gt;package.json&lt;/em&gt; file to the container, then the second one copies all the files inside the project directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RUN&lt;/code&gt;: execute a command-line inside the container: &lt;code&gt;npm install&lt;/code&gt; to install the dependencies in &lt;em&gt;package.json&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ARG&lt;/code&gt; and &lt;code&gt;ENV&lt;/code&gt;: get argument and set environment variable (prefix &lt;code&gt;REACT_APP_&lt;/code&gt; is required).&lt;/li&gt;
&lt;li&gt;run script &lt;code&gt;npm run build&lt;/code&gt; after the image is built, the product will be stored in &lt;strong&gt;build&lt;/strong&gt; folder.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Stage 2: Serve the React application with Nginx&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;install the image of the &lt;strong&gt;nginx&lt;/strong&gt; alpine version.&lt;/li&gt;
&lt;li&gt;copy the react build from Stage 1 into &lt;code&gt;/usr/share/nginx/html&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;expose port (should be &lt;code&gt;80&lt;/code&gt;) to the Docker host.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;daemon off;&lt;/code&gt; directive tells Nginx to stay in the foreground.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Write Docker Compose for MERN application&lt;/h2&gt;

&lt;p&gt;On the root of the project directory, we're gonna create the &lt;em&gt;docker-compose.yml&lt;/em&gt; file for the MERN stack. Follow &lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/"&gt;version 3&lt;/a&gt; syntax defined by Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'3.8'&lt;/span&gt;

&lt;span class="py"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="s"&gt;mongodb:&lt;/span&gt;
    &lt;span class="py"&gt;bezkoder-api&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;bezkoder-ui&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="py"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;version&lt;/code&gt;: Docker Compose file format version will be used.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;services&lt;/code&gt;: individual services in isolated containers. Our application has three services: &lt;code&gt;bezkoder-ui&lt;/code&gt; (React), &lt;code&gt;bezkoder-api&lt;/code&gt; (Nodejs) and &lt;code&gt;mongodb&lt;/code&gt; (MongoDB database).&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;&lt;a href="https://docs.docker.com/storage/volumes/"&gt;volumes&lt;/a&gt;&lt;/code&gt;: named volumes that keeps our data alive after restart.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;&lt;a href="https://docs.docker.com/network/"&gt;networks&lt;/a&gt;&lt;/code&gt;: facilitate communication between containers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's implement the details.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;docker-compose.yml&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'3.8'&lt;/span&gt;

&lt;span class="py"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="py"&gt;mongodb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:5.0.2&lt;/span&gt;
    &lt;span class="py"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="py"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.env&lt;/span&gt;
    &lt;span class="py"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;MONGO_INITDB_ROOT_USERNAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_USER&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;MONGO_INITDB_ROOT_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_PASSWORD&lt;/span&gt;
    &lt;span class="py"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;MONGODB_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;/data/db&lt;/span&gt;
    &lt;span class="py"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;backend&lt;/span&gt;

  &lt;span class="py"&gt;bezkoder-api&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;mongodb&lt;/span&gt;
    &lt;span class="py"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./bezkoder-api&lt;/span&gt;
    &lt;span class="py"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="py"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.env&lt;/span&gt;
    &lt;span class="py"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;NODE_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;$NODE_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_HOST&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;mongodb&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_USER&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_PASSWORD&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_DATABASE&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;DB_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$MONGODB_DOCKER_PORT&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;CLIENT_ORIGIN&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$CLIENT_ORIGIN&lt;/span&gt;
    &lt;span class="py"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;backend&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;frontend&lt;/span&gt;

  &lt;span class="py"&gt;bezkoder-ui&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="py"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;bezkoder-api&lt;/span&gt;
    &lt;span class="py"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="py"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./bezkoder-ui&lt;/span&gt;
      &lt;span class="py"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="py"&gt;REACT_APP_API_BASE_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$CLIENT_API_BASE_URL&lt;/span&gt;
    &lt;span class="py"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;REACT_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;$REACT_DOCKER_PORT&lt;/span&gt;
    &lt;span class="py"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;frontend&lt;/span&gt;  

&lt;span class="py"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
  &lt;span class="s"&gt;db:&lt;/span&gt;

&lt;span class="py"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="py"&gt;backend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="py"&gt;frontend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;mongodb&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;image&lt;/code&gt;: official Docker image&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;restart&lt;/code&gt;: configure the &lt;a href="https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy"&gt;restart policy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;env_file&lt;/code&gt;: specify our &lt;em&gt;.env&lt;/em&gt; path that we will create later&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment&lt;/code&gt;: provide setting using environment variables&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ports&lt;/code&gt;: specify ports will be used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;volumes&lt;/code&gt;: map volume folders&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;networks&lt;/code&gt;: join &lt;code&gt;backend&lt;/code&gt; network&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;bezkoder-api&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#depends_on"&gt;depends_on&lt;/a&gt;&lt;/code&gt;: dependency order, &lt;strong&gt;mongodb&lt;/strong&gt; service is started before &lt;strong&gt;bezkoder-api&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt;: configuration options that are applied at build time that we defined in the &lt;em&gt;Dockerfile&lt;/em&gt; with relative path&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment&lt;/code&gt;: environmental variables that Node application uses&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;networks&lt;/code&gt;: join both &lt;code&gt;backend&lt;/code&gt; and &lt;code&gt;frontent&lt;/code&gt; networks&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;bezkoder-ui&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;depends_on&lt;/code&gt;: start after &lt;code&gt;bezkoder-api&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build-args&lt;/code&gt;: add build arguments - environment variables accessible only during the build process&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;networks&lt;/code&gt;: join only &lt;code&gt;frontent&lt;/code&gt; network&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should note that the host port (&lt;code&gt;LOCAL_PORT&lt;/code&gt;) and the container port (&lt;code&gt;DOCKER_PORT&lt;/code&gt;) is different. Networked service-to-service communication uses the container port, and the outside uses the host port.&lt;/p&gt;

&lt;h2&gt;Docker Compose Environment variables&lt;/h2&gt;

&lt;p&gt;In the service configuration, we used environmental variables defined inside the &lt;em&gt;.env&lt;/em&gt; file. Now we start writing it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;.env&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;MONGODB_USER&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;123456&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_DATABASE&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;bezkoder_db&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;7017&lt;/span&gt;
&lt;span class="py"&gt;MONGODB_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;27017&lt;/span&gt;

&lt;span class="py"&gt;NODE_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;6868&lt;/span&gt;
&lt;span class="py"&gt;NODE_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;

&lt;span class="py"&gt;CLIENT_ORIGIN&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://127.0.0.1:8888&lt;/span&gt;
&lt;span class="py"&gt;CLIENT_API_BASE_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://127.0.0.1:6868/api&lt;/span&gt;

&lt;span class="py"&gt;REACT_LOCAL_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8888&lt;/span&gt;
&lt;span class="py"&gt;REACT_DOCKER_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;Run MERN stack with Docker Compose&lt;/h2&gt;

&lt;p&gt;We can easily run the whole with only a single command:&lt;br&gt;
&lt;code&gt;docker-compose up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Docker will pull the MongoDB and Node.js images (if our machine does not have it before).&lt;/p&gt;

&lt;p&gt;The services can be run on the background with command:&lt;br&gt;
&lt;code&gt;docker-compose up -d&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
Creating network &lt;span class="s2"&gt;"react-node-mongodb_backend"&lt;/span&gt; with the default driver
Creating network &lt;span class="s2"&gt;"react-node-mongodb_frontend"&lt;/span&gt; with the default driver
Creating volume &lt;span class="s2"&gt;"react-node-mongodb_db"&lt;/span&gt; with default driver
Pulling mongodb &lt;span class="o"&gt;(&lt;/span&gt;mongo:5.0.2&lt;span class="o"&gt;)&lt;/span&gt;...
5.0.2: Pulling from library/mongo
16ec32c2132b: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;6335cf672677: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;cbc70ccc8ebe: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;0d1a3c6bd417: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;960f3b9b27d3: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;aff995a136b4: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;4249be7550a8: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;cc105ff5aa3c: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;82819807d07a: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;81447d2c233f: Pull &lt;span class="nb"&gt;complete
&lt;/span&gt;Digest: sha256:93ea50c5f15f9814870b3509449d327c5bc4d38f2b17c20acec528472811a723
Status: Downloaded newer image &lt;span class="k"&gt;for &lt;/span&gt;mongo:5.0.2
Building bezkoder-api
Sending build context to Docker daemon  20.48kB
Step 1/6 : FROM node:14
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 256d6360f157
Step 2/6 : WORKDIR /bezkoder-api
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;630b36161cfc
Removing intermediate container 630b36161cfc
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; cce099c5509c
Step 3/6 : COPY package.json &lt;span class="nb"&gt;.&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 966883cd8e24
Step 4/6 : RUN npm &lt;span class="nb"&gt;install&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;246256e84187
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN node-express-mongodb@1.0.0 No repository field.

added 82 packages from 128 contributors and audited 82 packages &lt;span class="k"&gt;in &lt;/span&gt;8.017s

2 packages are looking &lt;span class="k"&gt;for &lt;/span&gt;funding
  run &lt;span class="sb"&gt;`&lt;/span&gt;npm fund&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;details

found 0 vulnerabilities

Removing intermediate container 246256e84187
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; bdab72a5d37b
Step 5/6 : COPY &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; e9069d0ee44a
Step 6/6 : CMD npm start
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;6f63286cae18
Removing intermediate container 6f63286cae18
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 65452914f005
Successfully built 65452914f005
Successfully tagged react-node-mongodb_bezkoder-api:latest
WARNING: Image &lt;span class="k"&gt;for &lt;/span&gt;service bezkoder-api was built because it did not already exist. To rebuild this image you must use &lt;span class="sb"&gt;`&lt;/span&gt;docker-compose build&lt;span class="sb"&gt;`&lt;/span&gt; or &lt;span class="sb"&gt;`&lt;/span&gt;docker-compose up &lt;span class="nt"&gt;--build&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Building bezkoder-ui
Sending build context to Docker daemon  67.07kB
Step 1/12 : FROM node:14 as build-stage
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 256d6360f157
Step 2/12 : WORKDIR /bezkoder-ui
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;e135a434b996
Removing intermediate container e135a434b996
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 80292facc18b
Step 3/12 : COPY package.json &lt;span class="nb"&gt;.&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 595fbe352edd
Step 4/12 : RUN npm &lt;span class="nb"&gt;install&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;9d8ef80ff165

added 1661 packages from 793 contributors and audited 1666 packages &lt;span class="k"&gt;in &lt;/span&gt;115.944s

94 packages are looking &lt;span class="k"&gt;for &lt;/span&gt;funding
  run &lt;span class="sb"&gt;`&lt;/span&gt;npm fund&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;details

found 10 vulnerabilities &lt;span class="o"&gt;(&lt;/span&gt;1 low, 5 moderate, 4 high&lt;span class="o"&gt;)&lt;/span&gt;
  run &lt;span class="sb"&gt;`&lt;/span&gt;npm audit fix&lt;span class="sb"&gt;`&lt;/span&gt; to fix them, or &lt;span class="sb"&gt;`&lt;/span&gt;npm audit&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;details
Removing intermediate container 9d8ef80ff165
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 18a4f1382bc7
Step 5/12 : COPY &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; f99e2a8ef053
Step 6/12 : ARG REACT_APP_API_BASE_URL
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;47dca1457fb2
Removing intermediate container 47dca1457fb2
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 8986f1482c8d
Step 7/12 : ENV &lt;span class="nv"&gt;REACT_APP_API_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$REACT_APP_API_BASE_URL&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;95687ba2d936
Removing intermediate container 95687ba2d936
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 7a20778bca2b
Step 8/12 : RUN npm run build
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;d0074ed04394

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; react-crud@0.1.0 build /bezkoder-ui
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; react-scripts build

Creating an optimized production build...
Compiled successfully.

File sizes after &lt;span class="nb"&gt;gzip&lt;/span&gt;:

  52.78 KB  build/static/js/2.c9e8967b.chunk.js
  22.71 KB  build/static/css/2.fa6c921b.chunk.css
  2.39 KB   build/static/js/main.aae2fe51.chunk.js
  776 B     build/static/js/runtime-main.99b514f4.js
  144 B     build/static/css/main.9c6cdb86.chunk.css

The project was built assuming it is hosted at /.
You can control this with the homepage field &lt;span class="k"&gt;in &lt;/span&gt;your package.json.

The build folder is ready to be deployed.
You may serve it with a static server:

  npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; serve
  serve &lt;span class="nt"&gt;-s&lt;/span&gt; build

Find out more about deployment here:

  bit.ly/CRA-deploy

Removing intermediate container d0074ed04394
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 9cd424a1901b
Step 9/12 : FROM nginx:1.17.0-alpine
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; bfba26ca350c
Step 10/12 : COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;build-stage /bezkoder-ui/build /usr/share/nginx/html
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 2b4cbdbd908e
Step 11/12 : EXPOSE &lt;span class="nv"&gt;$REACT_DOCKER_PORT&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;ced23b1795d6
Removing intermediate container ced23b1795d6
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 2850341d70f0
Step 12/12 : CMD nginx &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'daemon off;'&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Running &lt;span class="k"&gt;in &lt;/span&gt;d596e17eec46
Removing intermediate container d596e17eec46
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; fef41917c48b
Successfully built fef41917c48b
Successfully tagged react-node-mongodb_bezkoder-ui:latest
WARNING: Image &lt;span class="k"&gt;for &lt;/span&gt;service bezkoder-ui was built because it did not already exist. To rebuild this image you must use &lt;span class="sb"&gt;`&lt;/span&gt;docker-compose build&lt;span class="sb"&gt;`&lt;/span&gt; or &lt;span class="sb"&gt;`&lt;/span&gt;docker-compose up &lt;span class="nt"&gt;--build&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Creating react-node-mongodb_mongodb_1 ... &lt;span class="k"&gt;done
&lt;/span&gt;Creating react-node-mongodb_bezkoder-api_1 ... &lt;span class="k"&gt;done
&lt;/span&gt;Creating react-node-mongodb_bezkoder-ui_1  ... &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can check the current working containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker ps
CONTAINER ID   IMAGE                             COMMAND                  CREATED        STATUS         PORTS                                         NAMES
c9ee5ce3c370   react-node-mongodb_bezkoder-ui    &lt;span class="s2"&gt;"/bin/sh -c 'nginx -…"&lt;/span&gt;   Up 2 minutes   Up 2 minutes   0.0.0.0:8888-&amp;gt;80/tcp, :::8888-&amp;gt;80/tcp         react-node-mongodb_bezkoder-ui_1
f0c7d4174bdb   react-node-mongodb_bezkoder-api   &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   Up 2 minutes   Up 2 minutes   0.0.0.0:6868-&amp;gt;8080/tcp, :::6868-&amp;gt;8080/tcp     react-node-mongodb_bezkoder-api_1
2f8390fc81dd   mongo:5.0.2                       &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   Up 2 minutes   Up 2 minutes   0.0.0.0:7017-&amp;gt;27017/tcp, :::7017-&amp;gt;27017/tcp   react-node-mongodb_mongodb_1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And Docker images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker images
REPOSITORY                        TAG      IMAGE ID       CREATED         SIZE
react-node-mongodb_bezkoder-ui    latest   fef41917c48b   3 minutes ago   22MB
react-node-mongodb_bezkoder-api   latest   65452914f005   6 minutes ago   961MB
mongo                             5.0.2    269b735e72cb   7 minutes ago   682MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test the React UI:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PCCJsSuk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.bezkoder.com/wp-content/uploads/2021/05/docker-mern-nginx-example-test-ui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PCCJsSuk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.bezkoder.com/wp-content/uploads/2021/05/docker-mern-nginx-example-test-ui.png" alt="docker-mern-nginx-example-test-ui" width="680" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MongoDB Database:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A5NWZsoU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.bezkoder.com/wp-content/uploads/2021/05/docker-mern-nginx-example-test-database.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A5NWZsoU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.bezkoder.com/wp-content/uploads/2021/05/docker-mern-nginx-example-test-database.png" alt="docker-mern-nginx-example-test-database" width="580" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And Node.js Express API:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OsajTGD_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.bezkoder.com/wp-content/uploads/2021/05/docker-mern-nginx-example-test-api.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OsajTGD_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.bezkoder.com/wp-content/uploads/2021/05/docker-mern-nginx-example-test-api.png" alt="docker-mern-nginx-example-test-api" width="513" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Stop the Application&lt;/h2&gt;

&lt;p&gt;Stopping all the running containers is also simple with a single command:&lt;br&gt;
&lt;code&gt;docker-compose down&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose down
Stopping react-node-mongodb_bezkoder-ui_1  ... &lt;span class="k"&gt;done
&lt;/span&gt;Stopping react-node-mongodb_bezkoder-api_1 ... &lt;span class="k"&gt;done
&lt;/span&gt;Stopping react-node-mongodb_mongodb_1      ... &lt;span class="k"&gt;done
&lt;/span&gt;Removing react-node-mongodb_bezkoder-ui_1  ... &lt;span class="k"&gt;done
&lt;/span&gt;Removing react-node-mongodb_bezkoder-api_1 ... &lt;span class="k"&gt;done
&lt;/span&gt;Removing react-node-mongodb_mongodb_1      ... &lt;span class="k"&gt;done
&lt;/span&gt;Removing network react-node-mongodb_backend
Removing network react-node-mongodb_frontend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to stop and remove all containers, networks, and all images used by any service in &lt;em&gt;docker-compose.yml&lt;/em&gt; file, use the command:&lt;br&gt;
&lt;code&gt;docker-compose down --rmi all&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;Today we've successfully created MERN application with Docker and Nginx. Now we can deploy MERN stack: React + Nodejs Express and MongoDB on a very simple way: &lt;em&gt;docker-compose.yml&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can apply this way to one of following project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/react-node-express-mongodb-mern-stack/"&gt;React + Node.js + Express + MongoDB example: CRUD App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/react-node-mongodb-auth/"&gt;React + Node.js Express + MongoDB: User Authentication with JWT example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Learning! See you again.&lt;/p&gt;

&lt;h2&gt;Source Code&lt;/h2&gt;

&lt;p&gt;The source code for this tutorial can be found at &lt;a href="https://github.com/bezkoder/docker-mern-nginx"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>docker</category>
      <category>devops</category>
    </item>
    <item>
      <title>JPA @ManyToOne example in Spring Boot</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Mon, 07 Aug 2023 01:26:10 +0000</pubDate>
      <link>https://forem.com/tienbku/jpa-manytoone-example-in-spring-boot-3n97</link>
      <guid>https://forem.com/tienbku/jpa-manytoone-example-in-spring-boot-3n97</guid>
      <description>&lt;p&gt;In this tutorial, I will show you how to implement Spring Data JPA Many-to-One example in Spring Boot for One-To-Many mapping using &lt;code&gt;@ManyToOne&lt;/code&gt; annotation. You'll know:&lt;/p&gt;

&lt;ul&gt;
        &lt;li&gt;How to configure Spring Data, JPA, Hibernate to work with Database&lt;/li&gt;
        &lt;li&gt;How to define Data Models and Repository interfaces for JPA One-To-Many relationship using &lt;code&gt;@ManyToOne&lt;/code&gt;
&lt;/li&gt;
    &lt;li&gt;Way to use Spring JPA to interact with Database for Many-to-One association&lt;/li&gt;
    &lt;li&gt;Way to create Spring Rest Controller to process HTTP requests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Related Posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/jpa-one-to-one/" rel="noopener noreferrer"&gt;JPA One To One example with Hibernate in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/jpa-many-to-many/" rel="noopener noreferrer"&gt;JPA Many to Many example with Hibernate in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-validate-request-body/" rel="noopener noreferrer"&gt;Validate Request Body in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-jwt-authentication/" rel="noopener noreferrer"&gt;Spring Boot Token based Authentication with Spring Security &amp;amp; JWT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-jpa-h2-example/" rel="noopener noreferrer"&gt;Spring JPA + H2 example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-jpa-crud-rest-api/" rel="noopener noreferrer"&gt;Spring JPA + MySQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-postgresql-example/" rel="noopener noreferrer"&gt;Spring JPA + PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-hibernate-oracle/" rel="noopener noreferrer"&gt;Spring JPA + Oracle example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-sql-server/" rel="noopener noreferrer"&gt;Spring JPA + SQL Server example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Documentation: &lt;a href="https://www.bezkoder.com/spring-boot-swagger-3/" rel="noopener noreferrer"&gt;Spring Boot Swagger 3 example&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Caching: &lt;a href="https://www.bezkoder.com/spring-boot-redis-cache-example/" rel="noopener noreferrer"&gt;Spring Boot Redis Cache example&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;span id="Way"&gt;JPA @ManyToOne is appropriate way for One To Many mapping in Spring&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;In a relational database, a One-to-Many relationship between table A and table B indicates that one row in table A links to many rows in table B, but one row in table B links to only one row in table A.&lt;/p&gt;

&lt;p&gt;For example, you need to design data model for a Tutorial Blog in which &lt;strong&gt;One&lt;/strong&gt; Tutorial has &lt;strong&gt;Many&lt;/strong&gt; Comments. So this is a One-to-Many association.&lt;/p&gt;

&lt;p&gt;You can map the child entities as a collection (List of &lt;code&gt;Comment&lt;/code&gt;s) in the parent object (&lt;code&gt;Tutorial&lt;/code&gt;), and JPA/Hibernate provides the &lt;a href="https://docs.oracle.com/javaee/7/api/javax/persistence/OneToMany.html" rel="noopener noreferrer"&gt;@OneToMany&lt;/a&gt; annotation for that case: only the parent-side defines the relationship. We call it unidirectional &lt;code&gt;@OneToMany&lt;/code&gt; association.&lt;/p&gt;

&lt;p&gt;For tutorial, please visit: &lt;a href="https://www.bezkoder.com/jpa-one-to-many-unidirectional/" rel="noopener noreferrer"&gt;JPA One To Many Unidirectional example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Similarly, when only the child-side manage the relationship, we have unidirectional Many-to-One association with &lt;a href="https://docs.oracle.com/javaee/7/api/javax/persistence/ManyToOne.html" rel="noopener noreferrer"&gt;@ManyToOne&lt;/a&gt; annotation where the child (&lt;code&gt;Comment&lt;/code&gt;) has an entity object reference to its parent entity (&lt;code&gt;Tutorial&lt;/code&gt;) by mapping the Foreign Key column (&lt;code&gt;tutorial_id&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The most appropriate way to implement JPA/Hibernate One To Many mapping is unidirectional Many-to-One association with &lt;a href="https://docs.oracle.com/javaee/7/api/javax/persistence/ManyToOne.html" rel="noopener noreferrer"&gt;@ManyToOne&lt;/a&gt; because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With &lt;code&gt;@OneToMany&lt;/code&gt;, we need to declare a collection (Comments) inside parent class (Tutorial), we cannot limit the size of that collection, for example, in case of pagination.&lt;/li&gt;
&lt;li&gt;With &lt;code&gt;@ManyToOne&lt;/code&gt;, you can modify the Repository:
&lt;ul&gt;
&lt;li&gt;to work with Pagination&lt;/li&gt;
&lt;li&gt;or to sort/order by multiple fields&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;&lt;span id="JPA_Many_to_One"&gt;JPA ManyToOne example&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;We're gonna create a Spring project from scratch, then we implement JPA/Hibernate Many to One Mapping with &lt;code&gt;tutorials&lt;/code&gt; and &lt;code&gt;comments&lt;/code&gt; table as following:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-many-to-one-diagram.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-many-to-one-diagram.png" alt="jpa-many-to-one-diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We also write Rest Apis to perform CRUD operations on the Comment entities.&lt;/p&gt;

&lt;p&gt;These are APIs that we need to provide:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Methods&lt;/th&gt;
&lt;th&gt;Urls&lt;/th&gt;
&lt;th&gt;Actions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/api/tutorials/:id/comments&lt;/td&gt;
&lt;td&gt;create new Comment for a Tutorial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/api/tutorials/:id/comments&lt;/td&gt;
&lt;td&gt;retrieve all Comments of a Tutorial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/api/comments/:id&lt;/td&gt;
&lt;td&gt;retrieve a Comment by &lt;code&gt;:id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;/api/comments/:id&lt;/td&gt;
&lt;td&gt;update a Comment by &lt;code&gt;:id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;/api/comments/:id&lt;/td&gt;
&lt;td&gt;delete a Comment by &lt;code&gt;:id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;/api/tutorials/:id&lt;/td&gt;
&lt;td&gt;delete a Tutorial (and its Comments) by &lt;code&gt;:id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;/api/tutorials/:id/comments&lt;/td&gt;
&lt;td&gt;delete all Comments of a Tutorial&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Assume that we've had &lt;strong&gt;tutorials&lt;/strong&gt; table 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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-parent-table.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-parent-table.png" alt="jpa-manytoone-parent-table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are the example requests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create new Comments: POST &lt;code&gt;/api/tutorials/[:id]/comments&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-create-child-entity.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-create-child-entity.png" alt="jpa-manytoone-example-create-child-entity"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;comments&lt;/strong&gt; table after that:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-child-table.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-child-table.png" alt="jpa-manytoone-child-table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieve all Comments of specific Tutorial: GET &lt;code&gt;/api/tutorials/[:id]/comments&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-retrieve.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-retrieve.png" alt="jpa-manytoone-example-spring-crud-retrieve"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete all Comments of specific Tutorial: DELETE &lt;code&gt;/api/tutorials/[:id]/comments&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-delete.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-delete.png" alt="jpa-manytoone-example-spring-crud-delete"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check the &lt;strong&gt;comment&lt;/strong&gt; table, all Comments of Tutorial with id=2 were deleted:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-table-delete.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-table-delete.png" alt="jpa-manytoone-example-spring-crud-table-delete"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete a Tutorial: DELETE &lt;code&gt;/api/tutorials/[:id]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-delete-cascade.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-delete-cascade.png" alt="jpa-manytoone-example-spring-crud-delete-cascade"&gt;&lt;/a&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-delete-parent-table.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-delete-parent-table.png" alt="jpa-manytoone-example-spring-crud-delete-parent-table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All Comments of the Tutorial with id=3 were &lt;strong&gt;CASCADE&lt;/strong&gt; deleted automatically.&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-delete-cascade-table.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-spring-crud-delete-cascade-table.png" alt="jpa-manytoone-example-spring-crud-delete-cascade-table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's build our Spring Boot @ManyToOne CRUD example.&lt;/p&gt;

&lt;h2&gt;&lt;span id="Spring_Boot_Many_to_One"&gt;Spring Boot ManyToOne example&lt;/span&gt;&lt;/h2&gt;

&lt;h3&gt;&lt;span id="Technology"&gt;Technology&lt;/span&gt;&lt;/h3&gt;

&lt;ul&gt;
        &lt;li&gt;Java 17 / 11 / 8&lt;/li&gt;
        &lt;li&gt;Spring Boot 3 / 2 (with Spring Web MVC, Spring Data JPA)&lt;/li&gt;
        &lt;li&gt;H2/PostgreSQL/MySQL&lt;/li&gt;
        &lt;li&gt;Maven&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;&lt;span id="Project_Structure"&gt;Project Structure&lt;/span&gt;&lt;/h3&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-hibernate-spring-boot-project-structure.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-example-hibernate-spring-boot-project-structure.png" alt="jpa-manytoone-example-hibernate-spring-boot-project-structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me explain it briefly.&lt;/p&gt;

&lt;p&gt;– &lt;code&gt;Tutorial&lt;/code&gt;, &lt;code&gt;Comment&lt;/code&gt; data model class correspond to entity and table &lt;em&gt;tutorials&lt;/em&gt;, &lt;em&gt;comments&lt;/em&gt;.&lt;br&gt;
– &lt;code&gt;TutorialRepository&lt;/code&gt;, &lt;code&gt;CommentRepository&lt;/code&gt; are interfaces that extends &lt;a href="https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html" rel="noopener noreferrer"&gt;JpaRepository&lt;/a&gt; for CRUD methods and custom finder methods. It will be autowired in &lt;code&gt;TutorialController&lt;/code&gt;, &lt;code&gt;CommentController&lt;/code&gt;.&lt;br&gt;
– &lt;code&gt;TutorialController&lt;/code&gt;, &lt;code&gt;CommentController&lt;/code&gt; are &lt;a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RestController.html" rel="noopener noreferrer"&gt;RestController&lt;/a&gt;s which has request mapping methods for RESTful CRUD API requests.&lt;br&gt;
– Configuration for Spring Datasource, JPA &amp;amp; Hibernate in &lt;strong&gt;application.properties&lt;/strong&gt;.&lt;br&gt;
– &lt;strong&gt;pom.xml&lt;/strong&gt; contains dependencies for Spring Boot and MySQL/PostgreSQL/H2 database.&lt;/p&gt;

&lt;p&gt;– About &lt;strong&gt;exception&lt;/strong&gt; package, to keep this post straightforward, I won't explain it. For more details, you can read following tutorial:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-boot-restcontrolleradvice/" rel="noopener noreferrer"&gt;@RestControllerAdvice example in Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;&lt;span id="Setup"&gt;Create &amp;amp; Setup Spring Boot project&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;Use &lt;a href="http://start.spring.io/" rel="noopener noreferrer"&gt;Spring web tool&lt;/a&gt; or your development tool (&lt;a href="https://spring.io/tools" rel="noopener noreferrer"&gt;Spring Tool Suite&lt;/a&gt;, Eclipse, &lt;a href="https://www.jetbrains.com/idea/download/" rel="noopener noreferrer"&gt;Intellij&lt;/a&gt;) to create a Spring Boot project.&lt;/p&gt;

&lt;p&gt;Then open &lt;strong&gt;pom.xml&lt;/strong&gt; and add these dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&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;org.springframework.boot&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;spring-boot-starter-data-jpa&lt;span class="nt"&gt;&amp;lt;/artifactId&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;org.springframework.boot&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;spring-boot-starter-web&lt;span class="nt"&gt;&amp;lt;/artifactId&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;p&gt;We also need to add one more dependency.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you want to use &lt;strong&gt;MySQL&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&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;com.mysql&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;mysql-connector-j&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&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;ul&gt;
&lt;li&gt;or &lt;strong&gt;PostgreSQL&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&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;org.postgresql&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;postgresql&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&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;ul&gt;
&lt;li&gt;or &lt;strong&gt;H2&lt;/strong&gt; (embedded database):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&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;com.h2database&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;h2&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&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;h3&gt;&lt;span id="Configuration"&gt;Configure Spring Datasource, JPA, Hibernate&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;Under src/main/resources folder, open application.properties and write these lines.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For MySQL:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;spring.datasource.url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;jdbc:mysql://localhost:3306/testdb?useSSL=false&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.username&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.password&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;123456&lt;/span&gt;

&lt;span class="py"&gt;spring.jpa.properties.hibernate.dialect&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;org.hibernate.dialect.MySQLDialect&lt;/span&gt;

&lt;span class="c"&gt;# Hibernate ddl auto (create, create-drop, validate, update)
&lt;/span&gt;&lt;span class="py"&gt;spring.jpa.hibernate.ddl-auto&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;update&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;For PostgreSQL:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;spring.datasource.url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;jdbc:postgresql://localhost:5432/testdb&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.username&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.password&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;123&lt;/span&gt;

&lt;span class="py"&gt;spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;spring.jpa.properties.hibernate.dialect&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;org.hibernate.dialect.PostgreSQLDialect&lt;/span&gt;

&lt;span class="c"&gt;# Hibernate ddl auto (create, create-drop, validate, update)
&lt;/span&gt;&lt;span class="py"&gt;spring.jpa.hibernate.ddl-auto&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;update&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;spring.datasource.username&lt;/code&gt; &amp;amp; &lt;code&gt;spring.datasource.password&lt;/code&gt; properties are the same as your database installation.&lt;/li&gt;
    &lt;li&gt;Spring Boot uses Hibernate for JPA implementation, we configure &lt;code&gt;MySQLDialect&lt;/code&gt; for MySQL or &lt;code&gt;PostgreSQLDialect&lt;/code&gt; for PostgreSQL&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;spring.jpa.hibernate.ddl-auto&lt;/code&gt; is used for database initialization. We set the value to &lt;code&gt;update&lt;/code&gt; value so that a table will be created in the database automatically corresponding to defined data model. Any change to the model will also trigger an update to the table. For production, this property should be &lt;code&gt;validate&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
&lt;li&gt;For H2 database:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;spring.datasource.url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;jdbc:h2:mem:testdb&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.driverClassName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;org.h2.Driver&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.username&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;sa&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.password&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;

&lt;span class="py"&gt;spring.jpa.show-sql&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;spring.jpa.properties.hibernate.dialect&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;org.hibernate.dialect.H2Dialect&lt;/span&gt;
&lt;span class="py"&gt;spring.jpa.hibernate.ddl-auto&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;update&lt;/span&gt;

&lt;span class="py"&gt;spring.h2.console.enabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="c"&gt;# default path: h2-console
&lt;/span&gt;&lt;span class="py"&gt;spring.h2.console.path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/h2-ui&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;spring.datasource.url&lt;/code&gt;: &lt;code&gt;jdbc:h2:mem:[database-name]&lt;/code&gt; for In-memory database and &lt;code&gt;jdbc:h2:file:[path/database-name]&lt;/code&gt; for disk-based database.&lt;/li&gt;
    &lt;li&gt;We configure &lt;code&gt;H2Dialect&lt;/code&gt; for H2 Database&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;spring.h2.console.enabled=true&lt;/code&gt; tells the Spring to start H2 Database administration tool and you can access this tool on the browser: &lt;code&gt;http://localhost:8080/h2-console&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;spring.h2.console.path=/h2-ui&lt;/code&gt; is for H2 console's url, so the default url &lt;code&gt;http://localhost:8080/h2-console&lt;/code&gt; will change to &lt;code&gt;http://localhost:8080/h2-ui&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;&lt;span id="Model"&gt;Define Data Model for JPA ManyToOne mapping&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;In &lt;strong&gt;model&lt;/strong&gt; package, we define &lt;code&gt;Tutorial&lt;/code&gt; and &lt;code&gt;Comment&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Tutorial has four fields: id, title, description, published.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;model&lt;/strong&gt;/&lt;em&gt;Tutorial.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.hibernate.onetomany.model&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;jakarta.persistence.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Entity&lt;/span&gt;
&lt;span class="nd"&gt;@Table&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;"tutorials"&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;Tutorial&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Id&lt;/span&gt;
  &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SEQUENCE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"tutorial_generator"&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;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;@Column&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;"title"&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;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Column&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;"description"&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;description&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Column&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;"published"&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;boolean&lt;/span&gt; &lt;span class="n"&gt;published&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;Tutorial&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="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Tutorial&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;title&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;description&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;published&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;title&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="k"&gt;this&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="n"&gt;description&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;published&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;published&lt;/span&gt;&lt;span class="o"&gt;;&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;ul&gt;
&lt;li&gt;
&lt;code&gt;@Entity&lt;/code&gt; annotation indicates that the class is a persistent Java class.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;@Table&lt;/code&gt; annotation provides the table that maps this entity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;@Id&lt;/code&gt; annotation is for the primary key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;@GeneratedValue&lt;/code&gt; annotation is used to define generation strategy for the primary key. &lt;code&gt;GenerationType.SEQUENCE&lt;/code&gt; means using database sequence to generate unique values.&lt;br&gt;
We also indicate the name of the primary key &lt;code&gt;generator&lt;/code&gt;. If you don't give it the name, id value will be generated with &lt;strong&gt;hibernate_sequence&lt;/strong&gt; table (supplied by persistence provider, for all entities) by default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;@Column&lt;/code&gt; annotation is used to define the column in database that maps annotated field.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;Comment&lt;/code&gt; class has the &lt;code&gt;@ManyToOne&lt;/code&gt; annotation for many-to-one relationship with the &lt;code&gt;Tutorial&lt;/code&gt; entity. &lt;code&gt;optional&lt;/code&gt; element is set to &lt;code&gt;false&lt;/code&gt; for non-null relationship.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;model&lt;/strong&gt;/&lt;em&gt;Comment.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.hibernate.onetomany.model&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;jakarta.persistence.*&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.hibernate.annotations.OnDelete&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.hibernate.annotations.OnDeleteAction&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;com.fasterxml.jackson.annotation.JsonIgnore&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Entity&lt;/span&gt;
&lt;span class="nd"&gt;@Table&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;"comments"&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;Comment&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Id&lt;/span&gt;
  &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SEQUENCE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"comment_generator"&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;@Lob&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;content&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@ManyToOne&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FetchType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LAZY&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;optional&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="nd"&gt;@JoinColumn&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;"tutorial_id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&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="nd"&gt;@OnDelete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OnDeleteAction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CASCADE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nd"&gt;@JsonIgnore&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&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;We also use the &lt;a href="https://docs.oracle.com/javaee/7/api/javax/persistence/JoinColumn.html" rel="noopener noreferrer"&gt;@JoinColumn&lt;/a&gt; annotation to specify the foreign key column (&lt;code&gt;tutorial_id&lt;/code&gt;). If you don't provide the &lt;code&gt;JoinColumn&lt;/code&gt; name, the name will be set automatically.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@JsonIgnore&lt;/code&gt; is used to ignore the logical property used in serialization and deserialization.&lt;/p&gt;

&lt;p&gt;We also implement cascade delete capabilities of the foreign-key with &lt;code&gt;@OnDelete(action = OnDeleteAction.CASCADE)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We set the &lt;code&gt;@ManyToOne&lt;/code&gt; with &lt;code&gt;FetchType.LAZY&lt;/code&gt; for &lt;code&gt;fetch&lt;/code&gt; type:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-lazy-fetch.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-lazy-fetch.png" alt="jpa-manytoone-lazy-fetch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By default, the &lt;code&gt;@ManyToOne&lt;/code&gt; association uses &lt;code&gt;FetchType.EAGER&lt;/code&gt; for &lt;code&gt;fetch&lt;/code&gt; type but it is bad for performance:&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="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Comment&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="nd"&gt;@ManyToOne&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FetchType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EAGER&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;optional&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="nd"&gt;@JoinColumn&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;"tutorial_id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&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="nd"&gt;@OnDelete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OnDeleteAction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CASCADE&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;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-eager-fetch.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fjpa-manytoone-eager-fetch.png" alt="jpa-manytoone-eager-fetch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;&lt;span id="Repository"&gt;Create Repository Interfaces for ManyToOne mapping&lt;/span&gt;&lt;/h3&gt;

&lt;p&gt;Let's create a repository to interact with database.&lt;br&gt;
In &lt;strong&gt;repository&lt;/strong&gt; package, create &lt;code&gt;TutorialRepository&lt;/code&gt; and &lt;code&gt;CommentRepository&lt;/code&gt; interfaces that extend &lt;code&gt;JpaRepository&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;repository&lt;/strong&gt;/&lt;em&gt;TutorialRepository.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.hibernate.onetomany.repository&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.data.jpa.repository.JpaRepository&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;com.bezkoder.spring.hibernate.onetomany.model.Tutorial&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;TutorialRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByPublished&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;published&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByTitleContaining&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;title&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;&lt;strong&gt;repository&lt;/strong&gt;/&lt;em&gt;CommentRepository.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.hibernate.onetomany.repository&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.transaction.Transactional&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.data.jpa.repository.JpaRepository&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;com.bezkoder.spring.hibernate.onetomany.model.Comment&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;CommentRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Comment&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;Comment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByTutorialId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;postId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@Transactional&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;deleteByTutorialId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;tutorialId&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;Now we can use JpaRepository's methods: &lt;code&gt;save()&lt;/code&gt;, &lt;code&gt;findOne()&lt;/code&gt;, &lt;code&gt;findById()&lt;/code&gt;, &lt;code&gt;findAll()&lt;/code&gt;, &lt;code&gt;count()&lt;/code&gt;, &lt;code&gt;delete()&lt;/code&gt;, &lt;code&gt;deleteById()&lt;/code&gt;... without implementing these methods.&lt;/p&gt;

&lt;p&gt;We also define custom finder methods:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;
&lt;code&gt;findByPublished()&lt;/code&gt;: returns all Tutorials with &lt;code&gt;published&lt;/code&gt; having value as input &lt;code&gt;published&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;findByTitleContaining()&lt;/code&gt;: returns all Tutorials which title contains input &lt;code&gt;title&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;findByTutorialId()&lt;/code&gt;: returns all Comments of a Tutorial specified by &lt;code&gt;tutorialId&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;deleteByTutorialId()&lt;/code&gt;: deletes all Comments of a Tutorial specified by &lt;code&gt;tutorialId&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The implementation is plugged in by &lt;a href="https://docs.spring.io/spring-data/jpa/docs/current/reference/html/" rel="noopener noreferrer"&gt;Spring Data JPA&lt;/a&gt; automatically.&lt;/p&gt;

&lt;p&gt;Now we can see the pros of &lt;code&gt;@ManyToOne&lt;/code&gt; annotation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With &lt;code&gt;@OneToMany&lt;/code&gt;, we need to declare a collection inside parent class, we cannot limit the size of that collection, for example, in case of pagination.&lt;/li&gt;
&lt;li&gt;With &lt;code&gt;@ManyToOne&lt;/code&gt;, you can modify Repository:
&lt;ul&gt;
&lt;li&gt;to work with Pagination, the instruction can be found at:
&lt;a href="https://bezkoder.com/spring-boot-pagination-filter-jpa-pageable/" rel="noopener noreferrer"&gt;Spring Boot Pagination &amp;amp; Filter example | Spring JPA, Pageable&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;or to sort/order by multiple fields:
&lt;a href="https://bezkoder.com/spring-data-sort-multiple-columns/" rel="noopener noreferrer"&gt;Spring Data JPA Sort/Order by multiple Columns | Spring Boot&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please notice that above tutorials are for &lt;code&gt;TutorialRepository&lt;/code&gt;, you need to apply the same way for &lt;code&gt;CommentRepository&lt;/code&gt; .&lt;/p&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;More Derived queries at:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/jpa-repository-query/" rel="noopener noreferrer"&gt;JPA Repository query example in Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Custom query with &lt;code&gt;@Query&lt;/code&gt; annotation:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-jpa-query/" rel="noopener noreferrer"&gt;Spring JPA @Query example: Custom query in Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You also find way to write Unit Test for this JPA Repository at:&lt;br&gt;
&lt;a href="https://bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for JPA Repository with @DataJpaTest&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span id="Controller"&gt;Create Spring Rest APIs Controller&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;Finally, we create controller that provides APIs for CRUD operations: creating, retrieving, updating, deleting and finding Tutorials and Comments.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;controller/TutorialController.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.hibernate.onetomany.controller&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.ArrayList&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.beans.factory.annotation.Autowired&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.http.HttpStatus&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.http.ResponseEntity&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.CrossOrigin&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.DeleteMapping&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.PostMapping&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.PutMapping&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.RequestBody&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.RequestParam&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;com.bezkoder.spring.hibernate.onetomany.exception.ResourceNotFoundException&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;com.bezkoder.spring.hibernate.onetomany.model.Tutorial&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;com.bezkoder.spring.hibernate.onetomany.repository.TutorialRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@CrossOrigin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;origins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://localhost:8081"&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;"/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;class&lt;/span&gt; &lt;span class="nc"&gt;TutorialController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="nc"&gt;TutorialRepository&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&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;"/tutorials"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getAllTutorials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestParam&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;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;)&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tutorials&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;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if&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="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findAll&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;tutorials:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByTitleContaining&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="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;tutorials:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorials&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&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;NO_CONTENT&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="n"&gt;tutorials&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="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;"/tutorials/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getTutorialById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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="kt"&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="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&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="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not found Tutorial with id = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&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="n"&gt;tutorial&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="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tutorials"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;createTutorial&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;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;_tutorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTitle&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDescription&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="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="n"&gt;_tutorial&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="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;"/tutorials/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;updateTutorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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="kt"&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;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Tutorial&lt;/span&gt; &lt;span class="n"&gt;_tutorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&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="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not found Tutorial with id = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="n"&gt;_tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTitle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTitle&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;_tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDescription&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDescription&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;_tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPublished&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isPublished&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="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_tutorial&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="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;"/tutorials/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;deleteTutorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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="kt"&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="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&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;NO_CONTENT&lt;/span&gt;&lt;span class="o"&gt;);&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;"/tutorials"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;deleteAllTutorials&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteAll&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;NO_CONTENT&lt;/span&gt;&lt;span class="o"&gt;);&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;"/tutorials/published"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByPublished&lt;/span&gt;&lt;span class="o"&gt;()&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;Tutorial&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tutorials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByPublished&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="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorials&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&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;NO_CONTENT&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="n"&gt;tutorials&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="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;&lt;em&gt;controller/CommentController.java&lt;/em&gt;&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;package&lt;/span&gt; &lt;span class="nn"&gt;com.bezkoder.spring.hibernate.onetomany.controller&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="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.beans.factory.annotation.Autowired&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.http.HttpStatus&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.http.ResponseEntity&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.CrossOrigin&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.DeleteMapping&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.PostMapping&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.PutMapping&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.RequestBody&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;com.bezkoder.spring.hibernate.onetomany.exception.ResourceNotFoundException&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;com.bezkoder.spring.hibernate.onetomany.model.Comment&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;com.bezkoder.spring.hibernate.onetomany.repository.CommentRepository&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;com.bezkoder.spring.hibernate.onetomany.repository.TutorialRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@CrossOrigin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;origins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://localhost:8081"&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;"/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;class&lt;/span&gt; &lt;span class="nc"&gt;CommentController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;TutorialRepository&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;CommentRepository&lt;/span&gt; &lt;span class="n"&gt;commentRepository&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;"/tutorials/{tutorialId}/comments"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;Comment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getAllCommentsByTutorialId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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;"tutorialId"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;tutorialId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;existsById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorialId&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not found Tutorial with id = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tutorialId&lt;/span&gt;&lt;span class="o"&gt;);&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;Comment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;comments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;commentRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByTutorialId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorialId&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="n"&gt;comments&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="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;"/comments/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Comment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getCommentsByTutorialId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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"&lt;/span&gt;&lt;span class="o"&gt;)&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="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Comment&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;commentRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&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="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not found Comment with id = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&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="n"&gt;comment&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="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tutorials/{tutorialId}/comments"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Comment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;createComment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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;"tutorialId"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;tutorialId&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;Comment&lt;/span&gt; &lt;span class="n"&gt;commentRequest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Comment&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorialId&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;commentRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTutorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorial&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;commentRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commentRequest&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}).&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not found Tutorial with id = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tutorialId&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="n"&gt;comment&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="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;"/comments/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Comment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;updateComment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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="kt"&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;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;Comment&lt;/span&gt; &lt;span class="n"&gt;commentRequest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Comment&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;commentRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&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="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CommentId "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"not found"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commentRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getContent&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="n"&gt;commentRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comment&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="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;"/comments/{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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;deleteComment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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="kt"&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="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;commentRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&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;NO_CONTENT&lt;/span&gt;&lt;span class="o"&gt;);&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;"/tutorials/{tutorialId}/comments"&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;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;Comment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;deleteAllCommentsOfTutorial&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&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;"tutorialId"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;tutorialId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;tutorialRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;existsById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorialId&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ResourceNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not found Tutorial with id = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tutorialId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;commentRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deleteByTutorialId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tutorialId&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;NO_CONTENT&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;h2&gt;&lt;span id="Conclusion"&gt;Conclusion&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;Today we've built a Spring Boot CRUD example using Spring Data JPA, Hibernate Many To One relationship with MySQL/PostgreSQL/embedded database (H2).&lt;/p&gt;

&lt;p&gt;We also see that &lt;code&gt;@ManyToOne&lt;/code&gt; annotation is the most appropriate way for implementing JPA One To Many Mapping, and &lt;code&gt;JpaRepository&lt;/code&gt; supports a great way to make CRUD operations, custom finder methods without need of boilerplate code.&lt;/p&gt;

&lt;p&gt;Custom query with &lt;code&gt;@Query&lt;/code&gt; annotation:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-jpa-query/" rel="noopener noreferrer"&gt;Spring JPA @Query example: Custom query in Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to add Pagination to this Spring project, you can find the instruction at:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-boot-pagination-filter-jpa-pageable/" rel="noopener noreferrer"&gt;Spring Boot Pagination &amp;amp; Filter example | Spring JPA, Pageable&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To sort/order by multiple fields:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-data-sort-multiple-columns/" rel="noopener noreferrer"&gt;Spring Data JPA Sort/Order by multiple Columns | Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Handle Exception for this Rest APIs is necessary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-controlleradvice-exceptionhandler/" rel="noopener noreferrer"&gt;Spring Boot @ControllerAdvice &amp;amp; @ExceptionHandler example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-restcontrolleradvice/" rel="noopener noreferrer"&gt;@RestControllerAdvice example in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or way to write Unit Test for the JPA Repository:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/spring-boot-unit-test-jpa-repo-datajpatest/" rel="noopener noreferrer"&gt;Spring Boot Unit Test for JPA Repository with @DataJpaTest&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-validate-request-body/" rel="noopener noreferrer"&gt;Validate Request Body in Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;how to deploy this Spring Boot App on AWS (for free) with &lt;a href="https://www.bezkoder.com/deploy-spring-boot-aws-eb/" rel="noopener noreferrer"&gt;this tutorial&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;dockerize with &lt;a href="https://www.bezkoder.com/docker-compose-spring-boot-mysql/" rel="noopener noreferrer"&gt;Docker Compose: Spring Boot and MySQL example&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;way to upload an Excel file and store the data in MySQL database with &lt;a href="https://www.bezkoder.com/spring-boot-upload-excel-file-database/" rel="noopener noreferrer"&gt;this post&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;upload CSV file and store the data in MySQL with &lt;a href="https://www.bezkoder.com/spring-boot-upload-csv-file/" rel="noopener noreferrer"&gt;this post&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy learning! See you again.&lt;/p&gt;

&lt;h2&gt;&lt;span id="Further_Reading"&gt;Further Reading&lt;/span&gt;&lt;/h2&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-jwt-authentication/" rel="noopener noreferrer"&gt;Secure Spring Boot App with Spring Security &amp;amp; JWT Authentication&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#reference" rel="noopener noreferrer"&gt;Spring Data JPA Reference Documentation&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-pagination-sorting-example/" rel="noopener noreferrer"&gt;Spring Boot Pagination and Sorting example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fullstack CRUD App:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-vue-js-crud-example/" rel="noopener noreferrer"&gt;Vue + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-spring-boot-crud/" rel="noopener noreferrer"&gt;Angular 8 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-10-spring-boot-crud/" rel="noopener noreferrer"&gt;Angular 10 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-11-spring-boot-crud/" rel="noopener noreferrer"&gt;Angular 11 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-12-spring-boot-crud/" rel="noopener noreferrer"&gt;Angular 12 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-angular-13-crud/" rel="noopener noreferrer"&gt;Angular 13 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-angular-14-crud/" rel="noopener noreferrer"&gt;Angular 14 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-angular-15-crud/" rel="noopener noreferrer"&gt;Angular 15 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-angular-16-crud/" rel="noopener noreferrer"&gt;Angular 16 + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/react-spring-boot-crud/" rel="noopener noreferrer"&gt;React + Spring Boot example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;span id="Source_Code"&gt;Source Code&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;You can find the complete source code for this tutorial on &lt;a href="https://github.com/bezkoder/spring-boot-one-to-many" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;@OneToMany&lt;/code&gt; instead: &lt;a href="https://www.bezkoder.com/jpa-one-to-many-unidirectional/" rel="noopener noreferrer"&gt;JPA One To Many Unidirectional example&lt;/a&gt;&lt;br&gt;
Many-to-Many: &lt;a href="https://www.bezkoder.com/jpa-many-to-many/" rel="noopener noreferrer"&gt;JPA Many to Many example with Hibernate in Spring Boot&lt;/a&gt;&lt;br&gt;
One-to-One: &lt;a href="https://www.bezkoder.com/jpa-one-to-one/" rel="noopener noreferrer"&gt;JPA One To One example with Hibernate in Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can apply this implementation in following tutorials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-jpa-h2-example/" rel="noopener noreferrer"&gt;Spring JPA + H2 example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-jpa-crud-rest-api/" rel="noopener noreferrer"&gt;Spring JPA + MySQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-postgresql-example/" rel="noopener noreferrer"&gt;Spring JPA + PostgreSQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-hibernate-oracle/" rel="noopener noreferrer"&gt;Spring JPA + Oracle example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-sql-server/" rel="noopener noreferrer"&gt;Spring JPA + SQL Server example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More Derived queries at:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/jpa-repository-query/" rel="noopener noreferrer"&gt;JPA Repository query example in Spring Boot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Documentation: &lt;a href="https://www.bezkoder.com/spring-boot-swagger-3/" rel="noopener noreferrer"&gt;Spring Boot + Swagger 3 example (with OpenAPI 3)&lt;/a&gt;&lt;br&gt;
Caching: &lt;a href="https://www.bezkoder.com/spring-boot-redis-cache-example/" rel="noopener noreferrer"&gt;Spring Boot Redis Cache example&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>java</category>
      <category>todayilearned</category>
      <category>springboot</category>
    </item>
    <item>
      <title>Angular 16 Pagination example</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Sat, 05 Aug 2023 01:13:25 +0000</pubDate>
      <link>https://forem.com/tienbku/angular-16-pagination-example-1lb1</link>
      <guid>https://forem.com/tienbku/angular-16-pagination-example-1lb1</guid>
      <description>&lt;p&gt;In this tutorial, I will show you how to make Angular 16 Pagination example with existing API (server-side pagination) using ngx-pagination.&lt;/p&gt;

&lt;p&gt;Related Posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-16-crud-example/" rel="noopener noreferrer"&gt;Angular 16 CRUD example with Rest Api&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-16-form-validation/" rel="noopener noreferrer"&gt;Angular 16 Form Validation example (Reactive Forms)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-16-file-upload/" rel="noopener noreferrer"&gt;Angular 16 File upload example with Progress bar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/angular-16-jwt-auth/" rel="noopener noreferrer"&gt;Angular 16 JWT Authentication example with Web Api&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fullstack with Node.js Express:&lt;br&gt;
&lt;a href="https://bezkoder.com/server-side-pagination-node-js-angular/" rel="noopener noreferrer"&gt;Server side Pagination with Node.js and Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fullstack with Spring Boot:&lt;br&gt;
&lt;a href="https://bezkoder.com/pagination-spring-boot-angular-12/" rel="noopener noreferrer"&gt;Spring Boot + Angular: Server side Pagination example&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Overview of Angular 16 Pagination example&lt;/h2&gt;

&lt;p&gt;One of the most important things to make a website friendly is the response time, and pagination comes for this reason. For example, this bezkoder.com website has hundreds of tutorials, and we don’t want to see all of them at once. Paging means displaying a small number of all, by a page.&lt;/p&gt;

&lt;p&gt;Assume that we have tutorials table in database 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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-database.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-database.png" alt="angular-16-pagination-example-database"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our Angular 16 app will display the result with pagination:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-ngx-pagination.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-ngx-pagination.png" alt="angular-16-pagination-example-ngx-pagination"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can change to a page with larger index:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-ngx-pagination-change-page-1.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-ngx-pagination-change-page-1.png" alt="angular-16-pagination-example-change-page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or change quantity of items per page:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-items-per-page.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-items-per-page.png" alt="angular-16-pagination-example-items-per-page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or paging with filter:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-ngx-pagination-filter.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-ngx-pagination-filter.png" alt="angular-16-pagination-example-ngx-pagination-filter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The API for this Angular client can be found at one of following posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/node-js-sequelize-pagination-mysql/" rel="noopener noreferrer"&gt;Node Express Pagination with MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/node-js-pagination-postgresql/" rel="noopener noreferrer"&gt;Node Express Pagination with PostgreSQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/node-js-mongodb-pagination/" rel="noopener noreferrer"&gt;Node Express Pagination with MongoDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-pagination-filter-jpa-pageable/" rel="noopener noreferrer"&gt;Spring Boot Pagination &amp;amp; Filter example | Spring JPA, Pageable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bezkoder.com/spring-boot-mongodb-pagination/" rel="noopener noreferrer"&gt;Spring Boot MongoDB Pagination example with Spring Data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These Servers will exports API for pagination (with/without filter), here are some url samples:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;/api/tutorials?page=1&amp;amp;size=5&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;/api/tutorials?size=5&lt;/code&gt;: using default value for page&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;/api/tutorials?page=1&lt;/code&gt;: using default value for size&lt;/li&gt;
    &lt;li&gt;
&lt;code&gt;/api/tutorials?title=data&amp;amp;page=1&amp;amp;size=3&lt;/code&gt;: pagination &amp;amp; filter by title containing 'data'&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is structure of the response (server-side pagination) for the HTTP GET request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"totalItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tutorials"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"totalPages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"currentPage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="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;This is a kind of server-side paging, where the server sends just a single page at a time. &lt;code&gt;ngx-pagination&lt;/code&gt; supports this scenario, so We actually only need to use &lt;code&gt;tutorials&lt;/code&gt; and &lt;code&gt;totalItems&lt;/code&gt; when working with this library.&lt;/p&gt;

&lt;h2&gt;ngx-pagination with Angular 16&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/ngx-pagination" rel="noopener noreferrer"&gt;ngx-pagination&lt;/a&gt; provides &lt;code&gt;NgxPaginationModule&lt;/code&gt; for displaying pagination with numbers and responsive style.&lt;/p&gt;

&lt;p&gt;There are 2 main things that we're gonna use: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PaginatePipe&lt;/code&gt;: placed at the end of an &lt;code&gt;ngFor&lt;/code&gt; expression
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;your-element&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let item of collection | paginate: { id: 'foo',
                                                      itemsPerPage: pageSize,
                                                      currentPage: page,
                                                      totalItems: total }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/your-element&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the &lt;code&gt;id&lt;/code&gt; if you need to support more than one instance of pagination at a time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PaginationControlsComponent&lt;/code&gt;: a default component for displaying pagination controls
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;pagination-controls&amp;gt;&amp;lt;/pagination-controls&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, this is the default display for simple &lt;code&gt;pagination-controls&lt;/code&gt; 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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fngx-pagination-example-angular-16-pagination-controls.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fngx-pagination-example-angular-16-pagination-controls.png" alt="ngx-pagination-example-angular-16-pagination-controls"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can customize the label displayed on the "previous"/"next" link using &lt;code&gt;previousLabel&lt;/code&gt;/&lt;code&gt;nextLabel&lt;/code&gt;, and enable "responsive" to hide individual page links on small screens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;pagination-controls&lt;/span&gt;
  &lt;span class="na"&gt;previousLabel=&lt;/span&gt;&lt;span class="s"&gt;"Prev"&lt;/span&gt;
  &lt;span class="na"&gt;nextLabel=&lt;/span&gt;&lt;span class="s"&gt;"Next"&lt;/span&gt;
  &lt;span class="na"&gt;responsive=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/pagination-controls&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fngx-pagination-example-angular-16-customize-pagination-controls.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fngx-pagination-example-angular-16-customize-pagination-controls.png" alt="ngx-pagination-example-angular-16-customize-pagination-controls"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For handling page changes, we pass &lt;code&gt;handlePageChange&lt;/code&gt; to &lt;code&gt;pageChange&lt;/code&gt;.&lt;br&gt;
Notice that count is &lt;code&gt;totalItems&lt;/code&gt; in the API response, and &lt;code&gt;page&lt;/code&gt; is the current page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;pagination-controls&lt;/span&gt;
  &lt;span class="na"&gt;(pageChange)=&lt;/span&gt;&lt;span class="s"&gt;"handlePageChange($event)"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/pagination-controls&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt;
    &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let tutorial of tutorials | paginate: {
              itemsPerPage: pageSize,
              currentPage: page,
              totalItems: count
            }"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    {{ tutorial.title }}
  &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TutorialsListComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;handlePageChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;pageChange&lt;/code&gt; is the expression invoked whenever the page changes via a click on the pagination controls. The &lt;code&gt;$event&lt;/code&gt; argument will be the number of the new page.&lt;/p&gt;

&lt;p&gt;There are more attributes that &lt;code&gt;ngx-pagination&lt;/code&gt; supports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;pagination-controls&lt;/span&gt;  &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"some_id"&lt;/span&gt;
                      &lt;span class="na"&gt;(pageChange)=&lt;/span&gt;&lt;span class="s"&gt;"pageChanged($event)"&lt;/span&gt;
                      &lt;span class="na"&gt;(pageBoundsCorrection)=&lt;/span&gt;&lt;span class="s"&gt;"pageChanged($event)"&lt;/span&gt;
                      &lt;span class="na"&gt;maxSize=&lt;/span&gt;&lt;span class="s"&gt;"9"&lt;/span&gt;
                      &lt;span class="na"&gt;directionLinks=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
                      &lt;span class="na"&gt;autoHide=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
                      &lt;span class="na"&gt;responsive=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
                      &lt;span class="na"&gt;previousLabel=&lt;/span&gt;&lt;span class="s"&gt;"Previous"&lt;/span&gt;
                      &lt;span class="na"&gt;nextLabel=&lt;/span&gt;&lt;span class="s"&gt;"Next"&lt;/span&gt;
                      &lt;span class="na"&gt;screenReaderPaginationLabel=&lt;/span&gt;&lt;span class="s"&gt;"Pagination"&lt;/span&gt;
                      &lt;span class="na"&gt;screenReaderPageLabel=&lt;/span&gt;&lt;span class="s"&gt;"page"&lt;/span&gt;
                      &lt;span class="na"&gt;screenReaderCurrentLabel=&lt;/span&gt;&lt;span class="s"&gt;"You're on page"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/pagination-controls&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the details at: &lt;a href="https://www.npmjs.com/package/ngx-pagination" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.npmjs.com/package/ngx-pagination" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/ngx-pagination&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Technology&lt;/h2&gt;

&lt;ul&gt;
    &lt;li&gt;Angular 16&lt;/li&gt;
    &lt;li&gt;RxJS 7&lt;/li&gt;
    &lt;li&gt;ngx-pagination 6&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Setup Angular 16 Pagination Project&lt;/h2&gt;

&lt;p&gt;Let's open cmd and use Angular CLI to create a new Angular Project as following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new angular-16-pagination-example
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? CSS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can follow step by step, or get source code in this post:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/angular-16-crud-example/" rel="noopener noreferrer"&gt;Angular 16 CRUD example with Web API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Angular 16 Project contains structure that we only need to add some changes (in &lt;em&gt;tutorials-list&lt;/em&gt; component and &lt;em&gt;tutorial.service.ts&lt;/em&gt;) to make the pagination work well.&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-project.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-project.png" alt="angular-16-pagination-example-project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or you can get the new Github source code at the end of this tutorial.&lt;/p&gt;

&lt;h2&gt;Setup ngx-pagination for Angular 16 Pagination example&lt;/h2&gt;

&lt;p&gt;We need to install &lt;code&gt;ngx-pagination&lt;/code&gt; with command:&lt;br&gt;
&lt;code&gt;npm install ngx-pagination&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then open &lt;em&gt;app.module.ts&lt;/em&gt; and import it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HttpClientModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgxPaginationModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ngx-pagination&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;declarations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="nx"&gt;NgxPaginationModule&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="na"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppComponent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;Create Data Service&lt;/h2&gt;

&lt;p&gt;This service will use Angular HttpClient to send HTTP requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;services&lt;/strong&gt;/&lt;em&gt;tutorial.service.ts&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Tutorial&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../models/tutorial.model&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:8080/api/tutorials&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TutorialService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// other CRUD operations&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, you can see that we pass &lt;code&gt;params&lt;/code&gt; object to GET method.&lt;br&gt;
The &lt;code&gt;params&lt;/code&gt; object will have one, two or all fields: &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;page&lt;/code&gt;, &lt;code&gt;size&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Create Angular 16 Component with Pagination&lt;/h2&gt;

&lt;p&gt;This component has:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;a search bar for finding Tutorials by &lt;em&gt;title&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;a select element for quantity of items per page.&lt;/li&gt;
    &lt;li&gt;a &lt;code&gt;PaginationControlsComponent&lt;/code&gt; component&lt;/li&gt;
    &lt;li&gt;a &lt;em&gt;tutorials&lt;/em&gt; array displayed as a list on the left.&lt;/li&gt;
    &lt;li&gt;a selected Tutorial which is shown on the right.&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-items-per-page.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fangular-16-pagination-example-items-per-page.png" alt="angular-16-pagination-example-items-per-page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;components&lt;/strong&gt;/&lt;strong&gt;tutorials-list&lt;/strong&gt;/&lt;em&gt;tutorials-list.component.html&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"input-group mb-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form-control"&lt;/span&gt;
        &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Search by title"&lt;/span&gt;
        &lt;span class="na"&gt;[(ngModel)]=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;
      &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"input-group-append"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
          &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-outline-secondary"&lt;/span&gt;
          &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
          &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"searchTitle()"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          Search
        &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;pagination-controls&lt;/span&gt;
      &lt;span class="na"&gt;previousLabel=&lt;/span&gt;&lt;span class="s"&gt;"Prev"&lt;/span&gt;
      &lt;span class="na"&gt;nextLabel=&lt;/span&gt;&lt;span class="s"&gt;"Next"&lt;/span&gt;
      &lt;span class="na"&gt;[responsive]=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
      &lt;span class="na"&gt;(pageChange)=&lt;/span&gt;&lt;span class="s"&gt;"handlePageChange($event)"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&amp;lt;/pagination-controls&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-md-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;Tutorials List&lt;span class="nt"&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-group-item"&lt;/span&gt;
        &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"
          let tutorial of tutorials | paginate : {
                  itemsPerPage: pageSize,
                  currentPage: page,
                  totalItems: count
                };
          let i = index
        "&lt;/span&gt;
        &lt;span class="err"&gt;...&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{ tutorial.title }}
      &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  ...

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...

    Items per Page:
    &lt;span class="nt"&gt;&amp;lt;select&lt;/span&gt; &lt;span class="na"&gt;(change)=&lt;/span&gt;&lt;span class="s"&gt;"handlePageSizeChange($event)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let size of pageSizes"&lt;/span&gt; &lt;span class="na"&gt;[ngValue]=&lt;/span&gt;&lt;span class="s"&gt;"size"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{ size }}
      &lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will have following variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;search and display Tutorials:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;title&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tutorials&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;currentTutorial&lt;/code&gt; and &lt;code&gt;currentIndex&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;pagination:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;page&lt;/code&gt;: current page&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;count&lt;/code&gt;: total pages&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pageSize&lt;/code&gt;: number of items in each page&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;For pagination, we're gonna use &lt;code&gt;TutorialService.getAll()&lt;/code&gt; methods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;components&lt;/strong&gt;/&lt;strong&gt;tutorials-list&lt;/strong&gt;/&lt;em&gt;tutorials-list.component.ts&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Tutorial&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/app/models/tutorial.model&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TutorialService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/app/services/tutorial.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-tutorials-list&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./tutorials-list.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./tutorials-list.component.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TutorialsListComponent&lt;/span&gt; &lt;span class="kr"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nl"&gt;tutorials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tutorial&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;currentTutorial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tutorial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="nx"&gt;currentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;pageSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;pageSizes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;tutorialService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TutorialService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retrieveTutorials&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getRequestParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTitle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`title`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;searchTitle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`page`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`size`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;retrieveTutorials&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRequestParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tutorialService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;tutorials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;totalItems&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tutorials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tutorials&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;totalItems&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;handlePageChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retrieveTutorials&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;handlePageSizeChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pageSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retrieveTutorials&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="nf"&gt;searchTitle&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retrieveTutorials&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain some lines of code.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;retrieveTutorials()&lt;/code&gt; method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We get &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;page&lt;/code&gt;, &lt;code&gt;pageSize&lt;/code&gt; value and transform them into &lt;code&gt;params&lt;/code&gt; object:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;searchTitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"page"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;page&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;pageSize&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;ul&gt;
&lt;li&gt;We use &lt;code&gt;tutorials&lt;/code&gt; and &lt;code&gt;totalItems&lt;/code&gt; as &lt;code&gt;count&lt;/code&gt; value from the response data:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"totalItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tutorials"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"totalPages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"currentPage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;handlePageChange()&lt;/code&gt; and &lt;code&gt;handlePageSizeChange()&lt;/code&gt; methods are for setting new &lt;code&gt;page&lt;/code&gt; and &lt;code&gt;pageSize&lt;/code&gt;, then we invoke &lt;code&gt;retrieveTutorials()&lt;/code&gt; that updates the tutorials List when pagination information changes.&lt;/p&gt;

&lt;h2&gt;Run Angular 16 Pagination example&lt;/h2&gt;

&lt;p&gt;First you need to run the Server at one of following posts:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-sequelize-pagination-mysql/" rel="noopener noreferrer"&gt;Node Express Pagination with MySQL&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-pagination-postgresql/" rel="noopener noreferrer"&gt;Node Express Pagination with PostgreSQL&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-mongodb-pagination/" rel="noopener noreferrer"&gt;Node Express Pagination with MongoDB&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-pagination-filter-jpa-pageable/" rel="noopener noreferrer"&gt;Spring Boot Pagination &amp;amp; Filter example | Spring JPA, Pageable&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://www.bezkoder.com/spring-boot-mongodb-pagination/" rel="noopener noreferrer"&gt;Spring Boot MongoDB Pagination example with Spring Data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then you can run our App with command: &lt;code&gt;ng serve --port 8081&lt;/code&gt;.&lt;br&gt;
If the process is successful, open Browser with Url: &lt;code&gt;&lt;a href="http://localhost:8081/" rel="noopener noreferrer"&gt;http://localhost:8081/&lt;/a&gt;&lt;/code&gt; and check it.&lt;/p&gt;

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

&lt;p&gt;Today we've built a Angular 16 Pagination example that consume API (server-side pagination) successfully with &lt;code&gt;ngx-pagination&lt;/code&gt;. I hope you apply it in your project at ease.&lt;/p&gt;

&lt;p&gt;Happy learning, see you again!&lt;/p&gt;

&lt;h2&gt;Source Code&lt;/h2&gt;

&lt;p&gt;You can find the complete source code for this tutorial on &lt;a href="https://github.com/bezkoder/angular-16-pagination-example" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://www.npmjs.com/package/ngx-pagination" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/ngx-pagination&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://angular.io/guide/http" rel="noopener noreferrer"&gt;Angular HttpClient&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fullstack with Node.js Express:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/server-side-pagination-node-js-angular/" rel="noopener noreferrer"&gt;Server side Pagination with Node.js and Angular&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fullstack with Spring Boot:&lt;br&gt;
&lt;a href="https://www.bezkoder.com/pagination-spring-boot-angular-12/" rel="noopener noreferrer"&gt;Spring Boot + Angular: Server side Pagination example&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Express Typescript example</title>
      <dc:creator>Tien Nguyen</dc:creator>
      <pubDate>Wed, 02 Aug 2023 02:08:27 +0000</pubDate>
      <link>https://forem.com/tienbku/express-typescript-example-37l9</link>
      <guid>https://forem.com/tienbku/express-typescript-example-37l9</guid>
      <description>&lt;p&gt;&lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express&lt;/a&gt; is one of the most popular web frameworks for Node.js that supports routing, middleware, view system... In this tutorial, I will show you how to build Node.js Rest Api example using Express and Typescript.&lt;/p&gt;

&lt;p&gt;Related Posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/typescript-orm-mysql/" rel="noopener noreferrer"&gt;Node.js Typescript Express with MySQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/typescript-orm-postgres/" rel="noopener noreferrer"&gt;Node.js Typescript Express with Postgres example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Express Typescript example&lt;/h2&gt;

&lt;p&gt;We will build Node.js Rest Api using Typescript that handles GET/POST/PUT/DELETE Http requests.&lt;/p&gt;

&lt;p&gt;First, we start with an Express web server. Next, we write the controller. Then we define routes for handling all CRUD operations:&lt;/p&gt;

&lt;p&gt;The following table shows overview of the Rest APIs that will be exported:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Methods&lt;/th&gt;
&lt;th&gt;Urls&lt;/th&gt;
&lt;th&gt;Actions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;api/tutorials&lt;/td&gt;
&lt;td&gt;get all Tutorials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;api/tutorials/:id&lt;/td&gt;
&lt;td&gt;get Tutorial by &lt;code&gt;id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;api/tutorials&lt;/td&gt;
&lt;td&gt;add new Tutorial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;api/tutorials/:id&lt;/td&gt;
&lt;td&gt;update Tutorial by &lt;code&gt;id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;api/tutorials/:id&lt;/td&gt;
&lt;td&gt;remove Tutorial by &lt;code&gt;id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Finally, we're gonna test the Express Typescript Rest Api using Postman.&lt;/p&gt;

&lt;p&gt;Our project structure will be 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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-project.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-project.png" alt="express-typescript-example-project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Create Node.js Typescript application&lt;/h2&gt;

&lt;p&gt;Open terminal/console, then create a folder for our application:&lt;/p&gt;

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

$ mkdir express-typescript-example
$ cd express-typescript-example


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

&lt;/div&gt;

&lt;p&gt;Initialize the Node.js application with a &lt;em&gt;package.json&lt;/em&gt; file:&lt;/p&gt;

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

npm init

package name: (express-typescript-example) express-typescript-example
version: (1.0.0)
description: Rest API using Node.js, TypeScript, Express
entry point: (index.js) server.js
test command:
git repository:
keywords: nodejs, typescript, express, restapi, rest api, crud
author: bezkoder
license: (ISC)
About to write to D:\Projects\NodeTs\node-js-typescript-express-mysql\package.json:

{
  "name": "express-typescript-example",
  "version": "1.0.0",
  "description": "Rest API using Node.js, TypeScript, Express",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"
  },
  "keywords": [
    "nodejs",
    "typescript",
    "express",
    "restapi",
    "rest",
    "api",
    "crud"
  ],
  "author": "bezkoder",
  "license": "ISC"
}

Is this OK? (yes)


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

&lt;/div&gt;

&lt;h2&gt;Add Express and Typescript into Node.js Project&lt;/h2&gt;

&lt;p&gt;We need to install necessary modules: &lt;code&gt;express&lt;/code&gt;, &lt;code&gt;typescript&lt;/code&gt;, &lt;code&gt;cors&lt;/code&gt;, &lt;code&gt;ts-node&lt;/code&gt;, &lt;code&gt;@types/node&lt;/code&gt;, &lt;code&gt;@types/express&lt;/code&gt; and &lt;code&gt;@types/cors&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Run the command:&lt;/p&gt;

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

npm install typescript ts-node @types/node @types/express @types/cors --save-dev
npm install express cors


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

&lt;/div&gt;

&lt;p&gt;The &lt;em&gt;package.json&lt;/em&gt; file should look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"express-typescript-example"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rest API using Node.js, TypeScript, Express"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"server.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"typescript"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"rest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"restapi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"nodejs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"crud"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bezkoder"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ISC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@types/cors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.8.13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@types/express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.17.17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@types/node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^20.3.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ts-node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^10.9.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"typescript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5.1.6"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.8.5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.18.2"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="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;Next, we generate a &lt;em&gt;tsconfig.json&lt;/em&gt; file with command:&lt;/p&gt;

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

./node_modules/.bin/tsc --init


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

&lt;/div&gt;

&lt;p&gt;Open &lt;em&gt;tsconfig.json&lt;/em&gt; and modify the content like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;/*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Language&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Environment&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="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es2016"&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;Set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JavaScript&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;language&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;emitted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JavaScript&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;compatible&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;library&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;declarations.&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="nl"&gt;"experimentalDecorators"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;experimental&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;support&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;legacy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;experimental&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;decorators.&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="nl"&gt;"emitDecoratorMetadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Emit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;design-type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;metadata&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;decorated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;declarations&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;files.&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;Modules&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="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commonjs"&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;Specify&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;what&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;code&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;generated.&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="nl"&gt;"resolveJsonModule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;importing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;files.&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;Emit&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="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./build"&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;Specify&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;an&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;folder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;emitted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;files.&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;Interop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Constraints&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="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Emit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;additional&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JavaScript&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ease&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;support&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;importing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;CommonJS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;modules.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;enables&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'allowSyntheticDefaultImports'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;compatibility.&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="nl"&gt;"forceConsistentCasingInFileNames"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Ensure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;casing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;correct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;imports.&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;Type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Checking&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="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;strict&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;type-checking&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;options.&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;Completeness&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="nl"&gt;"skipLibCheck"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Skip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;checking&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.d.ts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;files.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;*/&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="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;To work with TypeScript, we need TypeScript compiler (&lt;strong&gt;tsc&lt;/strong&gt;), which converts TypeScript code into JavaScript (inside &lt;code&gt;./build&lt;/code&gt; folder). TypeScript files have the &lt;strong&gt;.ts&lt;/strong&gt; extension. Once compiled to JavaScript, we can run the resulting JavaScript files using a JavaScript runtime environment or include them in web applications.&lt;/p&gt;

&lt;p&gt;So we modify &lt;code&gt;"scripts"&lt;/code&gt; property of &lt;em&gt;package.json&lt;/em&gt; file by adding &lt;code&gt;build&lt;/code&gt;, &lt;code&gt;dev&lt;/code&gt; and &lt;code&gt;start&lt;/code&gt; like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node ./build/server.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc &amp;amp;&amp;amp; npm run dev"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;h2&gt;Create Express Typescript server&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;src&lt;/strong&gt; folder, create &lt;em&gt;index.ts&lt;/em&gt; file that export &lt;code&gt;Server&lt;/code&gt; class.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CorsOptions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cors&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;corsOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CorsOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:8081&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;corsOptions&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlencoded&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;What we do are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;import &lt;code&gt;express&lt;/code&gt;, and &lt;code&gt;cors&lt;/code&gt; modules:
&lt;ul&gt;
&lt;li&gt;Express is for building the Rest Apis&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/cors" rel="noopener noreferrer"&gt;cors&lt;/a&gt; provides Express middleware to enable CORS with various options.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;define &lt;code&gt;constructor()&lt;/code&gt; method that receives Express &lt;code&gt;Application&lt;/code&gt; object as parameter.&lt;/li&gt;

&lt;li&gt;in &lt;code&gt;constructor()&lt;/code&gt;, we call &lt;code&gt;config()&lt;/code&gt; method that adds body-parser (&lt;code&gt;json&lt;/code&gt; and &lt;code&gt;urlencoded&lt;/code&gt;) and &lt;code&gt;cors&lt;/code&gt; middlewares using &lt;code&gt;app.use()&lt;/code&gt; method. Notice that we set origin: &lt;code&gt;&lt;a href="http://localhost:8081" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="http://localhost:8081" rel="noopener noreferrer"&gt;http://localhost:8081&lt;/a&gt;&lt;/code&gt;.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;We continue to create &lt;em&gt;server.ts&lt;/em&gt; outside the &lt;strong&gt;src&lt;/strong&gt; folder.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/index&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Server&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;Server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is running on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EADDRINUSE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error: address already in use&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In the code, we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create an Express application using &lt;code&gt;express()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;initialize a &lt;code&gt;Server&lt;/code&gt; object with an &lt;code&gt;Application&lt;/code&gt; object&lt;/li&gt;
&lt;li&gt;listen on port 8080 for incoming requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's run the app with command: &lt;code&gt;npm run start&lt;/code&gt;.&lt;/p&gt;

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

$ npm run start

&amp;gt; express-typescript-example@1.0.0 start
&amp;gt; tsc &amp;amp;&amp;amp; npm run dev

&amp;gt; express-typescript-example@1.0.0 dev
&amp;gt; node ./build/server.js

Server is running on port 8080.


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

&lt;/div&gt;

&lt;h2&gt;Working with Express Router in Typescript&lt;/h2&gt;

&lt;p&gt;To handle HTTP requests, we create a new &lt;code&gt;Router&lt;/code&gt; object using &lt;code&gt;express.Router()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;src&lt;/strong&gt;/&lt;strong&gt;routes&lt;/strong&gt; folder, create &lt;em&gt;home.routes.ts&lt;/em&gt; file that exports &lt;code&gt;Router&lt;/code&gt; object.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;welcome&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../controllers/home.controller&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HomeRoutes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intializeRoutes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;intializeRoutes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HomeRoutes&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;router.get("/", welcome)&lt;/code&gt; is for handling Http GET requests with &lt;code&gt;welcome&lt;/code&gt; as handler function.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;src&lt;/strong&gt;/&lt;strong&gt;controllers&lt;/strong&gt;/&lt;em&gt;home.controller.ts&lt;/em&gt;, we export &lt;code&gt;welcome&lt;/code&gt; function.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome to bezkoder application.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Next we create &lt;code&gt;Routes&lt;/code&gt; class in &lt;strong&gt;src&lt;/strong&gt;/&lt;strong&gt;routes&lt;/strong&gt;/&lt;em&gt;index.ts&lt;/em&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;homeRoutes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./home.routes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Routes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;homeRoutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Then we import &lt;code&gt;Routes&lt;/code&gt; into &lt;code&gt;Server&lt;/code&gt; class's &lt;code&gt;constructor()&lt;/code&gt; method and initialize a new &lt;code&gt;Routes&lt;/code&gt; object.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./routes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Let's stop and re-start the server. Open your browser with url &lt;a href="http://localhost:8080/api" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="http://localhost:8080/api" rel="noopener noreferrer"&gt;http://localhost:8080/api&lt;/a&gt;, you will see:&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-server.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-server.png" alt="express-typescript-example-server"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Handling GET-POST-PUT-DELETE requests with Express Typescript&lt;/h2&gt;

&lt;p&gt;Now we implement more routes to &lt;code&gt;Routes&lt;/code&gt; class that follows APIs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Methods&lt;/th&gt;
&lt;th&gt;Urls&lt;/th&gt;
&lt;th&gt;Actions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;api/tutorials&lt;/td&gt;
&lt;td&gt;get all Tutorials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;api/tutorials/:id&lt;/td&gt;
&lt;td&gt;get Tutorial by &lt;code&gt;id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;api/tutorials&lt;/td&gt;
&lt;td&gt;add new Tutorial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;api/tutorials/:id&lt;/td&gt;
&lt;td&gt;update Tutorial by &lt;code&gt;id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;api/tutorials/:id&lt;/td&gt;
&lt;td&gt;remove Tutorial by &lt;code&gt;id&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In &lt;strong&gt;src&lt;/strong&gt;/&lt;strong&gt;routes&lt;/strong&gt;/&lt;em&gt;index.ts&lt;/em&gt;, add middleware function for &lt;code&gt;"/api/tutorials"&lt;/code&gt; endpoint.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;homeRoutes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./home.routes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;tutorialRoutes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./tutorial.routes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Routes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;homeRoutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/tutorials&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tutorialRoutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We continue to define the above &lt;code&gt;TutorialRoutes&lt;/code&gt; class which initializes a &lt;code&gt;TutorialController&lt;/code&gt; object that provides CRUD operation methods. It exports &lt;code&gt;Router&lt;/code&gt; object. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;src&lt;/strong&gt;/&lt;strong&gt;routes&lt;/strong&gt;/&lt;em&gt;tutorial.routes.ts&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TutorialController&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../controllers/tutorial.controller&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TutorialRoutes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;controller&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;TutorialController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intializeRoutes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;intializeRoutes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a new Tutorial&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Retrieve all Tutorials&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Retrieve a single Tutorial with id&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Update a Tutorial with id&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Delete a Tutorial with id&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TutorialRoutes&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In &lt;strong&gt;src&lt;/strong&gt;/&lt;strong&gt;controllers&lt;/strong&gt;/&lt;em&gt;tutorial.controller.ts&lt;/em&gt;, we define and export &lt;code&gt;TutorialController&lt;/code&gt; class that has &lt;code&gt;create&lt;/code&gt;, &lt;code&gt;findAll&lt;/code&gt;, &lt;code&gt;findOne&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt; methods.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TutorialController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;create OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;reqBody&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Internal Server Error!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;findAll OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Internal Server Error!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;findOne OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;reqParamId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Internal Server Error!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;update OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;reqParamId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;reqBody&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Internal Server Error!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delete OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;reqParamId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Internal Server Error!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;h2&gt;Run and Check&lt;/h2&gt;

&lt;p&gt;Run the Node.js Express Typescript Rest APIs with command:&lt;br&gt;
&lt;code&gt;npm run start&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET &lt;code&gt;&lt;a href="http://localhost:8080/api/tutorials" rel="noopener noreferrer"&gt;http://localhost:8080/api/tutorials&lt;/a&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-get.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-get.png" alt="express-typescript-example-get"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET &lt;code&gt;&lt;a href="http://localhost:8080/api/tutorials/%5Bid%5D" rel="noopener noreferrer"&gt;http://localhost:8080/api/tutorials/[id]&lt;/a&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-get-one.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-get-one.png" alt="express-typescript-example-get-one"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;POST &lt;code&gt;&lt;a href="http://localhost:8080/api/tutorials" rel="noopener noreferrer"&gt;http://localhost:8080/api/tutorials&lt;/a&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-post.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-post.png" alt="express-typescript-example-post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PUT &lt;code&gt;&lt;a href="http://localhost:8080/api/tutorials/%5Bid%5D" rel="noopener noreferrer"&gt;http://localhost:8080/api/tutorials/[id]&lt;/a&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-put.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-put.png" alt="express-typescript-example-put"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DELETE &lt;code&gt;&lt;a href="http://localhost:8080/api/tutorials/%5Bid%5D" rel="noopener noreferrer"&gt;http://localhost:8080/api/tutorials/[id]&lt;/a&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-delete.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%2Fwww.bezkoder.com%2Fwp-content%2Fuploads%2Fexpress-typescript-example-delete.png" alt="express-typescript-example-delete"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Today, we've learned how to create Node.js Rest Apis with an Express Typescript web server. We also know way to write a controller and define routes for handling all CRUD operations.&lt;/p&gt;

&lt;p&gt;Happy learning! See you again.&lt;/p&gt;

&lt;h2&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://expressjs.com/en/guide/routing.html" rel="noopener noreferrer"&gt;Express.js Routing&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://www.npmjs.com/package/express" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/express&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;File Upload Rest API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/node-js-express-file-upload/" rel="noopener noreferrer"&gt;Node.js Express File Upload Rest API example using Multer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/google-cloud-storage-nodejs-upload-file/" rel="noopener noreferrer"&gt;Google Cloud Storage with Node.js: File Upload example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Source code&lt;/h2&gt;

&lt;p&gt;You can find the complete source code for this example on &lt;a href="https://github.com/bezkoder/express-typescript-example" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With Database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/typescript-orm-mysql/" rel="noopener noreferrer"&gt;Node.js Typescript Express with MySQL example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bezkoder.com/typescript-orm-postgres/" rel="noopener noreferrer"&gt;Node.js Typescript Express with Postgres example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>express</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
