Home > Software design >  Calling External API from Spring Boot Web UI
Calling External API from Spring Boot Web UI

Time:12-22

I have a Spring Boot WebMVC application (with Thymeleaf) that is moving away from a direct database connection in favor of API calls to another service. I am wondering what the best architecture would be for calling the API and displaying the results to the user. Would RestTemplate be better to put in the Service class, or the Controller class (especially when thinking about error handling)? Also, would WebClient be better over RestTemplate even though it isn't using WebFlux?

Here is currently what I am thinking:

Entity:

public class Entity {
    public String id;
    public String name;
    ...
}

Service:

public class EntityService {
    @Autowired
    private RestTemplate restTemplate;

    public List<Entity> getAllEntities() {
        return restTemplate.getForObject("https://localhost.com:8081/entities", Entity.class);
    }
}

Controller:

public class EntityController {
    @Autowired
    private EntityService entityService;

    @GetMapping("/entities")
    public String getAllEntities(Model model) {
        model.addAttribute(entityList, entityService.getAllEntities())
        return "entity"
    }
}

HTML:

<!-- entity.html -->

<head>
...
</head>
<body>    
    <div th:each="entity : #{entityList}">
        <label th:text="${entity.id}"/>
        <label th:text="${entity.name}"/>
    </div>
</body>

CodePudding user response:

"It depends" is the answer to all your questions :)

So to work out the answers, you need to think about your application, how big it's going to get and how you will keep it all under control as it matures. The things I'd consider are:

  • How many upstream API calls will your app make? If there's only 1 and virtually no business logic, then a Service layer might just add noise, however if you start doing things other than just straight up displaying bean properties then the less code sitting in the Controller the clearer the app will be to the next person. I like to keep Controllers specific to the transport - eg HTTP or gRPC - and dealing with things like response codes, headers etc, so I generally move the ifs off to a service layer.

  • RestTemplate vs WebClient is usually a great distraction. If you are using traditional blocking Spring Boot, use RestTemplate, if you are using Reactive then use WebClient. It doesn't really matter that much from the application code perspective, it's usually not a huge job to replace one with the other if you've got the application architecture thought out.

Another thing - try avoid a controller package, a service package and a model package, group all this stuff together under the business context - in this case an Entity, but we all know there is going to be a service, controller, models etc etc.

You really don't want to have 300 controller classes in the controller package, best they are grouped together in a way that would make sense to the users or the product owner of an app..

My final bit of advice would be to not be afraid to change as the app gets bigger. Ensure your tests are reliable enough that you can refactor the app as you go. Things like replacing RestTemplate with something else, changing the app structure and so on.

  • Related