@Gruzchick

Стоит ли один и тот же endpont в RESTlike API делать доступным и для авторизованного и не авторизованного пользователя?

Здравствуйте.

Допустим я хочу сделать, апи блог-платформы. Предоставляю консюмерам такой ендпоинт:

/blogs?usrId={someValue}&filter[published]={someValue}

И теперь вынужден в коде рассмотреть несколько вариантов, а именно:
Авторизованный или не авторизованный запрос = 2 варианта
Указан uresId или нет = 2 варианта
Значения filter[published] : undefined, true, false = 3 варианта

В итоге надо рассмотреть 2*2*3 = 12 случаев и выдавать либо данные либо ошибку авторизации.

Меня смущает что надо столько условий проверять, в одном контроллере это нормально? Или есть какой то другой способ организации такой логики, допустим сделать два ендпоинта, но тогда как их назвать?

Выскажите свои соображения пожалуйста?

UPD:
Вот такое пришлось написать:
const {
      userId,
      filter: { published },
    } = params;

    const qb = this.blogRepository
      .createQueryBuilder()
      .select(['id', 'title', '"createdAt"'])
      .addSelect('SUBSTRING(body, 1, 300)', 'body');

    if (currentUser) {
      // request authorized
      if (userId) {
        qb.where('"userId" = :userId', { userId });
        if (published === Published.unpub) {
          if (currentUser.id === userId) {
            qb.andWhere('published = :published', { published });
          } else {
            throw new UnauthorizedError();
          }
        } else if (published === undefined) {
          if (currentUser.id !== userId) {
            qb.andWhere('published = :published', {
              published: Published.pub,
            });
          }
        } else {
          qb.andWhere('published = :published', {
            published: Published.pub,
          });
        }
      } else {
        if (published === Published.unpub) {
          qb.where('published = :published', { published }).andWhere(
            '"userId" = :userId',
            { userId: currentUser.id }
          );
        } else if (published === undefined) {
          qb.where('published = :published', {
            published: Published.pub,
          }).orWhere(
            new Brackets((qb1) => {
              qb1
                .where('published = :published', { published: Published.unpub })
                .andWhere('"userId" = :userId', { userId: currentUser.id });
            })
          );
        } else {
          qb.andWhere('published = :published', { published });
        }
      }
    } else {
      // request not authorized
      if (userId) {
        qb.where('"userId" = :userId', { userId });
        if (published === Published.unpub) {
          throw new UnauthorizedError();
        } else {
          qb.andWhere('published = :published', { published: Published.pub });
        }
      } else {
        if (published === Published.unpub) {
          throw new UnauthorizedError();
        } else {
          qb.andWhere('published = :published', { published: Published.pub });
        }
      }
    }


Всем спасибо за внимание.
  • Вопрос задан
  • 145 просмотров
Решения вопроса 1
angrySCV
@angrySCV
machine learning, programming, startuping
если нужно 12 логических вариантов реализовать, то прийдется их реализовывать, другое дело что используют подходы ускоряющие их реализацию:
обычно схема такая, ты свой запрос "наследуешь" от какого-то объекта с уже заготовленной ОБЩЕЙ функциональностью для запросов, например на проверку авторизации и возврат соответствующих ошибок.
а специфичные для запроса параметры парсишь, ну и в случае их отсутствия заменяешь на параметры по умолчанию и работаешь как работал, либо там какие-то ошибки выдаешь
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
mad_maximus
@mad_maximus
Делать разные ендпоинты не стоит, лучше сделать JWT авторизацию и тогда ваши проверки сократятся в 2 раза.
Ответ написан
inoise
@inoise
Solution Architect, AWS Certified, Serverless
Вам надо переосмыслить ваше API. Оба варианта пока что кажутся дикостью. Если детализируете что у вас за api, что делает этот конкретный метод то тогда можно помочь принять решение.

Вообще:
- выделите сущности системы (Entities of Domain Model хотябы)
- составьте список ролей и действий, которые они делать (UseCase)
- вот тут начнет проясняться
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы