Skip to content

Balita1124/spring-example-restfull-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Installation

  • $ git clone https://github.com/Balita1124/spring-example-restfull-api.git
  • $ cd spring-example-restfull-api
  • $ mvn install
  • $ mvn spring-boot:run (ou utiliser l'IDE)

Architecture

I. Base

1. Aller a https://start.spring.io/

2. Creer un projet avec les dependences suivantes:

  • Spring web Starter
  • Mysql Driver
  • Spring Data Jpa
  • Spring Boot DevTools
  • Lombok

3. Ajouter l'entity DateAudit

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(
       value = {"createdAt", "updatedAt"},
       allowGetters = true
)
public abstract class DateAudit implements Serializable {

   @CreatedDate
   @Column(nullable = false, updatable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
   private Instant createdAt;

   @LastModifiedDate
   @Column(nullable = false , columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
   private Instant updatedAt;
}

4. Ajouter le config pour CORS et l'audit pour le JPA

  • CORS
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
   public final long MAX_AGE_SECS = 3600;

   @Override
   public void addCorsMappings(CorsRegistry registry) {
       registry.addMapping("/**")
               .allowedOrigins("*")
               .allowedMethods("HEAD", "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")
               .maxAge(MAX_AGE_SECS);
   }
}
  • Audit JPA
@Configuration
@EnableJpaAuditing
public class AuditingConfig {
}

5. Creer les errors Custom

  • Field Error personnalisé
@Data
public class CustomFieldError {
   private String fieldname;
   private String errorMessage;

   public CustomFieldError(String fieldname, String errorMessage) {
       this.fieldname = fieldname;
       this.errorMessage = errorMessage;
   }
}
  • Section erreur dans la reponse
@Data
public class ErrorSection {
   Object request;
   List<?> errors;

   public ErrorSection(Object request, List<ObjectError> errors) {
       List<CustomFieldError> listErrors = new ArrayList<>();
       if (errors != null)
           errors.forEach(objectError -> listErrors.add(new CustomFieldError(((FieldError) objectError).getField(), objectError.getDefaultMessage())));
       this.request = request;
       this.errors = listErrors;
   }

   public ErrorSection(List<String> errors, Object request) {
       this.request = request;
       this.errors = errors;
   }
}

6. Creer les models

  • Enitity Person
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "PERSONS")
@Data
public class Person extends DateAudit{

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Integer id;

   private String firstname;

   @NotBlank
   private String lastname;

   @JsonFormat(pattern = "dd-MM-yyyy")
   @NotNull
   private Date birth;

   public Person() {
   }

   public Person(String firstname, String lastname, Date birth) {
       this.firstname = firstname;
       this.lastname = lastname;
       this.birth = birth;
   }
}

7. Creer les repository

@Repository
public interface PersonRepository extends CrudRepository<Person, Integer> {
}

8. Creer les services

@Service
public class PersonService {

   private PersonRepository personRepository;

   @Autowired
   public PersonService(PersonRepository personRepository) {
       this.personRepository = personRepository;
   }

   public List<Person> getAll() {
       List<Person> personList = new ArrayList<>();
       personRepository.findAll().forEach(personList::add);
       return personList;
   }

   public Person create(PersonRequest personRequest) {
       Person person = new Person(personRequest.getFirstname(), personRequest.getLastname(), personRequest.getBirth());
       return personRepository.save(person);

   }

   public Person update(Person currentPerson, PersonRequest personRequest) {
       currentPerson.setFirstname(personRequest.getFirstname());
       currentPerson.setLastname(personRequest.getLastname());
       currentPerson.setBirth(personRequest.getBirth());
       return personRepository.save(currentPerson);

   }

   public Person findPersonById(Integer personId) {
       return personRepository.findById(personId).orElse(null);
   }

   public void delete(Person person) {
       personRepository.delete(person);
   }
}

9. Creer les playload

  • ApiResponse
@Data
public class ApiResponse {
   private Boolean success;
   private HttpStatus status;
   private String message;
   private Object data;

   public ApiResponse(Boolean success, HttpStatus status, String message, Object data) {
       this.success = success;
       this.status = status;
       this.message = message;
       this.data = data;
   }
}
  • PersonRequest
@Data
public class PersonRequest {

   private String firstname;

   @NotBlank(message = "Last name can't blank")
   private String lastname;

   @JsonFormat(pattern="dd-MM-yyyy")
   @NotNull(message = "Date of birth")
   private Date birth;
}

10. Creer les controllers

II. Swagger

Swagger est une APi permettant de documenter un Rest Api

1. Ajouter la dependance maven

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>

2. Integrer Swagger dans le Project

@Configuration
@EnableSwagger2
public class SwaggerConfig {                                    
    @Bean
    public Docket api() { 
        return new Docket(DocumentationType.SWAGGER_2)  
          .select()                                  
          .apis(RequestHandlerSelectors.any())              
          .paths(PathSelectors.any())                          
          .build();                                           
    }
}

Il faut visiter http://localhost:8080/v2/api-docs pour verifier si ca marche.

III. Swagger

Une interface utilisateur qui permet d'interagir avec swagger

1. Ajouter la dependence

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

IL faut visiter http://localhost:8080/swagger-ui.html pour voir si ca marche

2. Filtrer l'api à exposer

@Bean
public Docket api() {                
    return new Docket(DocumentationType.SWAGGER_2)          
      .select()                                       
      .apis(RequestHandlerSelectors.basePackage("com.balita.springexamplecrud.controller"))
      .paths(PathSelectors.ant("/persons/*"))                     
      .build();
}

3. Api Info

private ApiInfo apiInfo() {
    return new ApiInfo(
      "My REST API", 
      "Some custom description of API.", 
      "API TOS", 
      "Terms of service", 
      new Contact("John Doe", "www.example.com", "myeaddress@company.com"), 
      "License of API", "API license URL", Collections.emptyList());
}