diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionController.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionController.java
new file mode 100644
index 0000000000000000000000000000000000000000..40f90e063d814cc94143246ef855a32e0bdb59a1
--- /dev/null
+++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionController.java
@@ -0,0 +1,116 @@
+package org.fuseri.moduleexercise.question;
+
+import jakarta.persistence.EntityNotFoundException;
+import org.fuseri.model.dto.common.Result;
+import org.fuseri.model.dto.exercise.QuestionCreateDto;
+import org.fuseri.model.dto.exercise.QuestionDto;
+import org.fuseri.moduleexercise.answer.Answer;
+import org.fuseri.moduleexercise.answer.AnswerMapper;
+import org.fuseri.moduleexercise.answer.AnswerService;
+import org.fuseri.moduleexercise.exercise.Exercise;
+import org.fuseri.moduleexercise.exercise.ExerciseService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.server.ResponseStatusException;
+
+import java.util.HashSet;
+
+/**
+ * Represent a REST API controller for questions
+ * Handle HTTP requests related to questions
+ */
+@RestController
+@RequestMapping("/questions")
+public class QuestionController {
+
+    private final QuestionService questionService;
+    private final ExerciseService exerciseService;
+    private final AnswerService answerService;
+    private final QuestionMapper questionMapper;
+    private final AnswerMapper answerMapper;
+
+    /**
+     * Constructor for QuestionController
+     *
+     * @param questionService the service responsible for handling question-related logic
+     * @param exerciseService the service responsible for handling exercise-related logic
+     * @param answerService   the service responsible for handling answer-related logic
+     * @param answerMapper    the mapper responsible for converting between Answer DTOs and entities
+     * @param questionMapper  the mapper responsible for converting between Question DTOs and entities
+     */
+    @Autowired
+    public QuestionController(QuestionService questionService, ExerciseService exerciseService, AnswerService answerService,
+                              QuestionMapper questionMapper, AnswerMapper answerMapper) {
+        this.questionService = questionService;
+        this.exerciseService = exerciseService;
+        this.answerService = answerService;
+        this.questionMapper = questionMapper;
+        this.answerMapper = answerMapper;
+    }
+
+    /**
+     * Find a question by ID.
+     *
+     * @param id the ID of the question to find
+     * @return a QuestionDto object representing the found question
+     */
+    @GetMapping("/{id}")
+    public QuestionDto find(@PathVariable String id) {
+        var a = questionService.find(id);
+        return questionMapper.toDto(a);
+    }
+
+    /**
+     * Find questions by exercise ID and return them in a paginated format
+     *
+     * @param exerciseId the ID of the exercise to find questions for
+     * @param page       the page number of the questions to retrieve
+     * @return a Result object containing a list of QuestionDto objects and pagination information
+     */
+    @GetMapping("/exercise/{exerciseId}")
+    public Result<QuestionDto> findByExerciseId(@PathVariable String exerciseId, @RequestParam int page) {
+        Page<Question> questions = questionService.findByExerciseId(exerciseId, page);
+        return questionMapper.toResult(questions);
+    }
+
+    /**
+     * Add a new question to an exercise
+     *
+     * @param dto a QuestionCreateDto object representing the new question to add
+     * @return a QuestionDto object representing the added question
+     * @throws ResponseStatusException if the exercise with exerciseId from QuestionCreateDto does not exist
+     */
+    @PostMapping
+    public QuestionDto addQuestion(@RequestBody QuestionCreateDto dto) {
+        Exercise exercise;
+        try {
+            exercise = exerciseService.find(dto.getExerciseId());
+        } catch (EntityNotFoundException e) {
+            throw new ResponseStatusException(HttpStatus.NOT_FOUND,
+                    "Exercise not found with id: " + dto.getExerciseId());
+        }
+
+        Question question = questionMapper.fromCreateDto(dto);
+        exercise.getQuestions().add(question);
+        question.setExerciseId(exercise.getId());
+
+        var answerDtos = dto.getAnswers();
+        var answers = new HashSet<Answer>();
+        for (var answerDto : answerDtos) {
+            Answer answer = answerMapper.fromCreateDto(answerDto);
+            answer = answerService.create(answer);
+            answers.add(answer);
+        }
+
+        question.setAnswers(answers);
+        var createdQuestion = questionService.create(question);
+
+        for (var answer : answers) {
+            answer.setQuestionId(createdQuestion.getId());
+        }
+
+        return questionMapper.toDto(createdQuestion);
+    }
+}
\ No newline at end of file