<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://blog.bitheater.co.uk/feed.xml" rel="self" type="application/atom+xml" /><link href="https://blog.bitheater.co.uk/" rel="alternate" type="text/html" /><updated>2026-10-18T10:20:10+00:00</updated><id>https://blog.bitheater.co.uk/feed.xml</id><title type="html">BitHeater Notes</title><subtitle>Software engineering notes from BitHeater, with links to our current projects.</subtitle><entry><title type="html">Creating your first Spring Boot REST app</title><link href="https://blog.bitheater.co.uk/first-spring-boot-app" rel="alternate" type="text/html" title="Creating your first Spring Boot REST app" /><published>2018-02-08T12:50:56+00:00</published><updated>2018-02-08T12:50:56+00:00</updated><id>https://blog.bitheater.co.uk/first-spring-boot-app</id><content type="html" xml:base="https://blog.bitheater.co.uk/first-spring-boot-app"><![CDATA[<p>In this tutorial, we’re going to create a Spring Boot users REST API from scratch. Without further delay, head to the Spring Initializr website (click <a href="http://start.spring.io/">here</a>):</p>

<p><img src="/images/first-spring-boot-app/spring-initializr.png" alt="Spring Initializr" title="Spring Initializr" class="img-responsive" /></p>

<p>Fill the basic information (group, artifact) and add the <em>Web</em> dependency, as we’re planning to use a REST API.</p>

<p>We’ll be using Gradle (Spring Boot supports Maven, too) and Groovy (Java and Kotlin are supported), but you can use whatever you feel more comfortable with.</p>

<p>Once you’ve filled the form, generate the project. It’ll download a ZIP file.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>unzip users.zip
<span class="nv">$ </span><span class="nb">cd users</span>
<span class="nv">$ </span>./gradlew bootRun
</code></pre></div></div>

<p>We’re done! Spring Boot is able to start the application, and it’s even listening on port 8080. But we have configured no controller to be listening, so any HTTP request will return 404. Let’s create our first endpoint.</p>

<p>Open the project on your favourite editor (we use IntelliJ) and create your user model:</p>

<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">uk.co.bitheater.users</span>

<span class="kd">class</span> <span class="nc">User</span> <span class="o">{</span>
    <span class="kt">int</span> <span class="n">id</span>
    <span class="n">String</span> <span class="n">name</span>
    <span class="n">String</span> <span class="n">email</span>
<span class="o">}</span>
</code></pre></div></div>

<p>A simple user class, with an identifier, a name and an email. Now let’s create a controller with some users in-memory:</p>

<div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">uk.co.bitheater.users</span>

<span class="kn">import</span> <span class="nn">org.springframework.http.HttpHeaders</span>
<span class="kn">import</span> <span class="nn">org.springframework.http.HttpStatus</span>
<span class="kn">import</span> <span class="nn">org.springframework.http.ResponseEntity</span>
<span class="kn">import</span> <span class="nn">org.springframework.web.bind.annotation.DeleteMapping</span>
<span class="kn">import</span> <span class="nn">org.springframework.web.bind.annotation.GetMapping</span>
<span class="kn">import</span> <span class="nn">org.springframework.web.bind.annotation.PathVariable</span>
<span class="kn">import</span> <span class="nn">org.springframework.web.bind.annotation.PostMapping</span>
<span class="kn">import</span> <span class="nn">org.springframework.web.bind.annotation.PutMapping</span>
<span class="kn">import</span> <span class="nn">org.springframework.web.bind.annotation.RequestBody</span>
<span class="kn">import</span> <span class="nn">org.springframework.web.bind.annotation.RestController</span>

<span class="nd">@RestController</span>
<span class="kd">class</span> <span class="nc">UserController</span> <span class="o">{</span>
    <span class="kt">def</span> <span class="n">users</span> <span class="o">=</span> <span class="o">[</span>
            <span class="mi">1</span><span class="o">:</span> <span class="k">new</span> <span class="n">User</span><span class="o">(</span><span class="nl">id:</span> <span class="mi">1</span><span class="o">,</span> <span class="nl">name:</span> <span class="s1">'User 1'</span><span class="o">,</span> <span class="nl">email:</span> <span class="s1">'user1@gmail.com'</span><span class="o">),</span>
            <span class="mi">2</span><span class="o">:</span> <span class="k">new</span> <span class="n">User</span><span class="o">(</span><span class="nl">id:</span> <span class="mi">2</span><span class="o">,</span> <span class="nl">name:</span> <span class="s1">'User 2'</span><span class="o">,</span> <span class="nl">email:</span> <span class="s1">'user2@gmail.com'</span><span class="o">),</span>
            <span class="mi">3</span><span class="o">:</span> <span class="k">new</span> <span class="n">User</span><span class="o">(</span><span class="nl">id:</span> <span class="mi">3</span><span class="o">,</span> <span class="nl">name:</span> <span class="s1">'User 3'</span><span class="o">,</span> <span class="nl">email:</span> <span class="s1">'user3@gmail.com'</span><span class="o">)</span>
    <span class="o">]</span>

    <span class="nd">@GetMapping</span><span class="o">(</span><span class="s1">'/users'</span><span class="o">)</span>
    <span class="kt">def</span> <span class="nf">get</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">users</span><span class="o">.</span><span class="na">values</span><span class="o">()</span>
    <span class="o">}</span>

    <span class="nd">@GetMapping</span><span class="o">(</span><span class="s1">'/users/{id}'</span><span class="o">)</span>
    <span class="kt">def</span> <span class="nf">get</span><span class="o">(</span><span class="nd">@PathVariable</span><span class="o">(</span><span class="s2">"id"</span><span class="o">)</span> <span class="kt">int</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">users</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">id</span><span class="o">)</span>
    <span class="o">}</span>

    <span class="nd">@PostMapping</span><span class="o">(</span><span class="s1">'/users'</span><span class="o">)</span>
    <span class="kt">def</span> <span class="nf">add</span><span class="o">(</span><span class="nd">@RequestBody</span> <span class="n">User</span> <span class="n">user</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">users</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">user</span><span class="o">.</span><span class="na">id</span><span class="o">,</span> <span class="n">user</span><span class="o">)</span>

        <span class="kt">def</span> <span class="n">headers</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HttpHeaders</span><span class="o">()</span>
        <span class="n">headers</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s1">'Location'</span><span class="o">,</span> <span class="s2">"http://localhost:8080/users/$user.id"</span><span class="o">)</span>
        <span class="k">return</span> <span class="k">new</span> <span class="n">ResponseEntity</span><span class="o">&lt;&gt;(</span><span class="n">headers</span><span class="o">,</span> <span class="n">HttpStatus</span><span class="o">.</span><span class="na">CREATED</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="nd">@PutMapping</span><span class="o">(</span><span class="s1">'/users/{id}'</span><span class="o">)</span>
    <span class="n">User</span> <span class="nf">edit</span><span class="o">(</span><span class="nd">@PathVariable</span><span class="o">(</span><span class="s2">"id"</span><span class="o">)</span> <span class="kt">int</span> <span class="n">id</span><span class="o">,</span> <span class="nd">@RequestBody</span> <span class="n">User</span> <span class="n">user</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">users</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="n">user</span><span class="o">)</span>
        <span class="k">return</span> <span class="n">users</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">id</span><span class="o">)</span>
    <span class="o">}</span>

    <span class="nd">@DeleteMapping</span><span class="o">(</span><span class="s1">'/users/{id}'</span><span class="o">)</span>
    <span class="kt">def</span> <span class="nf">delete</span><span class="o">(</span><span class="nd">@PathVariable</span><span class="o">(</span><span class="s2">"id"</span><span class="o">)</span> <span class="kt">int</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">users</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="n">id</span><span class="o">)</span>
        <span class="k">return</span> <span class="k">new</span> <span class="n">ResponseEntity</span><span class="o">&lt;&gt;([],</span> <span class="n">HttpStatus</span><span class="o">.</span><span class="na">NO_CONTENT</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>We’re using some annotations here:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">@RestController</code> to automatically register our bean as a controller (REST, in our case, so it’ll automatically do any JSON processing for us)</li>
  <li><code class="language-plaintext highlighter-rouge">@GetMapping</code>, <code class="language-plaintext highlighter-rouge">@PostMapping</code>, <code class="language-plaintext highlighter-rouge">@PutMapping</code> and <code class="language-plaintext highlighter-rouge">@DeleteMapping</code> to associate operations with their custom controller method, depending on the HTTP verb used</li>
</ul>

<p>We’re basically transforming and playing around with an in memory map of users, and we trust our API users not to do crazy things. At the end of the day, this is just a demo!</p>

<p>We can run again our application, and test the endpoints easily using CURL:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl http://localhost:8080/users
<span class="nv">$ </span>curl http://localhost:8080/users/1
<span class="nv">$ </span>curl <span class="nt">-XPOST</span> http://localhost:8080/users <span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="nt">-d</span> <span class="s1">'{"id": 4, "name": "Test", "email": "test@test.com"}'</span>
<span class="nv">$ </span>curl http://localhost:8080/users/4
<span class="nv">$ </span>curl http://localhost:8080/users
<span class="nv">$ </span>curl <span class="nt">-XPUT</span> http://localhost:8080/users/4 <span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="nt">-d</span> <span class="s1">'{"id": 4, "name": "Test Edited", "email": "test@test.com"}'</span>
<span class="nv">$ </span>curl http://localhost:8080/users
<span class="nv">$ </span>curl http://localhost:8080/users/4
<span class="nv">$ </span>curl <span class="nt">-XDELETE</span> http://localhost:8080/users/4
<span class="nv">$ </span>curl http://localhost:8080/users
</code></pre></div></div>

<p>We were very quickly able to:</p>

<ul>
  <li>Query all users</li>
  <li>Query a single user</li>
  <li>Add a user</li>
  <li>Edit the user</li>
  <li>Delete the user</li>
</ul>

<p>We’re done! By just creating a couple of files and no configuration at all, we’re created the simplest possible RESTful API using Spring Boot. So easy!</p>]]></content><author><name>Magd Kudama</name></author><summary type="html"><![CDATA[In this tutorial, we’re going to create a Spring Boot users REST API from scratch. Without further delay, head to the Spring Initializr website (click here):]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.bitheater.co.uk/images/first-spring-boot-app/spring-boot-logo.png" /><media:content medium="image" url="https://blog.bitheater.co.uk/images/first-spring-boot-app/spring-boot-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>