как различить между 403 и 404 по запросу БД

0

Я работаю над REST API. При попытке доступа к ресурсу: мы хотим либо дать 403 (Forbidden), либо 404 (Not Found) ошибку. Наши таблицы:

CREATE TABLE 'Action' (
      'id' int(10) unsigned NOT NULL AUTO_INCREMENT,
      'created_By_Id' int(10) unsigned NOT NULL,
      'name' varchar(60) NOT NULL,
      'updated_action_at' datetime(3) DEFAULT NULL,
      'created_At' datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
      'notes' varchar(400) DEFAULT NULL,
       PRIMARY KEY ('id'),
       KEY 'action_empId_fk' ('created_By_Id'),
       CONSTRAINT 'action_empId_fk' FOREIGN KEY ('created_By_Id')
       REFERENCES 'Employee' ('id') ON DELETE CASCADE,
       ) ENGINE=InnoDB AUTO_INCREMENT=502004 DEFAULT CHARSET=latin1


CREATE TABLE 'ActionAssignedTo' (
    'action_Id' int(10) unsigned DEFAULT NULL,
    'assignee_Id' int(10) unsigned DEFAULT NULL,
     KEY 'actionassignedto_emp_id_foreign' ('emp_Id'),
     KEY 'actionassignedto_action_id_foreign' ('action_Id'),
     CONSTRAINT 'ActionAssignedTo_ibfk_1' FOREIGN KEY ('assignee_Id') 
     REFERENCES 'Employee' ('id') ON DELETE CASCADE,
     CONSTRAINT 'ActionAssignedTo_ibfk_2' FOREIGN KEY ('action_Id') 
     REFERENCES 'Action' ('id') ON DELETE CASCADE
     ) ENGINE=InnoDB DEFAULT CHARSET=latin1

CREATE TABLE 'Employee' (
    'id' int(10) unsigned NOT NULL AUTO_INCREMENT,
    'vendor_Id' int(10) unsigned DEFAULT NULL,
    'name' varchar(40) NOT NULL,
    'mobile_Number' varchar(15) NOT NULL,
    'active' tinyint(1) DEFAULT '1',
    'updated_At' datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
    'created_At' datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY ('id'),
    KEY 'employee_vendor_id_foreign' ('vendor_Id'),
    CONSTRAINT 'employee_vendor_id_foreign' FOREIGN KEY ('vendor_Id')
    REFERENCES 'Vendor' ('vendor_Id')
    ) ENGINE=InnoDB AUTO_INCREMENT=511 DEFAULT CHARSET=latin1

Мы запускаем запрос для получения действия с id: 17 сотрудником-создателем с идентификатором: 9 и идентификатором поставщика: 1, и этот сотрудник был создан, чтобы он мог просмотреть его (бизнес-правило). Действие может быть назначено нескольким сотрудникам.

select     Action.name,  
           group_concat(AssigneeNameTable.name) as assignedTo, 
           group_concat(AssigneeNameTable.id) as assignedToId, 
           ActionAssignedTo.action_Id as actionId
from       Action
inner join Employee
on         Action.created_By_Id = Employee.id
and        Employee.vendor_Id = 1 
inner join ActionAssignedTo 
on         Action.id = ActionAssignedTo.action_Id 
and        ActionAssignedTo.action_Id = 17 
inner join Employee as AssigneeNameTable 
on         ActionAssignedTo.assignee_Id = AssigneeNameTable.Id 
where      Action.created_By_Id = 9 
and        Action.deleted_at is null 
group by   Action.id 
limit       2

Теперь давайте скажем, если Action вообще не существует в DB ->, в этом случае указанный выше запрос возвращает пустой набор результатов

the problem is we can not differentiate the query return empty set because 

1. either the action with id:17 did not exist(404- Not Found) 

2. or the business rule failed (as in the person requested the action was not    
at all related to the action(403 - Forbidden).

Одним из решений, о котором я могу думать, является: Сначала запустите небольшой запрос, например:

select * from Action where id = 17

если этот запрос возвращает пустой набор, что означает, что действие не существует в db.

После этого я запускаю запрос Bigger

Различные комбинации набора результатов (число в массиве указывает на возвращаемые записи):

Small Query | Big Query  | Interpretation
---------------------------------------
[0]         | [0]        | Resource Not Found(404)
[1]         | [0]        | Forbidden (403)

Если Small Query возвращает 0 результат → мы можем напрямую отправить 404 Error; иначе мы выполняем Большой запрос.

  • 1
    Не могли бы вы расширить свой SQL-запрос, чтобы он также поставил флаг состояния, независимо от того, существовали данные или нет? Разве этого не достаточно, чтобы принять решение по делу 404?
  • 0
    @QualityCatalyst: Не уверен, как мы будем это делать. Удастся ли вам попробовать это по нашему запросу.
Показать ещё 3 комментария
Теги:
rest
http-status-code-403

1 ответ

0
Лучший ответ

Я использовал концепцию Left Outer Join, как предложил мой друг. Ниже вы найдете новый запрос:

select      *
from

(select     id
 from       Action
 where      id = 17) AS act1

left Outer Join

(select    Action.name,  
           group_concat(AssigneeNameTable.name) as assignedTo, 
           group_concat(AssigneeNameTable.id) as assignedToId, 
           ActionAssignedTo.action_Id as actionId
from       Action
inner join Employee
on         Action.created_By_Id = Employee.id
and        Employee.vendor_Id = 1 
inner join ActionAssignedTo 
on         Action.id = ActionAssignedTo.action_Id 
and        ActionAssignedTo.action_Id = 17 
inner join Employee as AssigneeNameTable 
on         ActionAssignedTo.assignee_Id = AssigneeNameTable.Id 
where      Action.created_By_Id = 9 
and        Action.deleted_at is null 
group by   Action.id 
limit      2) AS act2

on          act1.id = act2.actionId

Концепция проста

  • если результат не содержит результата → Объект не найден (404)

  • если вывод содержит поле id но не содержит ни одного поля из второго подзапроса, что означает, что сущность существует в db, но бизнес-правила не позволяют и, следовательно, запрещены (403).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню