Как создать конечные точки api на веб-сайте с автоматическим сохранением?

#java #c# #rest #restful-url

Вопрос:

У меня есть веб-сайт, где каждая компания может изменить некоторые настройки: верхний, нижний, Введение или размер текста. Каждое из этих полей имеет функцию автоматического сохранения. Должен ли я создавать конечные точки для каждого поля?

Это таблица в моей базе данных: введите описание изображения здесь

Это дизайн моего веб-сайта (каждое поле имеет автоматическое сохранение): введите описание изображения здесь

Я рассматриваю следующие конечные точки. Это хорошее направление?

 GET /PageSettings - to return a row in a database for a company
HEAD /PageSettings - to check if exists a row in a database for a company
POST /PageSettings - to create a row in a database with only Id and CompanyId

HEAD /PageSettings/UpperBanner/{FileId} - to check if exists UpperBanner in a database for a company
POST /PageSettings/UpperBanner - to add UpperBanner in a database for a company
PUT /PageSettings/UpperBanner/{FileId} - to change UpperBanner in a database for a company

HEAD /PageSettings/LowerBanner/{FileId} - to check if exists LowerBanner in a database for a company
POST /PageSettings/LowerBanner - to add LowerBanner in a database for a company
PUT /PageSettings/LowerBanner/{FileId} - to change LowerBanner in a database for a company

HEAD /PageSettings/Introduction - to check if exists Introduction in a database for a company
POST /PageSettings/Introduction - to add Introduction in a database for a company
PUT /PageSettings/Introduction - to change Introduction in a database for a company

HEAD /PageSettings/TextSize - to check if exists TextSize in a database for a company
POST /PageSettings/TextSize - to add TextSize in a database for a company
PUT /PageSettings/TextSize - to change TextSize in a database for a company
 

Комментарии:

1. Может быть, вы можете рассмотреть возможность использования пути метода HTTP?

2. У меня есть файлы, поэтому я задаюсь вопросом, будет ли ПУТЬ легким.

Ответ №1:

Гораздо лучше создать единую конечную точку CRUD, операция УСТАНОВКИ/ИСПРАВЛЕНИЯ которой обновляет только отправленную информацию. В этом случае вы должны различать, когда поле, которое может быть пустым, было отправлено или не было отправлено.

Если вы исключите возможность наличия нулевых элементов, слияние будет тривиальным:

 @Controller
... MyControllerClass {

    @Put / @Patch
    public Response upsert(Entity upsertEntity) {
        ...
        Entity currentEntity = repository
            .get(upsertEntity.getId())
            .merge(upsertEntity);
        ...
        repository.save(currentEntity);
 

где Entity.merge операция похожа:

 class Entity {
    ...
    public Entity merge(Entity other) {
        if(other.getField1() != null) setField1(other.getField1());
        if(other.getField2() != null) setField1(other.getField2());
        ...
        // merge hierarchy
        if(other.getFieldX() != null)
            getFieldX().merge(other.getFieldX());
        ...
        return this;
 

если поля могут быть удалены в null состояние, этот подход не работает, и вы не можете использовать одни и те же объекты сохранения для своего API (например, формы загрузки Spring во многих случаях вам нужна оболочка).

Таким образом, если клиент хочет обновить N полей, он может сделать это с помощью одной операции. Если, когда пользователь вносит изменения, вы ждете X секунд, вы можете обнаружить и накопить несколько изменений, которые будут отправлены все вместе.

Если вам нужно сбросить поля (установить значение null), создайте определенный тип для одной операции:

 class UpsertRequestData {
    private boolean resetField1; // or `field1IsPresent`
    private Field1Type field1;
    private boolean resetField2;
    private Field2Type field2;
    ...
 

Комментарии:

1. К сожалению, каждое поле может быть пустым 🙁

2. Затем, как я уже сказал, оберните свои данные для каждого поля, вместо этого создайте целую конечную точку.