Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Спринт 9. #5

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Спринт 9. #5

wants to merge 1 commit into from

Conversation

AlekseyGur
Copy link
Owner

Сделать API, веб сервер, эндпойнты, тесты

Copy link

@avfyodorov avfyodorov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Добрый вечер, Алексей!

В целом хорошо, правда, есть ряд уточнений.


assertEquals(200, response.statusCode());

List<Task> parsed = gson.fromJson(response.body(), new TaskListTypeToken().getType());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно было получить нужный тип прямо здесь, чтобы не создавать пустой класс.
На усмотрение

    List<Task> parsed = gson.fromJson(response.body(), new TypeToken<List<Task>>(){}.getType());


List<Task> parsed = gson.fromJson(response.body(), new TaskListTypeToken().getType());

assertTrue("Задачи не возвращаются", parsed.size() > 0);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Скорее вопрос... А что это за junit-библиотека, обычно же наоборот?

        assertTrue(parsed.size() > 0, "Задачи не возвращаются");


import ru.alexgur.kanban.model.Task;

public class TaskListTypeToken extends TypeToken<List<Task>> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Насколько я увидел, эти классы, кроме двух (DurationAdapter и LocalTimeAdapter ), используются исключительно для тестирования. Лучше было бы перенести их в пакеты, связанные с тестированием.

Изменять код для тестов - это плохая практика. Тесты никак не должны влиять на дизайн классов программы. Правильный дизайн классов первичен, а тесты вторичны.

private static final String HISTORY_PATH = "/history";
private static final String PRIORITIZED_PATH = "/prioritized";
public static final String IP = "127.0.0.1"; // "localhost";
public static final int PORT = 8070;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

По ТЗ:
.--------------
Создайте класс HttpTaskServer — он будет слушать порт $8080$

import java.io.IOException;
import java.net.InetSocketAddress;

public class HttpTaskServer extends BaseHttpHandler {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extends BaseHttpHandler {

Нет, не так. Зачем же он наследуется от обработчика, это разные вещи. По ТЗ:

.=================
Создайте класс HttpTaskServer — он будет слушать порт $8080$ и принимать запросы. Это будет основной класс вашего приложения. В нём должен находиться метод main, который будет запускаться для начала работы с программой.
.===============

На самом деле, Здесь всё проще, приблизительно так:

public class HttpTaskServer {
    public static final int PORT = 8080;

    private final HttpServer server;
    private final TaskManager manager;

    public HttpTaskServer(TaskManager manager) throws IOException {
        this.manager = manager;

        server = HttpServer.create(new InetSocketAddress("localhost", PORT), 0);
        server.createContext("/tasks", new TasksHandler(manager));
        server.createContext("/subtasks", new SubtasksHandler(manager));
        server.createContext("/epics", new EpicsHandler(manager));
        server.createContext("/history", new HistoryHandler(manager));
        server.createContext("/prioritized", new PrioritizedHandler(manager));
    }

    public void start() {
        System.out.println("Запустили TaskServer " + PORT);
        server.start();
    }

    public void stop() {
        server.stop(0);
        System.out.println("Остановили сервер на порту " + PORT);
    }

    public static void main(String[] args) throws IOException {
        TaskManager manager = Managers.getDefault();
        HttpTaskServer taskServer = new HttpTaskServer(manager);
        taskServer.start();
    }

}


import java.nio.charset.StandardCharsets;

public class HttpTaskManager extends HttpTaskServer {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сейчас получается, что вся бизнес-логика реализована в этом классе, что не совсем соответствует ООП. Хорошо было бы провести рефакторинг, в базовом классе (BaseHttpHandler) оставить обработчик и методы-заглушки, а в классах наследниках переопределять только эти методы (processGet, processPost….), если они нужны. Такое решение лучше соответствует принципам OOP

В результате должно получиться, что этот класс совсем не нужен.
Сейчас подробно распишу в базовом обработчике.

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class BaseHttpHandler {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь обработчик, методы-заглушки и служебные методы, приблизительно так:

public  class BaseHandler implements HttpHandler {
......................

       public void handle(HttpExchange exchange) throws IOException { 
       String method = exchange.getRequestMethod();
           switch (method) {
               case "GET":
                   processGet(exchange);
                   break;
               case "POST":
                   processPost(exchange);
                   break;
               case "DELETE":
                   processDelete(exchange);
                   break;
               default:
                   writeToUser(exchange, "Данный метод не предусмотрен");
           }
           
    protected void processGet(....) {
        sendMethodNotAllowed(...);
   }
   protected void processPost(....) {
        sendMethodNotAllowed(...);
   }

Далее в каждом из наследников мы будем переопределять только нужные для этого наследника методы processGet, processPost и т.д. и реализовывать в них нужную нам логику)
Почему возвращается статус 405 METHOD_NOT_ALLOWED можно посмотреть тут: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405

httpExchange.getResponseBody().write(resp);
httpExchange.close();
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для задач приблизительно так:

public class TasksHandler extends BaseHandler {
......................
    public TasksHandler(........................
    
    @Override
    protected void processGet(HttpExchange exchange, String path) throws IOException {
  .........................
    @Override
    protected void processPost(HttpExchange exchange) throws IOException {
 ...............
    @Override
    protected void processDelete(HttpExchange exchange, String path) throws IOException {
.......................

httpExchange.sendResponseHeaders(404, 0);
httpExchange.close();
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А для отсортированного по времени списка достаточно будет переопределить всего один метод:

public class PrioritizedHandler extends BaseHandler {
    private final TaskService tasks;

    public PrioritizedHandler(TaskService taskService) {
        super(TaskGson.GSON);

        this.tasks = taskService;
    }

    @Override
    protected void processGet(HttpExchange exchange, String path) throws IOException {
..................

httpExchange.sendResponseHeaders(406, 0);
httpExchange.close();
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Аналогично определяются классы-наследники и для эпиков, подзадач, истории.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants