Подтвердить дату из другого ограниченного контекста - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть два ограниченных контекста (обучение студентов, курсы). Studentenrollment имеет всех студентов с его курсами и домашним заданием. Курсы имеют административную часть, которая содержит всю информацию, связанную с курсом. Когда студент хочет получить информацию о курсе, он попадает в конечную точку (/ курсы / ID), отправляющую токен jwt. В контексте курса я получаю идентификатор студента, идентификатор курса и создаю запрос, который он отправляет в шину. В обработчике запросов, прежде чем получать информацию о курсе из идентификатора курса, я хочу проверить, существует ли идентификатор студента, и этот студент имеет этот курс. Для этого я должен назвать другой контекст ограниченным студентом. Итак, я искал, как справиться с этим в Интернете, и я нашел это: https://medium.com/@martinezdelariva/authentication-and-authorization-in-ddd-671f7a5596ac

class findByCourseIdAndStudentIdQueryHandler()
    {
        public function handle($findByCourseIdAndStudentIdQuery)
        {
            $courseId = $findByCourseIdAndStudentIdQuery->courseId();
            $studentId = $findByCourseIdAndStudentIdQuery->studentId();

            $student = $this->collaboratorService->studentFrom(
                $courseId,
                $studentId
            );


            $this->courseRepository->findByCourseId($courseId);
        }
    }

    class collaboratorService()
    {
        public function studentFrom($courseId, $studentId)
        {
            $student = $this->studentEnrollmentClient->getStudentFrom($courseId, $studentId);

            if (!$student) {
                throw new InvalidStudentException();
            }

            return $student;
        }
    }

Что ты думаешь?

ОБНОВЛЕНО

namespace App\Context\Course\Module\Course\UI\Controller;

class GetCourseController extends Controller
{
    public function getAction($request) {
        $this->ask(new FindByCourseIdQueryHandler($request->get('course_id'));
    }
}

namespace App\Context\Course\Module\Course\Infrastracture\Query;

class AuthorizedQueryDispatcher extends QueryDispatcher
{
    //In this case $query would be FindByCourseIdQueryHandler
    public function handle($query)
    {
        $authUser = $this->oauthService->getAuthUser();

        //it can be student or teacher
        $role = $authUser->getRole();
        $userId = $authUser->getUserId();

        //it will return FindByCourseIdAndStudentIdAuthorizedQueryHandler
        $authorizedQuery = $this->inflector->getAuthorizedQueryName->from($userId, $role, $query);

        $this->dispatch($authorizedQuery);

        $this->queryDispatch->dispatch($query);
    }
}

namespace App\Context\Course\Module\Course\Application\Query;

class FindByCourseIdAndStudentIdAuthorizedQueryHandler
{
    public function handle($findByCourseIdAndStudentIdQuery)
    {
        $student = $this->studentEnrollmentClient->getStudentFrom($findByCourseIdAndStudentIdQuery->courseId, $findByCourseIdAndStudentIdQuery->studentId);

        if (!$student) {
            throw new InvalidStudentException();
        }
    }
}

namespace App\Context\Course\Module\Course\Application\Query;

class findByCourseIdAndStudentIdQueryHandler()
{
    public function handle($findByCourseIdQueryHandler)
    {
        $courseId = $findByCourseIdQueryHandler->courseId();

        $this->courseRepository->findByCourseId($courseId);
    }
}

1 Ответ

0 голосов
/ 14 сентября 2018

TLDR;Авторизация должна быть четко отделена от уровня домена, например, в другом пакете / пространстве имен / модуле.Кроме того, зависимость от Домена до Авторизации должна быть инвертирована, Домен не должен зависеть / знать об авторизации /

Один из способов реализовать это - создать сервис Авторизации, например FindByCourseIdAndStudentIdQueryAuthorizer (давайтеназовите это Authorizer).Эта услуга может пересекать границы ограниченного контекста (BC), то есть она может зависеть от услуг удаленного домена от удаленных BC.В идеале, удаленные данные должны быть уже доступны, когда авторизатор выполняет проверку.Таким образом, система становится более устойчивой в случае, если удаленные службы ограниченного контекста недоступны.Вы можете сделать это, прослушивая удаленные события или фоновые задачи.

В идеале, уровень домена (из любого BC) не должен знать об Авторизаторах.

Один из способов сделать это - украсить QueryDispatcher (или что у вас есть) в корне Composition приложения с помощью AuthorizedQueryDispatcher.Этот AuthorizedQueryDispatcher при получении запроса сначала ищет Авторизатора, а затем вызывает его.Если авторизация не пройдена, запрос отклоняется.Если авторизация прошла успешно или нет авторизатора, тогда запрос отправляется реальному / оформленному QueryDispatcher.

Если не можете этого сделать (т.е. у вас нет QueryDispatcher), тогда вы можете попытаться украсить каждыйобработчик запросов (вручную?).Например, у вас может быть FindByCourseIdAndStudentIdAuthorizedQueryHandler, который имеет тот же интерфейс, что и FindByCourseIdAndStudentIdQueryHandler.Вы можете заменить их в корне композиции приложения (DIC).

...