Skip to main content

Couche service

Les controllers sont suffisants pour créer une application, mais on se heurte rapidement à la limite de la réusabilité du code.

Si vous avez des règles de validation ou des règles métier concernant plusieurs controllers, il serait intéressant de les regrouper pour éviter de la recopie de code.

C'est le but des classes Service (annotées @Service, et instanciées par Spring Core) que vous pouvez injecter dans vos différents controller.

Par exemple, dans le cadre d'une application de gestion contenu (CMS) vous avez deux controllers permettant de créer un article :

  • un controller offrant une page web pour qu'un utilisateur puisse le rédiger dans son navigateur
  • un controller offrant une API permettant à un système externe de venir créer l'article en JSON

Le code permettant de récupérer l'article est différent (dans un cas c'est un formulaire depuis un navigateur, dans l'autre un appel REST), par contre, le code permettant de valider l'article et ses champs et le fait de l'enregistrer en base peut être commun.

La réponse dans le premier cas sera une réponse HTML, dans le deuxième cas une réponse JSON. On ne veut pas coder deux fois le mécanisme de validation et d'enregistrement en base de données.

Voici le controller avant d'ajouter le service :

@RestController
@RequestMapping("/article")
public class ArticleController {

@PostMapping
public Article creerArticle(Article article) {
// code permettant d'enregistrer l'article
}
}

On créée ensuite une classe service, qui contiendra le code fonctionnel sur la création de l'article (les règles de validation, les différents traitements ...) :

@Service
public class ArticleService {

@Autowired
private ArticleRepository articleRepository;

public Article enregistrerArticle(Article article) {
// validation des champs
// enregistrement en base
// mise à jour des statistiques du site ...
article = articleRepository.save(article);
return article;
}
}

Une fois le service créé, on peut l'injecter dans chaque controller, et appeler la méthode d'enregistrement d'article :

@RestController
@RequestMapping("/article")
public class ArticleController {

@Autowired
private ArticleService articleService;

@PostMapping
public Article postArticle(@RequestBody Article article) {
return articleService.enregistrerArticle(article);
}
}