역할 기반 REST API?


27

다른 역할을 가진 여러 사용자가 포함 된 리소스에 액세스 할 수있는 REST API를 만들고 있습니다.

범위를 단순하게 유지하기 위해 "학생 / 교사 / 클래스"도메인을 살펴 보겠습니다.

GET /students 액세스 할 수있는 리소스입니다.

사용자는 학생 및 / 또는 교사와 같은 역할을 할 수 있습니다

학생들은 자신의 수업 학생 만 이용할 수 있습니다. 교사는 자신이 가르치는 수업의 학생들에게 접근 할 수 있습니다. 어떤 용도는 학생 일 수도 있고 다른 수업도 가르 칠 수도 있습니다. 학생들은 수업 시간에 학생과 수업 시간에 액세스 할 수 있어야합니다.

이상적 으로이 기능을 역할 당 하나와 사용자가 여러 역할을 가진 경우 "연합"의 두 가지 기능으로 구현하고 싶습니다.

내 질문은 : 이것을 구현하기 위해 어떤 패턴을 사용해야합니까?

외부 적으로

  • 역할별로 API를 분할해야합니까? GET /teacher/students그리고 GET /student/students그것은 나에게 옳지 않은 것 같습니다.
  • 모두 하나의 리소스로 유지 (선호)

내부적으로

내부적으로 어떻게 구현해야합니까?

  • 모든 방법이 역할 당 BIG 스위치로 시작해야합니까?
  • 역할별로 리포지토리를 구현해야합니까?
  • 이를 달성하는 데 도움이되는 디자인 패턴이 있습니까?

부수적 의견 : ASP.NET Web APIEntity Framework 6을 사용 하고 있지만 개념적 구현에는 실제로 중요하지 않습니다.


3
"이것은 훌륭한 질문입니다. 비슷한 솔루션을 시도하고 있기 때문에 솔루션을 제공했는지 알고 싶습니다. 먼저 생각해야 할 것 : 먼저 필요한 모든 데이터를 반환하는 API를 구현합니다. 각 클라이언트는 API에 직접 연결되지 않고 해당 사용자의 역할에 따라 데이터를 필터링하는 프록시에 연결됩니다 "
Cleiton

답변:


11

역할이 아닌 리소스를 중심으로 API를 설계해야합니다. 예 :

/rest/students

학생을 볼 수있는 역할을 가진 사람이라면 누구나 접근 할 수 있어야합니다.

내부적으로 역할 기반 보안을 구현하고 있습니다. 이를 수행하는 방법은 응용 프로그램의 세부 사항에 따라 다르지만 역할 테이블이 있고 각 사람에게 하나 이상의 역할이 있으며 해당 역할이 각 사람이 액세스 할 수있는 대상을 결정한다고 가정 해 봅시다. 학생 액세스 규칙을 이미 언급했습니다.

  • 학생들은 수업에서 학생들에게 접근 할 수 있습니다
  • 교사는 수업 시간에 학생들에게 접근 할 수 있습니다

따라서 사람이 전화하면

/rest/students

학생의 역할을 전달하면서 학생에게 접근하는 방법을 호출합니다. 의사 코드는 다음과 같습니다.

roles = person.roles; //array
students = getStudents( roles );
return students;

이 방법을 사용하면 다음과 같은 별도의 호출을 통해 각 역할의 학생을 확보 할 수 있습니다.

factory = getFactory();
classes= [];
students = [];
for( role in roles ){
    service = factory.getService( role );
    // implementation details of how you get classes for student/teacher are hidden in the service
    classes = classes.merge( service.getClasses( person ) );
    // classes[] has class.students[]
    // loop on classes and add each student to students, or send back classes with nested students? depends on use case
  }
}

그것은 당신이 할 수있는 일에 대한 매우 거친 아이디어이며 반드시 특정 요구에 맞지 않을 수도 있지만 관련된 부분에 대한 감각을 제공해야합니다. 나열된 각 학생과 함께 수업을 반환하려면이 방법이 좋습니다. 학생들을 원한다면 각 수업에서 학생들을 추출하여 학생들의 모음으로 병합 할 수 있습니다.

아니요, 역할마다 별도의 저장소가 없어야합니다. 모든 역할은 데이터를 얻는 방법과 데이터로 수행 할 수있는 작업을 결정하는 것입니다 (예 : 교사가 학생 성적을 입력 할 수 있음). 데이터 자체는 동일합니다.

패턴의 경우이 방법은 팩토리 패턴을 사용하여 역할을 기반으로 데이터를 가져 오는 서비스를 추상화합니다. 역할별로 별도의 서비스를 제공하는 것이 적절하거나 적합하지 않을 수 있습니다. 프로그램의 각 단계에서 코드의 양을 최소화하고 스위치 나 if 블록보다 더 읽기 쉽기 때문에이 방법이 마음에 듭니다.


1
답장을 보내 주셔서 감사합니다. 나는 당신이 제안한 것과 같은 것을 끝내 었습니다. LINQ2SQL (C #)을 사용하여 각 "역할"에 쿼리를 전달하고 각 역할의 위치를 ​​사용자가 적용 할 수있었습니다. 결과는 사용자가 액세스 할 수있는 각 역할에 대해 "OR"조건이있는 sql 문입니다. 사용자에게 역할이 할당되지 않으면 호출자에게 Enumarable.Empty ()를 반환합니다.
캐스퍼 젠슨

0

펜과 종이를 찾아 시스템 모델링을 시작하십시오.

PERSON이라는 도메인 엔터티가 필요할 수 있습니다. 학생과 교사 모두 "is-a"PERSON이므로 이름, 성 등과 같은 일반 속성을 가진 PERSON이라는 추상 엔티티를 작성할 수 있습니다. 교사-> is-a-> 개인. 이제 학생들에게 적용되지 않는 교사의 특성을 찾아 볼 수 있습니다. 예를 들어 교사는 하나 이상의 주제에 관해 수업을 가르칩니다.

보안 적용은 응용 프로그램에서 작동하지 않는 것으로 간주됩니다. "비즈니스 로직"외부에서 처리해야하는 것은 교차 문제 입니다. @Robert Munn이 지적했듯이 ROLE은 모두 한곳에서 관리해야합니다. 역할을 사용하여 특정 기능에 대한 액세스를 제한하는 것은 다소 거칠며 개념을 RBAC ( 역할 기반 액세스 제어 )라고합니다.

교사가 학생의 성적을 볼 수 있는지 여부를 확인하려면 도메인 모델로 표현해야합니다. 교사가 과목 프로그래밍에 대한 수업을 가지고 있다고 가정하십시오. 당신은 아마도 학생들이 다른 과목에 대한 수업에 참석한다고 모델에 표현할 것입니다. 애플리케이션 / 비즈니스 로직이 시작됩니다. 이것은 테스트 중심 개발을 사용하여 확인할 수있는 로직입니다.

당신은 해야 응용 프로그램 검증 및 모듈 확인하기 위해 자원을 분할합니다.

어쨌든, 내가 실제로 의미하는 것을 보여주는 가장 좋은 방법은 코드로 표시하는 것입니다. :) GitHub 페이지는 다음과 같습니다. https://github.com/thomasandersen77/role-based-rest-api

행운을 빕니다 :)


3
귀하의 링크가 사라졌습니다 ...
Cleiton
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.