diff --git a/springfox/pom.xml b/springfox/pom.xml
new file mode 100644
index 0000000000..cbea0baa39
--- /dev/null
+++ b/springfox/pom.xml
@@ -0,0 +1,97 @@
+
+
+ 4.0.0
+ com.baeldung.web
+ springfox
+ springfox
+ SpringFox
+ war
+
+
+ parent-boot-2
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../parent-boot-2
+
+
+
+
+
+
+ jcenter
+ jcenter
+ https://jcenter.bintray.com/
+
+
+ jcenter-snapshots
+ jcenter
+ http://oss.jfrog.org/artifactory/oss-snapshot-local/
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-rest
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+
+
+
+
+
+ io.springfox
+ springfox-swagger2
+ 3.0.0-SNAPSHOT
+
+
+ io.springfox
+ springfox-swagger-ui
+ 3.0.0-SNAPSHOT
+
+
+ io.springfox
+ springfox-data-rest
+ 3.0.0-SNAPSHOT
+
+
+ io.springfox
+ springfox-bean-validators
+ 3.0.0-SNAPSHOT
+
+
+
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+ com.baeldung.springfox.SpringfoxApplication
+ 27.0.1-jre
+
+
diff --git a/springfox/src/main/java/com/baeldung/springfox/SpringfoxApplication.java b/springfox/src/main/java/com/baeldung/springfox/SpringfoxApplication.java
new file mode 100644
index 0000000000..20f560f9ef
--- /dev/null
+++ b/springfox/src/main/java/com/baeldung/springfox/SpringfoxApplication.java
@@ -0,0 +1,65 @@
+package com.baeldung.springfox;
+
+import static springfox.documentation.builders.PathSelectors.regex;
+
+import java.util.Collections;
+import java.util.function.Predicate;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Import;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import com.baeldung.springfox.plugin.EmailAnnotationPlugin;
+import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.data.rest.configuration.SpringDataRestConfiguration;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
+
+
+@SpringBootApplication
+@EnableSwagger2WebMvc
+@EntityScan("com.baeldung.springfox.model")
+@ComponentScan("com.baeldung.springfox.controller")
+@EnableJpaRepositories("com.baeldung.springfox.repository")
+@Import({SpringDataRestConfiguration.class, BeanValidatorPluginsConfiguration.class})
+public class SpringfoxApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringfoxApplication.class, args);
+ }
+
+ @Bean
+ public Docket springfoxAppInfo() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .groupName("baeldung-springfox-api")
+ .select()
+ .paths(paths())
+ .build()
+ .apiInfo(apiInfo());
+ }
+
+ private Predicate paths() {
+ return regex("/users.*").or(regex("/api.*"));
+ }
+
+ private ApiInfo apiInfo() {
+ return new ApiInfo(
+ "Springfox API specification",
+ "User REST and Spring Data APIs",
+ "",
+ "",
+ null,
+ "License of API", "API license URL", Collections.emptyList());
+ }
+
+ @Bean
+ public EmailAnnotationPlugin emailPlugin() {
+ return new EmailAnnotationPlugin();
+ }
+
+}
diff --git a/springfox/src/main/java/com/baeldung/springfox/controller/UserController.java b/springfox/src/main/java/com/baeldung/springfox/controller/UserController.java
new file mode 100644
index 0000000000..6a827bb757
--- /dev/null
+++ b/springfox/src/main/java/com/baeldung/springfox/controller/UserController.java
@@ -0,0 +1,42 @@
+package com.baeldung.springfox.controller;
+
+import static org.springframework.web.bind.annotation.RequestMethod.GET;
+import static org.springframework.web.bind.annotation.RequestMethod.POST;
+
+import java.util.Optional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.baeldung.springfox.model.User;
+import com.baeldung.springfox.repository.UserRepository;
+
+@Controller
+@RequestMapping(value = "/api/user", produces = MediaType.APPLICATION_JSON_VALUE)
+public class UserController {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @RequestMapping(method = POST)
+ @ResponseBody
+ public ResponseEntity createUser(@RequestBody User user) {
+ userRepository.save(user);
+ return new ResponseEntity<>(user, HttpStatus.OK);
+ }
+
+ @RequestMapping(method = GET)
+ @ResponseBody
+ public ResponseEntity getUser(@RequestParam Long id) {
+ Optional user = userRepository.findById(id);
+ return new ResponseEntity<>(user.get(), HttpStatus.OK);
+ }
+
+}
diff --git a/springfox/src/main/java/com/baeldung/springfox/model/User.java b/springfox/src/main/java/com/baeldung/springfox/model/User.java
new file mode 100644
index 0000000000..90de0deea5
--- /dev/null
+++ b/springfox/src/main/java/com/baeldung/springfox/model/User.java
@@ -0,0 +1,68 @@
+package com.baeldung.springfox.model;
+
+import javax.persistence.Id;
+import javax.validation.constraints.Email;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.persistence.Entity;
+
+@Entity
+public class User{
+
+ @Id
+ private Long id;
+
+ @NotNull(message = "First Name cannot be null")
+ private String firstName;
+
+ private String lastName;
+
+ @Min(value = 15, message = "Age should not be less than 15")
+ @Max(value = 65, message = "Age should not be greater than 65")
+ private int age;
+
+ @Email(regexp=".@.\\..*", message = "Email should be valid")
+ private String email;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ }
diff --git a/springfox/src/main/java/com/baeldung/springfox/plugin/EmailAnnotationPlugin.java b/springfox/src/main/java/com/baeldung/springfox/plugin/EmailAnnotationPlugin.java
new file mode 100644
index 0000000000..2e5e57aec5
--- /dev/null
+++ b/springfox/src/main/java/com/baeldung/springfox/plugin/EmailAnnotationPlugin.java
@@ -0,0 +1,39 @@
+package com.baeldung.springfox.plugin;
+
+import static springfox.bean.validators.plugins.Validators.annotationFromBean;
+
+import java.util.Optional;
+
+import javax.validation.constraints.Email;
+
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import springfox.bean.validators.plugins.Validators;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.schema.ModelPropertyBuilderPlugin;
+import springfox.documentation.spi.schema.contexts.ModelPropertyContext;
+
+@Component
+@Order(Validators.BEAN_VALIDATOR_PLUGIN_ORDER)
+public class EmailAnnotationPlugin implements ModelPropertyBuilderPlugin {
+
+ @Override
+ public boolean supports(DocumentationType delimiter) {
+ return true;
+ }
+
+ /**
+ * read Email annotation
+ */
+ @Override
+ public void apply(ModelPropertyContext context) {
+ Optional email = annotationFromBean(context, Email.class);
+ if (email.isPresent()) {
+ context.getBuilder().pattern(email.get().regexp());
+ context.getBuilder().example("email@email.com");
+ }
+ }
+
+}
+
diff --git a/springfox/src/main/java/com/baeldung/springfox/repository/UserRepository.java b/springfox/src/main/java/com/baeldung/springfox/repository/UserRepository.java
new file mode 100644
index 0000000000..16303bc6d0
--- /dev/null
+++ b/springfox/src/main/java/com/baeldung/springfox/repository/UserRepository.java
@@ -0,0 +1,11 @@
+package com.baeldung.springfox.repository;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.springfox.model.User;
+
+@Repository
+public interface UserRepository extends CrudRepository {
+
+}
diff --git a/springfox/src/main/java/com/baeldung/springfox/repository/UserRestRepository.java b/springfox/src/main/java/com/baeldung/springfox/repository/UserRestRepository.java
new file mode 100644
index 0000000000..9edce50af4
--- /dev/null
+++ b/springfox/src/main/java/com/baeldung/springfox/repository/UserRestRepository.java
@@ -0,0 +1,11 @@
+package com.baeldung.springfox.repository;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.rest.core.annotation.RepositoryRestResource;
+
+import com.baeldung.springfox.model.User;
+
+@RepositoryRestResource(collectionResourceRel = "users", path = "users")
+public interface UserRestRepository extends CrudRepository {
+
+}
diff --git a/springfox/src/main/resources/application.properties b/springfox/src/main/resources/application.properties
new file mode 100644
index 0000000000..3b4076297b
--- /dev/null
+++ b/springfox/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+### Spring Boot default error handling configurations
+#server.error.whitelabel.enabled=false
+#server.error.include-stacktrace=always