Initial commit
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
= RESTful Notes User Guide
|
||||
Andy Wilkinson;
|
||||
:doctype: book
|
||||
:toc:
|
||||
:toclevels: 4
|
||||
:source-highlighter: prettify
|
||||
|
||||
[introduction]
|
||||
= 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.
|
||||
|
||||
[getting-started]
|
||||
= Getting started
|
||||
|
||||
|
||||
|
||||
[getting-started-running-the-service]
|
||||
== Running the service
|
||||
RESTful Notes is written using http://projects.spring.io/spring-boot[Spring Boot] which
|
||||
makes it easy to get it up and running so that you can start exploring the REST API.
|
||||
|
||||
At the moment, binaries for RESTful Notes are not published anywhere. However, building
|
||||
and running it from source is straightforward. The first step is to clone the Git
|
||||
repository:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ git clone https://github.com/wilkinsona/spring-restdocs
|
||||
----
|
||||
|
||||
Once the clone is complete, you're ready to get the service up and running:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ cd rest-notes
|
||||
$ ./gradlew build
|
||||
$ java -jar build/libs/*.jar
|
||||
----
|
||||
|
||||
You can check that the service is up and running by executing a simple request using
|
||||
cURL:
|
||||
|
||||
include::{generated}/index/access_with_curl_request.asciidoc[]
|
||||
|
||||
This request should yield the following response in the
|
||||
http://stateless.co/hal_specification.html[Hypertext Application Language (HAL)] format:
|
||||
|
||||
include::{generated}/index/access_with_curl_response.asciidoc[]
|
||||
|
||||
Note the `_links` in the JSON response. They are key to navigating the API.
|
||||
|
||||
|
||||
|
||||
[getting-started-creating-a-note]
|
||||
== 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:
|
||||
|
||||
include::{generated}/index/access_with_curl_response.asciidoc[]
|
||||
|
||||
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:
|
||||
|
||||
include::{generated}/notes/create_with_curl_request.asciidoc[]
|
||||
|
||||
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:
|
||||
|
||||
include::{generated}/notes/create_with_curl_response.asciidoc[]
|
||||
|
||||
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:
|
||||
|
||||
include::{generated}/notes/get_with_curl_request.asciidoc[]
|
||||
|
||||
This request will produce a response with the note's details in its body:
|
||||
|
||||
include::{generated}/notes/get_with_curl_response.asciidoc[]
|
||||
|
||||
Note the `tags` link which we'll make use of later.
|
||||
|
||||
|
||||
|
||||
[getting-started-creating-a-tag]
|
||||
== 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:
|
||||
|
||||
include::{generated}/index/access_with_curl_response.asciidoc[]
|
||||
|
||||
To create a tag you need to execute a `POST` request to this URI, including a JSON
|
||||
payload containing the name of the tag:
|
||||
|
||||
include::{generated}/tags/create_with_curl_request.asciidoc[]
|
||||
|
||||
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:
|
||||
|
||||
include::{generated}/tags/create_with_curl_response.asciidoc[]
|
||||
|
||||
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:
|
||||
|
||||
include::{generated}/tags/get_with_curl_request.asciidoc[]
|
||||
|
||||
This request will produce a response with the tag's details in its body:
|
||||
|
||||
include::{generated}/tags/get_with_curl_response.asciidoc[]
|
||||
|
||||
|
||||
|
||||
[getting-started-tagging-a-note]
|
||||
== 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.
|
||||
|
||||
|
||||
|
||||
[getting-started-tagging-a-note-creating]
|
||||
=== 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. However, this time, in an array named tags, we
|
||||
include the URI of the tag we just created:
|
||||
|
||||
include::{generated}/notes/create_tagged_with_curl_request.asciidoc[]
|
||||
|
||||
Once again, the response's `Location` header tells us the URI of the newly created note:
|
||||
|
||||
include::{generated}/notes/create_tagged_with_curl_response.asciidoc[]
|
||||
|
||||
As before, a `GET` request executed against this URI will retrieve the note's details:
|
||||
|
||||
include::{generated}/notes/get_tagged_with_curl.asciidoc[]
|
||||
|
||||
To verify that the tag has been associated with the note, we can perform a `GET` request
|
||||
against the URI from the `tags` link:
|
||||
|
||||
include::{generated}/notes/get_tags_for_tagged_with_curl_request.asciidoc[]
|
||||
|
||||
The response embeds information about the tag that we've just associated with the note:
|
||||
|
||||
include::{generated}/notes/get_tags_for_tagged_with_curl_response.asciidoc[]
|
||||
|
||||
|
||||
|
||||
[getting-started-tagging-a-note-existing]
|
||||
=== 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 used the
|
||||
URI of the untagged note that we created earlier:
|
||||
|
||||
include::{generated}/notes/tag_existing_with_curl_request.asciidoc[]
|
||||
|
||||
This request should produce a `204 No Content` response:
|
||||
|
||||
include::{generated}/notes/tag_existing_with_curl_response.asciidoc[]
|
||||
|
||||
When we first created this note, we noted the tags link included in its details:
|
||||
|
||||
include::{generated}/notes/get_with_curl_response.asciidoc[]
|
||||
|
||||
We can use that link now and execute a `GET` request to see that the note now has a
|
||||
single tag:
|
||||
|
||||
include::{generated}/notes/get_tags_for_existing_with_curl.asciidoc[]
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.springframework.restdocs.core.RestDocumentationRequestPostProcessors.port;
|
||||
import static org.springframework.restdocs.core.RestDocumentationResultHandlers.documentCurlRequest;
|
||||
import static org.springframework.restdocs.core.RestDocumentationResultHandlers.documentCurlRequestAndResponse;
|
||||
import static org.springframework.restdocs.core.RestDocumentationResultHandlers.documentCurlResponse;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = Application.class)
|
||||
@WebAppConfiguration
|
||||
public class GettingStartedDocumentation {
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext context;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void index() throws Exception {
|
||||
this.mockMvc.perform(get("/").with(port(8080)).accept(MediaTypes.HAL_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("_links.notes", is(notNullValue())))
|
||||
.andExpect(jsonPath("_links.tags", is(notNullValue())))
|
||||
.andDo(documentCurlRequest("index/access_with_curl_request.asciidoc"))
|
||||
.andDo(documentCurlResponse("index/access_with_curl_response.asciidoc"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void creatingANote() throws JsonProcessingException, Exception {
|
||||
String noteLocation = createNote();
|
||||
getNote(noteLocation);
|
||||
|
||||
String tagLocation = createTag();
|
||||
getTag(tagLocation);
|
||||
|
||||
String taggedNoteLocation = createTaggedNote(tagLocation);
|
||||
getTaggedNote(taggedNoteLocation);
|
||||
getTags(taggedNoteLocation);
|
||||
|
||||
tagExistingNote(noteLocation, tagLocation);
|
||||
getTaggedExistingNote(noteLocation);
|
||||
getTagsForExistingNote(noteLocation);
|
||||
}
|
||||
|
||||
private String createNote() throws Exception {
|
||||
Map<String, String> note = new HashMap<String, String>();
|
||||
note.put("title", "Note creation with cURL");
|
||||
note.put("body", "An example of how to create a note using cURL");
|
||||
|
||||
String noteLocation = this.mockMvc
|
||||
.perform(
|
||||
post("/notes").with(port(8080)).contentType(MediaTypes.HAL_JSON)
|
||||
.content(objectMapper.writeValueAsString(note)))
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(header().string("Location", notNullValue()))
|
||||
.andDo(documentCurlRequest("notes/create_with_curl_request.asciidoc")
|
||||
.includeResponseHeaders())
|
||||
.andDo(documentCurlResponse("notes/create_with_curl_response.asciidoc")
|
||||
.includeResponseHeaders()).andReturn().getResponse()
|
||||
.getHeader("Location");
|
||||
return noteLocation;
|
||||
}
|
||||
|
||||
private void getNote(String noteLocation) throws Exception {
|
||||
this.mockMvc.perform(get(noteLocation).with(port(8080)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("title", is(notNullValue())))
|
||||
.andExpect(jsonPath("body", is(notNullValue())))
|
||||
.andExpect(jsonPath("_links.tags", is(notNullValue())))
|
||||
.andDo(documentCurlRequest("notes/get_with_curl_request.asciidoc"))
|
||||
.andDo(documentCurlResponse("notes/get_with_curl_response.asciidoc"));
|
||||
}
|
||||
|
||||
private String createTag() throws Exception, JsonProcessingException {
|
||||
Map<String, String> tag = new HashMap<String, String>();
|
||||
tag.put("name", "getting-started");
|
||||
|
||||
String tagLocation = this.mockMvc
|
||||
.perform(
|
||||
post("/tags").with(port(8080)).contentType(MediaTypes.HAL_JSON)
|
||||
.content(objectMapper.writeValueAsString(tag)))
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(header().string("Location", notNullValue()))
|
||||
.andDo(documentCurlRequest("tags/create_with_curl_request.asciidoc")
|
||||
.includeResponseHeaders())
|
||||
.andDo(documentCurlResponse("tags/create_with_curl_response.asciidoc")
|
||||
.includeResponseHeaders()).andReturn().getResponse()
|
||||
.getHeader("Location");
|
||||
return tagLocation;
|
||||
}
|
||||
|
||||
private void getTag(String tagLocation) throws Exception {
|
||||
this.mockMvc.perform(get(tagLocation).with(port(8080)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("name", is(notNullValue())))
|
||||
.andExpect(jsonPath("_links.notes", is(notNullValue())))
|
||||
.andDo(documentCurlRequest("tags/get_with_curl_request.asciidoc"))
|
||||
.andDo(documentCurlResponse("tags/get_with_curl_response.asciidoc"));
|
||||
}
|
||||
|
||||
private String createTaggedNote(String tag) throws Exception {
|
||||
Map<String, Object> note = new HashMap<String, Object>();
|
||||
note.put("title", "Tagged note creation with cURL");
|
||||
note.put("body", "An example of how to create a tagged note using cURL");
|
||||
note.put("tags", Arrays.asList(tag));
|
||||
|
||||
String noteLocation = this.mockMvc
|
||||
.perform(
|
||||
post("/notes").with(port(8080)).contentType(MediaTypes.HAL_JSON)
|
||||
.content(objectMapper.writeValueAsString(note)))
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(header().string("Location", notNullValue()))
|
||||
.andDo(documentCurlRequest(
|
||||
"notes/create_tagged_with_curl_request.asciidoc")
|
||||
.includeResponseHeaders())
|
||||
.andDo(documentCurlResponse(
|
||||
"notes/create_tagged_with_curl_response.asciidoc")
|
||||
.includeResponseHeaders()).andReturn().getResponse()
|
||||
.getHeader("Location");
|
||||
return noteLocation;
|
||||
}
|
||||
|
||||
private void getTaggedNote(String tagLocation) throws Exception {
|
||||
this.mockMvc
|
||||
.perform(get(tagLocation).with(port(8080)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("title", is(notNullValue())))
|
||||
.andExpect(jsonPath("body", is(notNullValue())))
|
||||
.andExpect(jsonPath("_links.tags", is(notNullValue())))
|
||||
.andDo(documentCurlRequestAndResponse("notes/get_tagged_with_curl.asciidoc"));
|
||||
}
|
||||
|
||||
private void getTags(String taggedNoteLocation) throws Exception {
|
||||
String tagsLocation = getLink(this.mockMvc.perform(get(taggedNoteLocation))
|
||||
.andReturn(), "tags");
|
||||
this.mockMvc
|
||||
.perform(get(tagsLocation).with(port(8080)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("_embedded.tags", hasSize(1)))
|
||||
.andDo(documentCurlRequest("notes/get_tags_for_tagged_with_curl_request.asciidoc"))
|
||||
.andDo(documentCurlResponse("notes/get_tags_for_tagged_with_curl_response.asciidoc"));
|
||||
}
|
||||
|
||||
private void tagExistingNote(String noteLocation, String tagLocation)
|
||||
throws Exception {
|
||||
Map<String, Object> update = new HashMap<String, Object>();
|
||||
update.put("tags", Arrays.asList(tagLocation));
|
||||
|
||||
this.mockMvc
|
||||
.perform(
|
||||
patch(noteLocation).with(port(8080))
|
||||
.contentType(MediaTypes.HAL_JSON)
|
||||
.content(objectMapper.writeValueAsString(update)))
|
||||
.andExpect(status().isNoContent())
|
||||
.andDo(documentCurlRequest(
|
||||
"notes/tag_existing_with_curl_request.asciidoc")
|
||||
.includeResponseHeaders())
|
||||
.andDo(documentCurlResponse(
|
||||
"notes/tag_existing_with_curl_response.asciidoc")
|
||||
.includeResponseHeaders());
|
||||
|
||||
}
|
||||
|
||||
private void getTaggedExistingNote(String tagLocation) throws Exception {
|
||||
this.mockMvc
|
||||
.perform(get(tagLocation).with(port(8080)))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(documentCurlRequestAndResponse("notes/get_tagged_existing_with_curl.asciidoc"));
|
||||
}
|
||||
|
||||
private void getTagsForExistingNote(String taggedNoteLocation) throws Exception {
|
||||
String tagsLocation = getLink(this.mockMvc.perform(get(taggedNoteLocation))
|
||||
.andReturn(), "tags");
|
||||
this.mockMvc
|
||||
.perform(get(tagsLocation).with(port(8080)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("_embedded.tags", hasSize(1)))
|
||||
.andDo(print())
|
||||
.andDo(documentCurlRequestAndResponse("notes/get_tags_for_existing_with_curl.asciidoc"));
|
||||
}
|
||||
|
||||
private String getLink(MvcResult result, String href)
|
||||
throws UnsupportedEncodingException {
|
||||
return JsonPath.parse(result.getResponse().getContentAsString()).read(
|
||||
"_links.tags.href");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.springframework.restdocs.outputDir = build/generated-documentation
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan
|
||||
@EnableJpaRepositories
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
@Entity
|
||||
public class Note {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private long id;
|
||||
|
||||
private String title;
|
||||
|
||||
private String body;
|
||||
|
||||
@ManyToMany
|
||||
private List<Tag> tags;
|
||||
|
||||
@JsonIgnore
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public List<Tag> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(List<Tag> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface NoteRepository extends CrudRepository<Note, Long> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
@Entity
|
||||
public class Tag {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@ManyToMany(mappedBy = "tags")
|
||||
private List<Note> notes;
|
||||
|
||||
@JsonIgnore
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Note> getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public void setNotes(List<Note> notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.notes;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface TagRepository extends CrudRepository<Tag, Long> {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user