G
G
Gruzchick2019-06-22 11:00:53
RESTful API
Gruzchick, 2019-06-22 11:00:53

Should the same endpont in a RESTlike API be made available to both authorized and non-authorized users?

Hello.
Let's say I want to do a blog platform api. I provide consumers with the following endpoint:
/blogs?usrId={someValue}&filter[published]={someValue}
And now I have to consider several options in the code, namely:
Authorized or not authorized request = 2 options
uresId specified or not = 2 options Filter
values [published] : undefined, true, false = 3 options
In total, we need to consider 2 * 2 * 3 = 12 cases and issue either data or an authorization error.
It confuses me that it is necessary to check so many conditions, is this normal in one controller? Or is there some other way to organize such logic, let's say make two endpoints, but then how to call them?
Tell me your thoughts please?
UPD:
This is what I had to write:

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 });
        }
      }
    }

Thank you all for your attention.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
⚡ Kotobotov ⚡, 2019-06-22
@Gruzchick

if you need to implement 12 logical options, then you will have to implement them, it’s another matter that they use approaches that speed up their implementation:
usually the scheme is like this, you “inherit” your request from some object with already prepared GENERAL functionality for requests, for example, to check authorization and return the corresponding errors.
and you parse the request-specific parameters, and if they are absent, you replace them with the default parameters and work as you did, or you give some errors there

K
kafkiansky, 2019-06-22
@mad_maximus

It is not worth doing different endpoints, it is better to do JWT authorization and then your checks will be reduced by 2 times.

I
Ivan Shumov, 2019-06-22
@inoise

You need to rethink your API. Both options so far seem wild. If you detail what your api is, what this particular method does, then you can help make a decision.
In general:
- select the entities of the system (Entities of Domain Model at least)
- make a list of roles and actions that they do (UseCase)
- this is where it starts to clear up

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question