Skip to main content

Quiz: Service Layer and Architecture

Test your knowledge on the service layer, validation, and MVC architecture.

30 questions - Click on each question to reveal the answer.


Questions 1-10: Service Layer​

Question 1: What is the role of the Service layer in the MVC architecture?

Answer: The Service layer contains the application's business logic. It:

  • Orchestrates operations between controllers and repositories
  • Applies business rules
  • Manages transactions
  • Is independent of the HTTP protocol

Question 2: Which annotation is used to declare a Spring service?

Answer: @Service - It is a specialized stereotype of @Component indicating that the class contains business logic.

@Service
public class UserService {
// business logic
}

Question 3: Why not put business logic in the controller?

Answer: Separating business logic from the controller allows:

  • Reusability: the service can be called by multiple controllers
  • Testability: test logic without HTTP
  • Maintainability: more organized code
  • Separation of concerns: each layer has a specific role

Question 4: How to inject a Repository into a Service?

Answer: By constructor injection (recommended):

@Service
public class UserService {

private final UserRepository userRepository;

public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}

Question 5: What is a DTO (Data Transfer Object)?

Answer: A DTO is a simple object used to transfer data between layers. It:

  • Contains no business logic
  • Exposes only necessary data
  • Protects the JPA entity from direct exposure
  • Allows data formatting for the API

Question 6: Why use DTOs instead of JPA entities directly?

Answer:

  1. Security: do not expose sensitive fields (password)
  2. Performance: avoid lazy loading of relationships
  3. Flexibility: different format from the entity
  4. Decoupling: internal changes do not affect the API
  5. Validation: specific input/output rules

Question 7: How to convert an entity to a DTO?

Answer: Several approaches:

// 1. Manual method
public UserDto toDto(User user) {
return new UserDto(user.getId(), user.getName(), user.getEmail());
}

// 2. With MapStruct
@Mapper
public interface UserMapper {
UserDto toDto(User user);
}

// 3. With ModelMapper
modelMapper.map(user, UserDto.class);

Question 8: What is the difference between a RequestDTO and a ResponseDTO?

Answer:

  • RequestDTO: incoming data (creation, update), contains validation
  • ResponseDTO: outgoing data, formatted for the client
// Request
public class CreateUserRequest {
@NotBlank
private String email;
@Size(min = 8)
private String password;
}

// Response
public class UserResponse {
private Long id;
private String email;
// No password!
}

Question 9: How to handle errors in the Service layer?

Answer: Throw custom exceptions:

@Service
public class UserService {

public User findById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException("User not found: " + id));
}
}

These exceptions are then handled by @ControllerAdvice.


Question 10: What is @Transactional on a service?

Answer: @Transactional automatically manages transactions:

  • Starts a transaction at the beginning of the method
  • Commits if successful
  • Rolls back if an exception occurs
@Service
@Transactional
public class OrderService {
// All methods are transactional
}

Questions 11-20: Validation​

Question 11: What dependency to add for validation?

Answer: spring-boot-starter-validation

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Question 12: How to enable validation on a controller?

Answer: With @Valid or @Validated on the parameter:

@PostMapping
public ResponseEntity<User> create(@Valid @RequestBody CreateUserRequest request) {
// If validation fails, MethodArgumentNotValidException is thrown
}

Question 13: What are common validation annotations?

Answer:

AnnotationDescription
@NotNullMust not be null
@NotBlankNot null, not empty, not whitespace
@NotEmptyNot null and not empty
@Size(min, max)Size between min and max
@Min, @MaxNumeric min/max value
@EmailValid email format
@PatternCustom regex
@Past, @FutureDate in the past/future

Question 14: How to customize the validation error message?

Answer: With the message attribute:

public class CreateUserRequest {

@NotBlank(message = "Email is required")
@Email(message = "Invalid email format")
private String email;

@Size(min = 8, message = "Password must be at least 8 characters")
private String password;
}

Question 15: How to create a custom validation?

Answer: Create an annotation and a validator:

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueEmailValidator.class)
public @interface UniqueEmail {
String message() default "Email already used";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {
@Override
public boolean isValid(String email, ConstraintValidatorContext context) {
// Check if email exists
}
}

Question 16: What is the difference between @Valid and @Validated?

Answer:

  • @Valid: standard Java (JSR-380), cascades validation
  • @Validated: Spring, supports validation groups
// Validation groups
public interface OnCreate {}
public interface OnUpdate {}

@NotNull(groups = OnUpdate.class)
private Long id;

@Validated(OnCreate.class)
public void create(...) { }

Question 17: How to validate query parameters?

Answer: Add @Validated on the controller:

@RestController
@Validated
public class UserController {

@GetMapping("/users")
public List<User> search(
@RequestParam @Min(0) int page,
@RequestParam @Max(100) int size) {
// ...
}
}

Question 18: How to validate a nested object?

Answer: Use @Valid on the nested field:

public class OrderRequest {

@Valid // Cascades validation
@NotNull
private AddressDto shippingAddress;
}

public class AddressDto {
@NotBlank
private String street;
@NotBlank
private String city;
}

Question 19: How to retrieve validation errors?

Answer: Via BindingResult or @ExceptionHandler:

// Option 1: BindingResult
@PostMapping
public ResponseEntity<?> create(@Valid @RequestBody Request req, BindingResult result) {
if (result.hasErrors()) {
return ResponseEntity.badRequest().body(result.getAllErrors());
}
}

// Option 2: ControllerAdvice (recommended)
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidation(MethodArgumentNotValidException ex) {
// Extract errors
}

Question 20: What is service-level validation?

Answer: Validation of business logic (not just format):

@Service
public class OrderService {

public Order createOrder(OrderRequest request) {
// Business validation
if (request.getQuantity() > productService.getStock(request.getProductId())) {
throw new InsufficientStockException("Insufficient stock");
}
// ...
}
}

Questions 21-30: Architecture​

Question 21: What are the 3 main layers of the MVC architecture?

Answer:

  1. Controller (Presentation): handles HTTP, input validation
  2. Service (Business): business logic, transactions
  3. Repository (Data): database access
Client → Controller → Service → Repository → Database

Question 22: In which layer should transaction management be placed?

Answer: In the Service layer. This is where the business logic that defines what constitutes an atomic unit of work is located.

@Service
@Transactional
public class TransferService {
public void transfer(Long fromId, Long toId, BigDecimal amount) {
// The entire operation is atomic
}
}

Question 23: How to organize packages in a Spring Boot project?

Answer: By layer or by feature:

// By layer
com.example.app
├── controller/
├── service/
├── repository/
├── model/
└── dto/

// By feature (recommended for large projects)
com.example.app
├── user/
│ ├── UserController
│ ├── UserService
│ └── UserRepository
├── order/
└── product/

Question 24: What is the Single Responsibility Principle (SRP)?

Answer: A class should have only one reason to change. Each class has a single responsibility:

  • Controller: handle HTTP requests
  • Service: business logic
  • Repository: data access

Bad example: a controller that does everything (HTTP + business + DB).


Question 25: Why use interfaces for services?

Answer:

  1. Decoupling: clients depend on the abstraction
  2. Testability: easy to mock
  3. Flexibility: change implementation
  4. Proxying: Spring AOP works better
public interface UserService {
User findById(Long id);
}

@Service
public class UserServiceImpl implements UserService { }

Question 26: What is a @ControllerAdvice?

Answer: A component that handles exceptions globally for all controllers:

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(UserNotFoundException ex) {
return ResponseEntity.status(404).body(new ErrorResponse(ex.getMessage()));
}
}

Question 27: How to structure a standard error response?

Answer: Create a consistent error DTO:

public class ErrorResponse {
private LocalDateTime timestamp;
private int status;
private String error;
private String message;
private String path;
}

// Or ProblemDetail format (RFC 7807)

Question 28: What is the difference between @RestController and @Controller?

Answer:

  • @Controller: returns views (HTML)
  • @RestController: returns data (JSON/XML)

@RestController = @Controller + @ResponseBody

@RestController  // Everything is JSON
public class UserController { }

@Controller
public class ViewController {
@GetMapping("/")
public String home() {
return "index"; // Thymeleaf view
}
}

Question 29: How to handle appropriate HTTP codes?

Answer: Use ResponseEntity:

@PostMapping
public ResponseEntity<User> create(@RequestBody UserRequest req) {
User user = userService.create(req);
return ResponseEntity
.status(HttpStatus.CREATED) // 201
.body(user);
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build(); // 204
}

Question 30: What are common HTTP codes in REST?

Answer:

CodeMeaningUsage
200OKSuccessful GET, PUT
201CreatedSuccessful POST
204No ContentSuccessful DELETE
400Bad RequestValidation failed
401UnauthorizedNot authenticated
403ForbiddenNot authorized
404Not FoundResource not found
500Server ErrorInternal error

Score​

ScoreLevel
27-30Excellent - Mastered architecture
21-26Good - Some revisions needed
15-20Average - Review the chapters
Less than 15Needs improvement - Go back to basics

Back to Module 3