마법사가있는 웹 페이지를위한 REST API 디자인


11

마법사 형식의 웹 페이지가 있습니다. API 제출 버튼은 마법사의 4 단계에 있습니다. 그러나 마법사의 다음 단계로 이동하기 전에 입력 한 데이터를 데이터베이스에 저장하려고합니다. 또한 단일 탭이있는 페이지에서 REST API가 작동하기를 원합니다.

그래서 쿼리 매개 변수 action = draft 또는 submit을 수행하도록 API를 설계했습니다. 조치가 초안 인 경우 특정 필드 만 필수입니다. 조치가 제출되면 모든 필드가 필수입니다. REST API의 서비스 계층에서 유효성 검사는 쿼리 매개 변수를 기반으로 수행됩니다. 설명서에서 if / else 절을 ​​명시 적으로 지정해야합니다. 이것이 RESTful 디자인의 수용 가능한 형태입니까? 이러한 요구 사항에 가장 적합한 디자인은 무엇입니까?


3
임시 데이터를 DB에 저장해야하는 이유는 무엇입니까?
Dan1701

2
@ Dan1701 : 다른 컴퓨터에서 마법사를 다시 시작할 수 있습니다. 길고 복잡한 양식을 채울 때 필요한 데이터를 모두 준비하지 않았거나 다른 위치에서 업로드하기 위해 추가 파일을 수집해야 할 수 있으므로 필요한 모든 데이터를 완료하는 데 며칠이 걸릴 수 있습니다. 다른 장치에서 다시 시작할 수있는 경우 마법사를로드하여 휴대폰에서 사진을 업로드하고 데스크탑 등의 실제 키보드로 긴 설명 / 인수를 계속 입력 할 수 있습니다.
Lie Ryan

이 경우 @ guillaume31의 대답이 합리적이라고 생각합니다.
Dan1701

답변:


7

마법사 단계 사이에 서버에있는 것들을 유지하고자하므로 각 단계를 별도의 리소스로 간주하는 것이 좋습니다. 이 라인을 따라 뭔가 :

POST /wizard/123/step1
POST /wizard/123/step2
POST /wizard/123/step3

응답에 하이퍼 미디어 링크를 포함 시키면이 단계 이후에 수행 할 수있는 작업에 대해 클라이언트에게 알릴 수 있습니다. 중간 단계는 앞뒤로 진행하고 마지막 단계는 수행하지 않습니다. 당신은 그림 5에서의 예를 볼 수 있습니다 여기에 .


UI에 Angular를 사용하고 있습니다. 따라서 상태 시스템이 얼마나 도움이되는지 잘 모르겠습니다. 그러나 단계 기반 리소스가 다른 테이블을 관리하는 것보다 더 의미가 있다고 생각합니다. 또한 모든 단계를 한 번에 제출할 수 있어야합니다. 오늘이 디자인에 대해 설명하겠습니다. 도와 주셔서 감사합니다.
TechCrunch

천만에요. 그건 그렇고, "두 테이블"접근법은 이것과 상호 배타적이지 않습니다. 단계 당 하나의 HTTP 자원이 있어도 데이터베이스 스키마는 물론 애플리케이션 서버의 오브젝트 모델을 지시하지 않습니다. 그것은 단지 웹 표현입니다.
guillaume31

1
@TechCrunch 기본적으로 기 illa (Guillaume)은 양식을 나타내는 개체 / 테이블이 부분으로 나뉘어 모델의 일부가 각 단계에서 저장되는 부분으로 나눌 수 있음을 의미합니다. 실제로 각 "단계"를 전체 모델의 일부로 만들 수 있습니다 . 이 접근 방식을 취하면 실제로 아키텍처가 매우 단순 해집니다. 서버에 대한 각 POST는 동일한 모델을 작성 (또는 작성)하고 각 GET은 동일한 모델을로드하며 각 단계는 의미 상 의미가있는 (함께) 필드 세트를 채우는 양식이됩니다. 그리고 단순히에 대한 부울을 in_progress갖습니다 draft.
Chris Cirefice

3

나는 얼마 전에 비슷한 일을해야했고, 다음은 우리가 끝내는 것을 설명합니다.

Item과 UnfinishedItem이라는 두 개의 테이블이 있습니다. 사용자가 마법사를 사용하여 데이터를 입력하면 데이터가 UnfinishedItem 테이블에 저장됩니다. 각 마법사 단계에서 서버는 해당 단계 동안 입력 된 데이터의 유효성을 검사합니다. 사용자가 마법사를 마치면 마법사는 확인 페이지에 숨겨진 / 읽기 전용 양식을 렌더링하여 제출할 모든 데이터를 표시합니다. 사용자는이 페이지를 검토하고 관련 단계로 돌아가 오류를 수정할 수 있습니다. 사용자가 항목에 만족하면 제출을 클릭하면 마법사가 숨겨진 / 읽기 전용 양식 필드의 모든 데이터를 API 서버에 제출합니다. API 서버는이 요청을 처리 할 때 마법사의 각 단계에서 수행 한 모든 유효성 검사를 다시 실행하고 개별 단계에 맞지 않는 추가 유효성 검사 (예 : 전역 유효성 검사, 값 비싼 유효성 검사)를 수행합니다.

두 가지 테이블 접근 방식의 장점 :

  • 데이터베이스에서는 UnfinishedItem 테이블보다 Item 테이블에 더 엄격한 제한 조건을 가질 수 있습니다. 마법사가 완료 될 때 실제로 필요한 선택적 열이 없어도됩니다.

  • 완료되지 않은 항목을 제외하는 것을 기억할 필요가 없으므로 완성 된 항목에 대해보고를위한 집계 쿼리가 더 쉽습니다. 이 경우 Item과 UnfinishedItems간에 집계 쿼리를 수행 할 필요가 없었으므로 문제가되지 않습니다.

단점 :

  • 유효성 검사 논리가 복제되기 쉽습니다. 우리가 사용했던 웹 프레임 워크 인 Django는 약간의 메타 마술과 함께 모델 상속을 사용하여 Item과 UnfinishedItem에서 달라야하는 제약 조건을 변경함에 따라 이것을 좀 더 견딜 수있게 만들었습니다. Django는 대부분의 데이터베이스와 양식 유효성 검사를 모델에서 생성하므로 그 위에 몇 가지 추가 유효성 검사 만 해킹하면됩니다.

내가 고려한 다른 가능성과 왜 우리가 그들과 함께 가지 않았습니까?

  • 쿠키 또는 로컬 저장소에 데이터 저장 : 사용자는 다른 기기에서 제출을 계속하거나 브라우저 기록을 삭제 한 경우
  • UnfinishedItem을 데이터베이스 또는 보조 데이터 저장소에 구조화되지 않은 데이터 (예 : JSON)로 저장합니다. 구문 분석 논리를 정의해야하며 Django의 자동 모델 / 양식 유효성 검사를 사용할 수 없습니다.
  • 클라이언트 측에서 단계별 유효성 검사를 수행하십시오 .Python / Django와 JavaScript간에 유효성 검사 논리를 복제해야합니다.

1
'초안'유형 모델 및 '완료'모델에 대한 유효성 검증을 지적하면 +1; 나는 그것을 생각하지 않았으며, 고려해야 할 중요한 점입니다. 그렇지 않으면 if유효성 검사 전반에 걸쳐 초안 상태를 확인 하는 많은 진술이있을 수 있습니다. Ruby on Rails와 같은 매우 정교한 프레임 워크는 올바르게 구현되면이 문제를 크게 단순화 할 수 있습니다.
Chris Cirefice

1

나는 @ guillauma31과 @Lie Ryan의 솔루션과 비슷한 방식으로 이것을 구현했습니다.

주요 개념은 다음과 같습니다.

  1. 완료 될 때까지 부분적으로 지속될 수있는 3 단계 마법사가 있습니다.
  2. 각 단계 (예 : 그것의 자신의 자원을 가지고 /users/:id_user/profile/step_1, .../step_2등)
  3. 각 단계에서 데이터 및 완료 상태는 GET 요청을 통해 검색되고 PATCH 요청을 통해 지속될 수 있습니다.
  4. 각 리소스에는 입력 한 데이터에 대한 자체 유효성 검사 규칙이 있습니다.
  5. 각 단계는 시퀀스를 보장하기 위해 다음 단계의 입력에 사용해야하는 키를 반환합니다. 사용되거나 새로운 토큰이 생성되면이 토큰은 만료됩니다.
  6. 마지막 단계에서 데이터베이스에 필요한 모든 데이터가 있으며 확인 화면이 표시됩니다. 이 확인은 다른 리소스를 호출하여 데이터를 완료된 것으로 표시합니다 (예 :) .../profile/confirm. 이 리소스는 모든 데이터를 다시받을 필요가 없습니다. 데이터가 정확하고 완전한 것으로 표시됩니다.
  7. 이 불완전한 항목을 며칠 이상 지운 예약 된 루틴이 있습니다.

프론트 엔드 녀석은 마법사의 앞뒤 흐름을 작동시키기 위해 토큰을 관리해야합니다.

API는 상태가없고 원자 적입니다.

이 설정에서 "1 단계 마법사"를 사용하려면 토큰 흐름 제거 또는 마법사 유형에 따라 토큰을 반환 할 리소스 생성 또는이 특정 단일 항목 만 채울 새로운 리소스 생성과 같은 몇 가지 사항을 변경해야합니다. 단계 마법사 (예 :) PUT /users/:id_user/profile/.

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