diff --git a/spring-boot-samples/pom.xml b/spring-boot-samples/pom.xml
index 9dd8a0cec1..55851b7721 100644
--- a/spring-boot-samples/pom.xml
+++ b/spring-boot-samples/pom.xml
@@ -36,6 +36,7 @@
spring-boot-sample-data-rest
spring-boot-sample-data-solr
spring-boot-sample-flyway
+ spring-boot-sample-hateoas
spring-boot-sample-hornetq
spring-boot-sample-integration
spring-boot-sample-jersey
diff --git a/spring-boot-samples/spring-boot-sample-hateoas/pom.xml b/spring-boot-samples/spring-boot-sample-hateoas/pom.xml
new file mode 100644
index 0000000000..5a9a8477bc
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-hateoas/pom.xml
@@ -0,0 +1,49 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-samples
+ 1.1.11.BUILD-SNAPSHOT
+
+ spring-boot-sample-hateoas
+ Spring Boot Hateoas Sample
+ Spring Boot Hateoas Sample
+ http://projects.spring.io/spring-boot/
+
+ Pivotal Software, Inc.
+ http://www.spring.io
+
+
+ ${basedir}/../..
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.hateoas
+ spring-hateoas
+
+
+ org.springframework.plugin
+ spring-plugin-core
+ 1.1.0.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/SampleHateoasApplication.java b/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/SampleHateoasApplication.java
new file mode 100644
index 0000000000..ff3bad1ab4
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/SampleHateoasApplication.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2012-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 sample;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableAutoConfiguration
+@ComponentScan
+public class SampleHateoasApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SampleHateoasApplication.class, args);
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/domain/Customer.java b/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/domain/Customer.java
new file mode 100644
index 0000000000..d978e03a20
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/domain/Customer.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012-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 sample.domain;
+
+public class Customer {
+
+ private final Long id;
+
+ private final String firstName;
+
+ private final String lastName;
+
+ public Customer(Long id, String firstName, String lastName) {
+ this.id = id;
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public String getFirstName() {
+ return this.firstName;
+ }
+
+ public String getLastName() {
+ return this.lastName;
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/domain/CustomerRepository.java b/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/domain/CustomerRepository.java
new file mode 100644
index 0000000000..d183b173a1
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/domain/CustomerRepository.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2012-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 sample.domain;
+
+import java.util.List;
+
+public interface CustomerRepository {
+
+ List findAll();
+
+ Customer findOne(Long id);
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/domain/InMemoryCustomerRepository.java b/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/domain/InMemoryCustomerRepository.java
new file mode 100644
index 0000000000..ee791d2249
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/domain/InMemoryCustomerRepository.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2012-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 sample.domain;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.stereotype.Repository;
+import org.springframework.util.ObjectUtils;
+
+@Repository
+public class InMemoryCustomerRepository implements CustomerRepository {
+
+ private final List customers = new ArrayList();
+
+ public InMemoryCustomerRepository() {
+ this.customers.add(new Customer(1L, "Oliver", "Gierke"));
+ this.customers.add(new Customer(2L, "Andy", "Wilkinson"));
+ this.customers.add(new Customer(2L, "Dave", "Syer"));
+ }
+
+ @Override
+ public List findAll() {
+ return this.customers;
+ }
+
+ @Override
+ public Customer findOne(Long id) {
+ for (Customer customer : this.customers) {
+ if (ObjectUtils.nullSafeEquals(customer.getId(), id)) {
+ return customer;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/web/CustomerController.java b/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/web/CustomerController.java
new file mode 100644
index 0000000000..aeda87376c
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-hateoas/src/main/java/sample/web/CustomerController.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012-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 sample.web;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.hateoas.EntityLinks;
+import org.springframework.hateoas.ExposesResourceFor;
+import org.springframework.hateoas.Resource;
+import org.springframework.hateoas.Resources;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import sample.domain.Customer;
+import sample.domain.CustomerRepository;
+
+@Controller
+@RequestMapping("/customers")
+@ExposesResourceFor(Customer.class)
+public class CustomerController {
+
+ private final CustomerRepository repository;
+
+ private final EntityLinks entityLinks;
+
+ @Autowired
+ public CustomerController(CustomerRepository repository, EntityLinks entityLinks) {
+ this.repository = repository;
+ this.entityLinks = entityLinks;
+ }
+
+ @RequestMapping(method = RequestMethod.GET)
+ HttpEntity> showCustomers() {
+ Resources resources = new Resources(this.repository.findAll());
+ resources.add(this.entityLinks.linkToCollectionResource(Customer.class));
+ return new ResponseEntity>(resources, HttpStatus.OK);
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+ HttpEntity> showCustomer(@PathVariable Long id) {
+ Resource resource = new Resource(this.repository.findOne(id));
+ resource.add(this.entityLinks.linkToSingleResource(Customer.class, id));
+ return new ResponseEntity>(resource, HttpStatus.OK);
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-hateoas/src/test/java/sample/SampleHateoasApplicationTests.java b/spring-boot-samples/spring-boot-sample-hateoas/src/test/java/sample/SampleHateoasApplicationTests.java
new file mode 100644
index 0000000000..419209b822
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-hateoas/src/test/java/sample/SampleHateoasApplicationTests.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012-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 sample;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.IntegrationTest;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.boot.test.TestRestTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.startsWith;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = SampleHateoasApplication.class)
+@WebAppConfiguration
+@IntegrationTest("server.port:0")
+@DirtiesContext
+public class SampleHateoasApplicationTests {
+
+ @Value("${local.server.port}")
+ private int port;
+
+ @Test
+ public void hasHalLinks() throws Exception {
+ ResponseEntity entity = new TestRestTemplate().getForEntity(
+ "http://localhost:" + this.port + "/customers/1", String.class);
+ assertThat(entity.getStatusCode(), equalTo(HttpStatus.OK));
+ assertThat(entity.getBody(), startsWith("{\"id\":1,\"firstName\":\"Oliver\""
+ + ",\"lastName\":\"Gierke\""));
+ assertThat(entity.getBody(), containsString("_links\":{\"self\":{\"href\""));
+ }
+
+}