API handlers

We will put API handlers in separate controllers for different resources. The controllers that we will need to create are the following:

  • com.taskagile.web.apis.MeController to handle the /api/me request
  • com.taskagile.web.apis.BoardController to handle the /api/boards request
  • com.taskagile.web.apis.TeamController to handle the /api/teams request

One difference from RegistrationApiController is that we will need to get the information of the logged in user, or, let's call it the current user, from Spring Security's SecurityContext. There are several ways of retrieving the current user's information:

  • We can get it from HttpServletRequest.getUsePrincipal(). That will require Spring to inject HttpServletRequest into the API handler method.
  • We can also get it from SecurityContextHolder directly, like this—SecurityContextHolder.getContext().getAuthentication().
  • We can create an annotation that is applied with Spring Security's @AuthenticationPrincipal, and then we can ask Spring to inject our implementation of UserDetails into the API handler method.

We will take the last approach since it makes the code easy to understand and easy to test. The annotation we create is called @CurrentUser, which looks like this:

@Target({ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@AuthenticationPrincipal
public @interface CurrentUser {
}

As you can see, it is a very simple annotation. The key here is to apply the @AuthenticationPrincipal annotation to it.

With this annotation, we can get the current user information in BoardController, TeamController, and MeController easily. BoardController looks as follows:

@Controller
public class BoardApiController {
...
@PostMapping("/api/boards")
public ResponseEntity<ApiResult> createBoard(
@RequestBody CreateBoardPayload payload,
@CurrentUser SimpleUser currentUser) {

Board board =
boardService.createBoard(payload.
toCommand(currentUser.getUserId()));
return CreateBoardResult.build(board);
}
}

As you can see, in the createBoard() API handler method, we apply the @CurrentUser annotation to the currentUser parameter, and Spring will pass an instance of SimpleUser to our method. For this method, we use it to retrieve the current user's ID and create CreateBoardCommand from the instance of CreateBoardPayload, which is a class for capturing the parameters in the request body. Once the board is created by the service, we use the CreateBoardResult class to create ResponseEntity to send the new board information back to the frontend.

TeamController is similar to BoardController, and we will not list its code here. MeController looks as follows:

@Controller
public class MeApiController {
...
@GetMapping("/api/me")
public ResponseEntity<ApiResult> getMyData(
@CurrentUser SimpleUser currentUser) {

List<Team> teams =
teamService.findTeamsByUserId(currentUser.getUserId());
List<Board> boards =
boardService.findBoardsByMembership(currentUser.getUserId());
return MyDataResult.build(currentUser, teams, boards);
}
}

As you can see, we call the teamService.findTeamsByUserId() method and boardService.findBoardsByMembership() method to get all the teams and boards the current user has access to, and then use MyDataResult to create ResponseEntity.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.213.44