Introduction

RESTful Notes is a RESTful web service for creating and storing notes. It uses hypermedia to describe the relationships between resources and to allow navigation between them.

Running the service

RESTful Notes is written using Spring Boot which makes it easy to get it up and running so that you can start exploring the REST API.

The first step is to clone the Git repository:

$ git clone https://github.com/spring-projects/spring-restdocs

Once the clone is complete, you’re ready to get the service up and running:

$ cd samples/rest-notes-spring-hateoas
$ ./gradlew build
$ java -jar build/libs/*.jar

You can check that the service is up and running by executing a simple request using cURL:

$ curl 'http://localhost:8080/' -i -X GET \
    -H 'Accept: application/hal+json'

This request should yield the following response:

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 155

{
  "_links" : {
    "notes" : {
      "href" : "http://localhost:8080/notes"
    },
    "tags" : {
      "href" : "http://localhost:8080/tags"
    }
  }
}

Note the _links in the JSON response. They are key to navigating the API.

Creating a note

Now that you’ve started the service and verified that it works, the next step is to use it to create a new note. As you saw above, the URI for working with notes is included as a link when you perform a GET request against the root of the service:

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 155

{
  "_links" : {
    "notes" : {
      "href" : "http://localhost:8080/notes"
    },
    "tags" : {
      "href" : "http://localhost:8080/tags"
    }
  }
}

To create a note you need to execute a POST request to this URI, including a JSON payload containing the title and body of the note:

$ curl 'http://localhost:8080/notes' -i -X POST \
    -H 'Content-Type: application/hal+json' \
    -d '{
  "title" : "Note creation with cURL",
  "body" : "An example of how to create a note using cURL"
}'

The response from this request should have a status code of 201 Created and contain a Location header whose value is the URI of the newly created note:

HTTP/1.1 201 Created
Location: http://localhost:8080/notes/16

To work with the newly created note you use the URI in the Location header. For example you can access the note’s details by performing a GET request:

$ curl 'http://localhost:8080/notes/16' -i -X GET

This request will produce a response with the note’s details in its body:

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 270

{
  "body" : "An example of how to create a note using cURL",
  "title" : "Note creation with cURL",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/notes/16"
    },
    "note-tags" : {
      "href" : "http://localhost:8080/notes/16/tags"
    }
  }
}

Note the note-tags link which we’ll make use of later.

Creating a tag

To make a note easier to find, it can be associated with any number of tags. To be able to tag a note, you must first create the tag.

Referring back to the response for the service’s index, the URI for working with tags is include as a link:

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 155

{
  "_links" : {
    "notes" : {
      "href" : "http://localhost:8080/notes"
    },
    "tags" : {
      "href" : "http://localhost:8080/tags"
    }
  }
}

To create a tag you need to execute a POST request to this URI, including a JSON payload containing the name of the tag:

$ curl 'http://localhost:8080/tags' -i -X POST \
    -H 'Content-Type: application/hal+json' \
    -d '{
  "name" : "getting-started"
}'

The response from this request should have a status code of 201 Created and contain a Location header whose value is the URI of the newly created tag:

HTTP/1.1 201 Created
Location: http://localhost:8080/tags/17

To work with the newly created tag you use the URI in the Location header. For example you can access the tag’s details by performing a GET request:

$ curl 'http://localhost:8080/tags/17' -i -X GET

This request will produce a response with the tag’s details in its body:

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 203

{
  "name" : "getting-started",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/tags/17"
    },
    "tagged-notes" : {
      "href" : "http://localhost:8080/tags/17/notes"
    }
  }
}

Tagging a note

A tag isn’t particularly useful until it’s been associated with one or more notes. There are two ways to tag a note: when the note is first created or by updating an existing note. We’ll look at both of these in turn.

Creating a tagged note

The process is largely the same as we saw before, but this time, in addition to providing a title and body for the note, we’ll also provide the tag that we want to be associated with it.

Once again we execute a POST request, but this time, in an array named tags, we include the URI of the tag we just created:

$ curl 'http://localhost:8080/notes' -i -X POST \
    -H 'Content-Type: application/hal+json' \
    -d '{
  "title" : "Tagged note creation with cURL",
  "body" : "An example of how to create a tagged note using cURL",
  "tags" : [ "http://localhost:8080/tags/17" ]
}'

Once again, the response’s Location header tells use the URI of the newly created note:

HTTP/1.1 201 Created
Location: http://localhost:8080/notes/18

As before, a GET request executed against this URI will retrieve the note’s details:

$ curl 'http://localhost:8080/notes/18' -i -X GET
HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 284

{
  "body" : "An example of how to create a tagged note using cURL",
  "title" : "Tagged note creation with cURL",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/notes/18"
    },
    "note-tags" : {
      "href" : "http://localhost:8080/notes/18/tags"
    }
  }
}

To see the note’s tags, execute a GET request against the URI of the note’s note-tags link:

$ curl 'http://localhost:8080/notes/18/tags' -i -X GET

The response shows that, as expected, the note has a single tag:

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 286

{
  "_embedded" : {
    "tags" : [ {
      "name" : "getting-started",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/tags/17"
        },
        "tagged-notes" : {
          "href" : "http://localhost:8080/tags/17/notes"
        }
      }
    } ]
  }
}

Tagging an existing note

An existing note can be tagged by executing a PATCH request against the note’s URI with a body that contains the array of tags to be associated with the note. We’ll use the URI of the untagged note that we created earlier:

$ curl 'http://localhost:8080/notes/16' -i -X PATCH \
    -H 'Content-Type: application/hal+json' \
    -d '{
  "tags" : [ "http://localhost:8080/tags/17" ]
}'

This request should produce a 204 No Content response:

HTTP/1.1 204 No Content

When we first created this note, we noted the note-tags link included in its details:

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 270

{
  "body" : "An example of how to create a note using cURL",
  "title" : "Note creation with cURL",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/notes/16"
    },
    "note-tags" : {
      "href" : "http://localhost:8080/notes/16/tags"
    }
  }
}

We can use that link now and execute a GET request to see that the note now has a single tag:

$ curl 'http://localhost:8080/notes/16/tags' -i -X GET
HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 286

{
  "_embedded" : {
    "tags" : [ {
      "name" : "getting-started",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/tags/17"
        },
        "tagged-notes" : {
          "href" : "http://localhost:8080/tags/17/notes"
        }
      }
    } ]
  }
}