-
Notifications
You must be signed in to change notification settings - Fork 524
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Lesson 5: Giving Your Microservice a REST
- Loading branch information
Showing
23 changed files
with
561 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
:compat-mode: | ||
= Lesson 5: Giving Your Microservice a REST | ||
|
||
_Why the web is a existence proof of the HTTP architecture and how to build | ||
services that exploit that._ | ||
|
||
- link:livelessons-rest-basic[Basic] | ||
- link:livelessons-rest-sync[Sync] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>livelessons</groupId> | ||
<artifactId>livelessons-rest</artifactId> | ||
<version>1.0.0-SNAPSHOT</version> | ||
</parent> | ||
<artifactId>livelessons-rest-basic</artifactId> | ||
<properties> | ||
<main.basedir>../..</main.basedir> | ||
</properties> | ||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-web</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-data-rest</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-data-jpa</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.h2database</groupId> | ||
<artifactId>h2</artifactId> | ||
</dependency> | ||
</dependencies> | ||
</project> |
26 changes: 26 additions & 0 deletions
26
livelessons-rest/livelessons-rest-basic/src/main/java/demo/Application.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package demo; | ||
|
||
import java.util.Arrays; | ||
|
||
import org.springframework.boot.CommandLineRunner; | ||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.context.annotation.Bean; | ||
|
||
@SpringBootApplication | ||
public class Application { | ||
|
||
@Bean | ||
CommandLineRunner commandLineRunner(PersonRepository personRepository) { | ||
return args -> { | ||
Arrays.asList("Phil", "Josh").forEach(name -> personRepository | ||
.save(new Person(name, (name + "@email.com").toLowerCase()))); | ||
personRepository.findAll().forEach(System.out::println); | ||
}; | ||
} | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(Application.class, args); | ||
} | ||
|
||
} |
44 changes: 44 additions & 0 deletions
44
livelessons-rest/livelessons-rest-basic/src/main/java/demo/Person.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package demo; | ||
|
||
import javax.persistence.Entity; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.Id; | ||
|
||
@Entity | ||
public class Person { | ||
|
||
@Id | ||
@GeneratedValue | ||
private Long id; | ||
|
||
private String name; | ||
|
||
private String email; | ||
|
||
Person() { | ||
} | ||
|
||
public Person(String name, String email) { | ||
this.name = name; | ||
this.email = email; | ||
} | ||
|
||
public Long getId() { | ||
return this.id; | ||
} | ||
|
||
public String getName() { | ||
return this.name; | ||
} | ||
|
||
public String getEmail() { | ||
return this.email; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Person{" + "id=" + id + ", name='" + name + '\'' + ", email='" + email | ||
+ '\'' + '}'; | ||
} | ||
|
||
} |
69 changes: 69 additions & 0 deletions
69
livelessons-rest/livelessons-rest-basic/src/main/java/demo/PersonPhotoRestController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package demo; | ||
|
||
import java.io.File; | ||
import java.io.FileNotFoundException; | ||
import java.io.FileOutputStream; | ||
import java.net.URI; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.core.io.FileSystemResource; | ||
import org.springframework.core.io.Resource; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.util.Assert; | ||
import org.springframework.util.FileCopyUtils; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestMethod; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import org.springframework.web.multipart.MultipartFile; | ||
import org.springframework.web.servlet.support.ServletUriComponentsBuilder; | ||
|
||
@RestController | ||
@RequestMapping("/people/{id}/photo") | ||
public class PersonPhotoRestController { | ||
|
||
private File root; | ||
|
||
@Autowired | ||
private PersonRepository personRepository; | ||
|
||
@Value("${user.home}") | ||
public void setUserHome(String home) { | ||
this.root = new File(home, "Desktop/images"); | ||
Assert.isTrue(this.root.exists() || this.root.mkdirs(), | ||
"The path '" + this.root.getAbsolutePath() + "' must exist."); | ||
} | ||
|
||
@RequestMapping(method = RequestMethod.GET) | ||
public ResponseEntity<Resource> read(@PathVariable Long id) throws Exception { | ||
Person person = this.personRepository.findOne(id); | ||
File file = fileFor(person); | ||
if (!file.exists()) { | ||
throw new FileNotFoundException(file.getAbsolutePath()); | ||
} | ||
HttpHeaders httpHeaders = new HttpHeaders(); | ||
httpHeaders.setContentType(MediaType.IMAGE_JPEG); | ||
Resource resource = new FileSystemResource(file); | ||
return new ResponseEntity<>(resource, httpHeaders, HttpStatus.OK); | ||
} | ||
|
||
@RequestMapping(method = { RequestMethod.POST, RequestMethod.PUT }) | ||
public ResponseEntity<?> write(@PathVariable Long id, | ||
@RequestParam MultipartFile file) throws Exception { | ||
Person person = this.personRepository.findOne(id); | ||
FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(fileFor(person))); | ||
URI location = ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand(id) | ||
.toUri(); | ||
return ResponseEntity.created(location).build(); | ||
} | ||
|
||
private File fileFor(Person person) { | ||
return new File(this.root, Long.toString(person.getId())); | ||
} | ||
|
||
} |
14 changes: 14 additions & 0 deletions
14
livelessons-rest/livelessons-rest-basic/src/main/java/demo/PersonRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package demo; | ||
|
||
import java.util.Collection; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.repository.query.Param; | ||
import org.springframework.data.rest.core.annotation.RepositoryRestResource; | ||
|
||
@RepositoryRestResource(path = "people") | ||
interface PersonRepository extends JpaRepository<Person, Long> { | ||
|
||
Collection<Person> findByEmail(@Param("email") String e); | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
livelessons-rest/livelessons-rest-basic/src/main/java/demo/PersonResourceProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package demo; | ||
|
||
import org.springframework.hateoas.Link; | ||
import org.springframework.hateoas.Resource; | ||
import org.springframework.hateoas.ResourceProcessor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.servlet.support.ServletUriComponentsBuilder; | ||
import org.springframework.web.util.UriComponents; | ||
|
||
@Component | ||
public class PersonResourceProcessor implements ResourceProcessor<Resource<Person>> { | ||
|
||
@Override | ||
public Resource<Person> process(Resource<Person> resource) { | ||
String id = Long.toString(resource.getContent().getId()); | ||
UriComponents uriComponents = ServletUriComponentsBuilder.fromCurrentContextPath() | ||
.path("/people/{id}/photo").buildAndExpand(id); | ||
String uri = uriComponents.toUriString(); | ||
resource.add(new Link(uri, "photo")); | ||
return resource; | ||
} | ||
|
||
} |
16 changes: 16 additions & 0 deletions
16
...-rest/livelessons-rest-basic/src/main/java/demo/SimpleRepositoryRestMvcConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package demo; | ||
|
||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.rest.core.config.RepositoryRestConfiguration; | ||
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration; | ||
|
||
@Configuration | ||
public class SimpleRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration { | ||
|
||
@Override | ||
protected void configureRepositoryRestConfiguration( | ||
RepositoryRestConfiguration config) { | ||
config.exposeIdsFor(Person.class); | ||
} | ||
|
||
} |
4 changes: 4 additions & 0 deletions
4
livelessons-rest/livelessons-rest-basic/src/main/resources/data.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
insert into person( name, email) values ( 'josh', 'josh@email.com'); | ||
insert into person( name, email) values ( 'john', 'john@email.com'); | ||
insert into person( name, email) values ( 'yoana', 'yoana@email.com'); | ||
insert into person( name, email) values ( 'emo', 'emo@email.com'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>livelessons</groupId> | ||
<artifactId>livelessons-rest</artifactId> | ||
<version>1.0.0-SNAPSHOT</version> | ||
</parent> | ||
<artifactId>livelessons-rest-errors</artifactId> | ||
<properties> | ||
<main.basedir>../..</main.basedir> | ||
</properties> | ||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-web</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-data-rest</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.hateoas</groupId> | ||
<artifactId>spring-hateoas</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.plugin</groupId> | ||
<artifactId>spring-plugin-core</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-data-jpa</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.h2database</groupId> | ||
<artifactId>h2</artifactId> | ||
</dependency> | ||
</dependencies> | ||
</project> |
26 changes: 26 additions & 0 deletions
26
livelessons-rest/livelessons-rest-errors/src/main/java/demo/Application.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package demo; | ||
|
||
import java.util.Arrays; | ||
|
||
import org.springframework.boot.CommandLineRunner; | ||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.context.annotation.Bean; | ||
|
||
@SpringBootApplication | ||
public class Application { | ||
|
||
@Bean | ||
public CommandLineRunner commandLineRunner(PersonRepository personRepository) { | ||
return args -> { | ||
Arrays.asList("Phil", "Josh").forEach(name -> personRepository | ||
.save(new Person(name, (name + "@email.com").toLowerCase()))); | ||
personRepository.findAll().forEach(System.out::println); | ||
}; | ||
} | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(Application.class, args); | ||
} | ||
|
||
} |
44 changes: 44 additions & 0 deletions
44
livelessons-rest/livelessons-rest-errors/src/main/java/demo/Person.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package demo; | ||
|
||
import javax.persistence.Entity; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.Id; | ||
|
||
@Entity | ||
public class Person { | ||
|
||
@Id | ||
@GeneratedValue | ||
private Long id; | ||
|
||
private String name; | ||
|
||
private String email; | ||
|
||
Person() { | ||
} | ||
|
||
public Person(String name, String email) { | ||
this.name = name; | ||
this.email = email; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public String getEmail() { | ||
return email; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Person{" + "id=" + id + ", name='" + name + '\'' + ", email='" + email | ||
+ '\'' + '}'; | ||
} | ||
|
||
} |
36 changes: 36 additions & 0 deletions
36
livelessons-rest/livelessons-rest-errors/src/main/java/demo/PersonControllerAdvice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package demo; | ||
|
||
import java.io.FileNotFoundException; | ||
import java.util.Optional; | ||
|
||
import org.springframework.hateoas.VndErrors; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.web.bind.annotation.ControllerAdvice; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.ResponseBody; | ||
import org.springframework.web.bind.annotation.ResponseStatus; | ||
|
||
@ControllerAdvice | ||
@RequestMapping(produces = "application/vnd.error") | ||
@ResponseBody | ||
public class PersonControllerAdvice { | ||
|
||
@ResponseStatus(value = HttpStatus.NOT_FOUND) | ||
@ExceptionHandler(FileNotFoundException.class) | ||
public VndErrors fileNotFoundException(FileNotFoundException ex) { | ||
return this.error(ex, ex.getLocalizedMessage()); | ||
} | ||
|
||
@ResponseStatus(value = HttpStatus.NOT_FOUND) | ||
@ExceptionHandler(PersonNotFoundException.class) | ||
public VndErrors personNotFoundException(PersonNotFoundException e) { | ||
return this.error(e, e.getPersonId() + ""); | ||
} | ||
|
||
private <E extends Exception> VndErrors error(E e, String logref) { | ||
String msg = Optional.of(e.getMessage()).orElse(e.getClass().getSimpleName()); | ||
return new VndErrors(logref, msg); | ||
} | ||
|
||
} |
Oops, something went wrong.