Build a Markdown-based Blog with Spring Boot - Part 1
Tags: springboot, java, markdown, thymeleaf
Published: 2021-05-19 16:09:47

<p>In this piece, we will be building a personal blog containing articles written in Markdown.</p><p>We will use Spring Boot to develop the project and few other tools and libraries. We will push our project to a GitHub repository and use Heroku's Automatic Deployment feature to publish posts to our blog.</p><p>Additionally, we will use the RemoteMySQL service to host our remote MySQL database. To communicate with the database, we will need MySQL connector for Java and Spring Data JPA.</p><p>For rendering our view, we will use Thymeleaf.</p><p>This article is one part of a series of posts that I intend to publish on this topic.&nbsp;</p><p>For the entirety of this tutorial, I will use IntelliJ IDEA Community Edition as the IDE.</p><p>There may be some IntelliJ-specific shortcuts and hotkeys here and there, but you can follow along using your IDE of choice.</p><p>Now let's get going!</p><p><br /></p><h3 style="text-align: left;">Generating Project</h3><p>Just like how every fun Spring Boot adventure begins, go to <a href="http://start.spring.io" target="_blank">start.spring.io</a>&nbsp;(Spring Initializr) and configure our project.</p><p>Select the <span style="background-color: white;"><span style="font-family: inherit;"><em>Maven Project</em></span></span> option and <em>Java</em> as the language.</p><p>Choose a non-snapshot version of Spring Boot (I chose 2.4.5).&nbsp;</p><p>Then, fill up your Project Metadata -- including the Group, Artifact, Name, Description, and Package name.</p><p>We will be using Jar packaging, so select <em>Jar</em>. Then, choose <em>11</em> as the Java version.</p><p>For dependencies, we will need the following:</p><p></p><ul style="text-align: left;"><li>Spring Data JPA</li><li>MySQL Driver</li><li>Thymeleaf</li><li>Spring Web</li><li>Lombok</li></ul><div>Finally, generate the project structure by clicking the <em>Generate</em> button.</div><p style="text-align: left;">Extract the resulting <em>.zip</em> file and you're ready to go!</p><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-rLWfwW3sIU4/YKUVYp4PHII/AAAAAAAAG6U/zICDtMPsDVAH6Wkoj-xRy7TkJKnT9YTggCLcBGAsYHQ/s1725/spring-init.jpg" style="margin-left: 1em; margin-right: 1em;"><img alt="Configuring project with start.spring.io" border="0" data-original-height="907" data-original-width="1725" src="https://1.bp.blogspot.com/-rLWfwW3sIU4/YKUVYp4PHII/AAAAAAAAG6U/zICDtMPsDVAH6Wkoj-xRy7TkJKnT9YTggCLcBGAsYHQ/s16000/spring-init.jpg" title="Configuring project with start.spring.io" /></a></div><br /><div><br /></div><h3 style="text-align: left;">Opening the project</h3><p style="text-align: left;">Once the .zip file has been extracted, the project can be imported into the IDE.</p><p style="text-align: left;">Using IntelliJ IDEA, you can open the project by pointing IntelliJ to the root folder of the project (one that contains the <em>pom.xml</em> file as an immediate child).</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-TFEtQw9LX0o/YKUalTzeJ_I/AAAAAAAAG6c/ccv21dZfAIY2ppZx_YkEbKArd70aSE3kACLcBGAsYHQ/s616/intellij-open-project.jpg" style="margin-left: 1em; margin-right: 1em;"><img alt="Open project with IntelliJ IDEA" border="0" data-original-height="465" data-original-width="616" src="https://1.bp.blogspot.com/-TFEtQw9LX0o/YKUalTzeJ_I/AAAAAAAAG6c/ccv21dZfAIY2ppZx_YkEbKArd70aSE3kACLcBGAsYHQ/s16000/intellij-open-project.jpg" title="Open project with IntelliJ IDEA" /></a></div><br /><p style="text-align: left;">After you've opened the project, take a look at the directory and file structure generated by Spring Intializr.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-INBthZF8SRU/YKUbLeS45pI/AAAAAAAAG6k/554DO-d7M4EEC3Qp4PUqw33M6TmMf88vwCLcBGAsYHQ/s1919/opened-project.png" style="margin-left: 1em; margin-right: 1em;"><img alt="Project directory structure" border="0" data-original-height="1020" data-original-width="1919" src="https://1.bp.blogspot.com/-INBthZF8SRU/YKUbLeS45pI/AAAAAAAAG6k/554DO-d7M4EEC3Qp4PUqw33M6TmMf88vwCLcBGAsYHQ/s16000/opened-project.png" title="Project directory structure" /></a></div><br /><p style="text-align: left;">The pom.xml file is crucial for a Maven project.</p><p style="text-align: left;">It is filled with the dependencies that we selected from our little configuration session with Spring Initialzr.</p><p style="text-align: left;">Since Spring Boot is an opinionated framework, within its starter dependencies are a collection of other dependencies that have been curated by Spring Boot itself.</p><p style="text-align: left;"><br /></p><h3 style="text-align: left;">Defining entities</h3><p style="text-align: left;">Our blog needs two entities -- posts and authors.</p><p style="text-align: left;">The author entity describes an author of a post with their name, email, and website.</p><p style="text-align: left;">The post entity describes a post, with its title, content, timestamp of creation, synopsis (first 150 characters of the post), and the ID of the author.</p><p style="text-align: left;">Both entities are identified by a unique, auto-generating ID.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-XAzFVjGF-B8/YKUflQfmhDI/AAAAAAAAG6s/c509lX3vHY4g1BW8qdOc6To32q9XL5guQCLcBGAsYHQ/s964/erd.png" style="margin-left: 1em; margin-right: 1em;"><img alt="ER diagram of entities" border="0" data-original-height="530" data-original-width="964" src="https://1.bp.blogspot.com/-XAzFVjGF-B8/YKUflQfmhDI/AAAAAAAAG6s/c509lX3vHY4g1BW8qdOc6To32q9XL5guQCLcBGAsYHQ/s16000/erd.png" title="ER diagram of entities" /></a></div><br /><h3 style="text-align: left;">Defining POJOs</h3><p style="text-align: left;">The Plain Old Java Object (POJO) definitions for the entities are as described below.</p>
<p>{% gist https://gist.github.com/roshanadh/e1fafb94ecdf25b73e86c037038fc9fc.js %}</p>
<p>{% gist https://gist.github.com/roshanadh/335baf527b9c952379e27752c1b2b54e.js %}</p>
<p style="text-align: left;">We use <em>JPA</em> annotations to specify a one-to-many relationship between authors and posts.</p><p style="text-align: left;">Furthermore, to map Java's <em>LocalDateTime</em> typed attribtue to MySQL's <em>datetime</em> typed column, we need to convert between the two types (from LocalDateTime to <em>TimeStamp</em> and vice-versa).</p><p style="text-align: left;">For that, we define a new <em>LocalDateTimeConverter</em> class as following.</p>
<p>{% gist https://gist.github.com/roshanadh/3dd51453124f6114cada5a567ff6b380.js %}</p>

<h3 style="text-align: left;"><br /></h3><h3 style="text-align: left;">Code</h3><p style="text-align: left;">I will end things at this much for now. We will continue the project from the next part of this series.</p><p style="text-align: left;">The project has been pushed to a GitHub repository, and you can find the code <a href="https://github.com/roshanadh/markdown-blog/tree/part-1" target="_blank">here</a>.</p>