편안한 URL을 디자인하는 방법을 결정하기 위해 고심하고 있습니다. 나는 명사와 함께 URL을 사용하는 평온한 접근 방식을 사용하고 동사는 이것을 수행하는 방법을 이해하지 못합니다.
재무 계산기를 구현하는 서비스를 만들고 있습니다. 계산기는 CSV 파일을 통해 업로드 할 여러 매개 변수를 사용합니다. 사용 사례는 다음과 같습니다.
- 새 매개 변수 업로드
- 최신 매개 변수 얻기
- 지정된 영업일에 대한 매개 변수 가져 오기
- 매개 변수 세트를 활성화하십시오.
- 매개 변수 세트 확인
나는 다음과 같은 유형의 URL을 갖는 것이 편한 방법을 모은다.
/parameters
/parameters/12-23-2009
다음을 사용하여 처음 세 가지 사용 사례를 달성 할 수 있습니다.
- 게시 요청에 매개 변수 파일을 포함하는 POST
- 첫 URL의 GET
- 두 번째 URL의 GET
그러나 동사없이 네 번째와 다섯 번째 사용 사례를 어떻게 수행합니까? 다음과 같은 URL이 필요하지 않습니까?
/parameters/ID/activate
/parameters/ID/validate
??
답변
아마도 다음과 같습니다.
PUT /parameters/activation HTTP/1.1
Content-Type: application/json; encoding=UTF-8
Content-Length: 18
{ "active": true }
답변
올바른 URI 디자인을위한 일반 원칙 :
- 상태를 변경하기 위해 쿼리 매개 변수를 사용 하지 마십시오
- 도움이 될 수 있으면 대소 문자를 혼용 하지 마십시오 . 소문자가 가장 좋습니다
- URI에 구현 별 확장을 사용 하지 마십시오 (.php, .py, .pl 등).
- URI 로 RPC에 빠지지 마십시오.
- 마 가능한 한 당신의 URI 공간을 제한
- 마 짧은 킵 경로 세그먼트
- 음주 중 하나를 선호
/resource
하거나/resource/
; 사용하지 않는 301 리디렉션을 만듭니다. - 수행 자원의 하위 선택을 위해 사용 쿼리 매개 변수; 즉 페이지 매김, 검색어
- 음주 는 HTTP 헤더 또는 본문에 있어야 URI의 이사 물건
(참고 : “RESTful URI 디자인”이라고 말하지 않았습니다. URI는 본질적으로 REST에서 불투명합니다.)
HTTP 메소드 선택의 일반 원칙 :
- 상태를 변경하기 위해 GET을 사용 하지 마십시오 . Googlebot이 하루를 망칠 수있는 좋은 방법입니다.
- 전체 리소스를 업데이트하지 않는 한 PUT을 사용 하지 마십시오
- 동일한 URI에서 합법적으로 GET을 수행 할 수 없다면 PUT을 사용 하지 마십시오.
- 오래 지속되거나 캐시하기에 합당한 정보를 검색하기 위해 POST를 사용 하지 마십시오
- PUT에서 dem 등원 이 아닌 작업을 수행 하지 마십시오
- 수행 가능한 위해 사용 GET을
- 확실하지 않은 경우 PUT에 우선하여 POST를 사용하십시오.
- 수행 하면 RPC-같은 느낌이 뭔가를해야 할 때마다 사용 POST를
- 수행 크거나 계층되는 자원의 클래스를 사용 PUT을
- 마 제거 리소스에 POST에 우선하여 DELETE 사용
- 입력이 크지 않은 경우 계산과 같은 작업 에는 GET을 사용하십시오.이 경우 POST를 사용하십시오
HTTP를 사용한 웹 서비스 디자인의 일반 원칙 :
- 헤더에 있어야하는 응답 본문에 메타 데이터를 넣지 마십시오.
- 메타 데이터를 포함하지 않으면 별도의 리소스에 메타 데이터를 넣지 마십시오.
- 마 적절한 상태 코드를 사용
201 Created
자원을 만든 후; 응답이 전송 될 때 자원 이 존재 해야 합니다.202 Accepted
작업을 성공적으로 수행하거나 비동기 적으로 리소스를 생성 한 후400 Bad Request
누군가가 명백히 가짜 인 데이터를 조작 할 때; 응용 프로그램의 경우 유효성 검사 오류 일 수 있습니다. 잡히지 않은 예외에 대해 일반적으로 500을 예약합니다401 Unauthorized
필요한Authorization
헤더 를 제공하지 않고 누군가가 API에 액세스 하거나 내부의 자격 증명Authorization
이 유효하지 않은 경우Authorization
헤더 를 통해 자격 증명을 기대하지 않으면이 응답 코드를 사용하지 마십시오 .403 Forbidden
누군가 악의적이거나 권한이없는 방식으로 API에 액세스하는 경우405 Method Not Allowed
누군가 PUT을 사용해야했을 때 POST를 사용하는 경우413 Request Entity Too Large
누군가 허용 할 수없는 큰 파일을 보내려고 할 때418 I'm a teapot
주전자로 커피를 추출하려고 할 때
- 가능 하면 캐싱 헤더를 사용하십시오.
ETag
리소스를 해시 값으로 쉽게 줄일 수있는 경우 헤더가 좋습니다.Last-Modified
리소스가 업데이트 될 때의 타임 스탬프를 유지하는 것이 좋습니다.Cache-Control
및Expires
합리적인 값을 제공해야
- 수행 요청에 헤더를 캐싱 명예를 당신이 할 수있는 모든 것을 (
If-None-Modified
,If-Modified-Since
) - 마 사용 리디렉션 그들은 감각을 할 때, 그러나 이들은 웹 서비스에 대한 드문해야한다
특정 질문과 관련하여 POST는 # 4 및 # 5에 사용해야합니다. 이러한 작업은 위의 “RPC 유사”지침에 해당합니다. # 5의 경우 POST에서 반드시을 사용할 필요는 없습니다 Content-Type: application/x-www-form-urlencoded
. JSON 또는 CSV 페이로드와 마찬가지로 쉽게 사용할 수 있습니다.
답변
새로운 동사가 필요할 때마다 그 동사를 명사로 바꾸는 것을 고려하십시오. 예를 들어 ‘activate’를 ‘activation’으로, ‘validate’를 ‘validation’으로 바꾸십시오.
그러나 당신이 작성한 것에서 나는 당신의 응용 프로그램에 훨씬 더 큰 문제가 있다고 말합니다.
‘파라미터’라는 자원이 제안 될 때마다 모든 프로젝트 팀원의 마음에 적신호를 보내야합니다. ‘parameter’는 문자 그대로 모든 리소스에 적용 할 수 있습니다. 구체적이지 않습니다.
‘파라미터’는 정확히 무엇을 나타 냅니까? 아마도 여러 가지 다른 것들이 있으며, 각각에는 별도의 리소스가 필요합니다.
이것을 얻는 또 다른 방법-최종 사용자 (프로그래밍에 대해 거의 알지 못하는 사람)와 응용 프로그램을 논의 할 때 반복적으로 사용하는 단어는 무엇입니까?
그것들은 당신이 응용 프로그램을 디자인해야 할 단어입니다.
아직 잠재 사용자와이 변환을하지 않은 경우 지금 당장 모든 것을 중지하고 다른 코드 줄을 작성하지 마십시오. 그래야만 팀이 무엇을 구축해야하는지 알 수 있습니다.
금융 소프트웨어에 대해서는 아무것도 모르지만 추측해야 할 경우 일부 리소스는 “Report”, “Payment”, “Transfer”및 “Currency”와 같은 이름으로 갈 수 있습니다.
소프트웨어 디자인 프로세스의이 부분에 대한 많은 좋은 책들이 있습니다. 내가 추천 할 수있는 두 가지는 도메인 기반 설계 및 분석 패턴 입니다.
답변
URL 디자인은 응용 프로그램이 RESTful인지 여부와 관련이 없습니다. 따라서 “RESTful URLs”라는 문구는 의미가 없습니다.
REST가 실제로 무엇인지 좀 더 읽어야한다고 생각합니다. REST는 URL을 불투명하게 처리하므로 동사, 명사 등이 있는지 여부를 알 수 없습니다. 여전히 URL을 디자인하고 싶을 수도 있지만 REST가 아닌 UI에 관한 것입니다.
즉, 귀하의 질문에합시다 : 마지막 두 경우는 RESTful하지 않으며 어떤 종류의 편안한 체계에도 적합하지 않습니다. 그것들을 RPC라고 부릅니다. REST에 대해 진지한 경우, 애플리케이션이 처음부터 어떻게 작동하는지 다시 생각해야합니다. REST를 포기하거나 RPC 앱으로 앱을 수행하십시오.
흠.
여기서 아이디어는 모든 것을 리소스로 취급해야하므로 매개 변수 집합에서 참조 할 수있는 URL이 있으면 추가하면됩니다.
GET [parametersurl]/validationresults
POST [paramatersurl]
body: {command:"activate"}
그러나 다시 활성화하는 것은 REST가 아니라 RPC입니다.
답변
활성화 및 유효성 검사 요구 사항은 리소스 상태를 변경하려고하는 상황입니다. 주문을 “완료”하거나 다른 요청을 “제출”하는 것은 다르지 않습니다. 이러한 종류의 상태 변경을 모델링하는 방법에는 여러 가지가 있지만, 자주 작동하는 것으로 확인되는 방법은 동일한 상태의 리소스에 대한 수집 리소스를 만든 다음 컬렉션간에 리소스를 이동하여 상태에 영향을주는 것입니다.
예를 들어,
/ActiveParameters
/ValidatedParameters
매개 변수 집합을 활성화하려면 해당 매개 변수 집합을 ActiveParameters 컬렉션에 추가하십시오. 다음과 같이 매개 변수 집합을 엔터티 본문으로 전달하거나 url을 쿼리 매개 변수로 전달할 수 있습니다.
POST /ActiveParameters?parameter=/Parameters/{Id}
/ ValidatedParameters를 사용하여 동일한 작업을 수행 할 수 있습니다. 매개 변수가 유효하지 않으면 서버는 요청에 “잘못된 요청”을 반환하여 유효성 검사 된 매개 변수 컬렉션에 매개 변수를 추가 할 수 있습니다.
답변
다음과 같은 메타 리소스 및 방법을 제안합니다.
매개 변수를 활성화 및 / 또는 확인하십시오.
> PUT /parameters/<id>/meta HTTP/1.1
> Host: example.com
> Content-Type: application/json
> Connection: close
>
> {'active': true, 'require-valid': true}
>
< HTTP/1.1 200 OK
< Connection: close
<
매개 변수가 활성화되어 있고 유효한지 확인하십시오.
> GET /parameters/<id>/meta HTTP/1.1
> Host: example.com
> Connection: close
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Connection: close
<
< {
< 'active': true,
< 'require-valid': true,
< 'valid': {'status': false, 'reason': '...'}
< }
<
답변
10 년이 지난 후에 OP에서 요청한 것과 같은 것이 REST 아키텍처에서 어떻게 설계 될 수 있는지에 대한 대답이 실제로 없다는 것을 알면 약간 슬프다 고 느끼므로 지금이 작업을 수행해야한다고 생각합니다.
우선, REST는 무엇입니까?! 약어 REST 또는 ReST는 “Representational State Transfer”를 나타내며 특정 표현 형식으로 자원 상태의 교환을 정의합니다. 표현 형식은 협상 된 미디어 유형과 관련이 있습니다. application/html
표현 형식 의 경우 브라우저에서 렌더링되는 HTML 형식의 텍스트 컨텐츠 스트림 일 수 있습니다. 일부 스타일 시트 형식을 적용하여 특정 위치에 특정 요소를 배치 한 경우 일 수 있습니다.
REST는 원칙적으로 브라우저뿐만 아니라 모든 종류의 응용 프로그램을 대상으로하지만 우리 모두가 알고있는 탐색 가능한 웹의 일반화입니다. 따라서 설계 상 웹에 적용되는 것과 동일한 개념이 REST 아키텍처에도 적용됩니다. “RESTful”방식으로 무언가를 달성하는 방법과 같은 질문은 웹 페이지에서 무언가를 달성 한 다음 동일한 개념을 응용 프로그램 계층에 적용하는 방법에 대한 대답을 해결합니다.
웹 기반 계산기는 일반적으로 입력 한 데이터를 서버로 보내기 전에 계산할 값을 입력 할 수있는 “페이지”로 시작할 수 있습니다. HTML에서는 일반적으로 HTML <form>
요소를 통해 클라이언트에게 설정 가능한 사용 가능한 매개 변수, 요청을 보낼 대상 위치 및 입력 데이터를 보낼 때 적용 할 표현 형식을 알려줍니다. 이것은 다음과 같이 보일 수 있습니다 :
<html>
<head>
...
</head>
<body>
<form action="/../someResource" method="post" enctype="application/x-www-form-urlencoded">
<label for="firstNumber">First number:</label>
<input type="number" id="firstNumber" name="firstNumber"/>
<label for="secondNumber">Second number:</label>
<input type="number" id="secondNumber" name="secondNumber"/>
<input type="submit" value="Add numbers"/>
</form>
</body>
</html>
위의 샘플은 즉 사용자 또는 다른 자동 입력 장치로 채울 수있는 두 개의 입력 필드가 있으며 제출 입력 요소를 호출하면 브라우저가 입력 데이터를 application/x-www-form-urlencoded
전송 되는 표현 형식으로 형식화하는 것을 처리합니다. POST
이 경우 지정된 HTTP 요청 방법을 통해 언급 된 대상 위치로 우리가 입력하면 1
로 firstNumber
입력 필드와 2
로 secondNumber
입력 필드, 브라우저의 표시를 생성 firstNumber=1&secondNumber=2
하고, 타깃 리소스에 대한 실제 요구의 본문이 페이로드를 전송.
따라서 서버에 발행 된 원시 HTTP 요청은 다음과 같습니다.
POST /../someResource
Host: www.acme.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
Accept: application/html
firstNumber=1&secondNumber=2
요청이 클라이언트가이 형식을 이해하고 있음을 나타내면 서버는 계산을 수행하고 계산 결과를 포함하는 추가 HTML 페이지로 응답 할 수 있습니다.
Breton이 이미 지적했듯이 “RESTful”URL 또는 URI는 없습니다. URI / URL은 고유 한 것이므로 클라이언트 / 사용자에게 의미를 전달해서는 안됩니다. 위의 계산기 샘플에서 사용자는 데이터를 어디로 보낼지 관심이 없으며 제출 입력 필드를 트리거 할 때 요청이 전송되는 것에 관심이 있습니다. 작업을 수행하는 데 필요한 모든 필수 정보는 이미 서버에서 제공해야합니다.
브라우저는 요청에 실제로 입력 매개 변수가있는 계산기를 먹이고 있음을 알지 못할 수도 있으며 주문 프로세스를 계속하기 위해 다음 양식 표현 만 반환하는 완전히 다른 일종의 주문 양식 일 수도 있습니다. 자원. 이 경우 HTML 사양에서 요구하는 것을 단순히 수행하며 서버가 실제로 수행하는 것을 덜 신경 쓰지 않았습니다. 이 개념을 통해 브라우저는 동일한 표현 형식을 사용하여 선호하는 온라인 상점에서 물건을 주문하고, 가장 친한 친구와 채팅하고, 온라인 계정에 로그인하는 등 모든 종류의 작업을 수행 할 수 있습니다.
일반적으로 버튼으로 렌더링되는 제출 입력 필드 사례에서 특정 요소 의 여유 는 해당 요소와 관련하여 수행해야 할 작업을 정의합니다. 버튼이나 링크의 경우 기본적으로 클릭하라는 메시지가 표시됩니다. 다른 요소는 다른 여유를 전달할 수 있습니다. 이러한 어포던스는 또한 링크 관계 를 통해 표현 될 수있다. 즉 preload
, 사용자가이 컨텐츠를 다음에 잡을 가능성이 높기 때문에 클라이언트가 백그라운드에서 링크 된 자원의 컨텐츠를 이미로드 할 수 있음을 클라이언트에게 알리는 주석이 달린 링크를 통해 표현 될 수있다 . 이러한 링크 관계는 물론 표준화되어야하거나 웹 링크에 의해 정의 된 관계 유형에 대한 확장 메커니즘을 따라야합니다 .
이것들은 웹에서 사용되는 기본 개념이며 REST 아키텍처에서도 사용해야합니다. “Uncle Bob”Robert C. Martin에 따르면 아키텍처는 의도에 관한 것이며 REST 아키텍처의 의도는 서버를 클라이언트와 분리하여 서버가 클라이언트를 해치지 않을까 염려하지 않고 미래에 자유롭게 진화 할 수 있도록하는 것입니다. 불행히도 커플 링을 도입하거나 빠른 수정 솔루션을 추가하여 작업을 완료하고 진행하기가 쉽기 때문에 많은 훈련이 필요합니다. Jim Webber가 REST 아키텍처에서 지적한 것처럼 서비스 제공 업체 는 클라이언트가 프로세스가 끝날 때까지 따라야 하는 70 년대의 텍스트 기반 컴퓨터 게임과 유사한 도메인 응용 프로그램 프로토콜 을 설계해야 합니다.
불행히도 실제로 “REST”API가 많이하는 것은 그 밖의 모든 것입니다. 일반적으로 동적으로 즉시 통합하기 어려운 API 관련 외부 문서에 지정된 대부분 JSON 기반 데이터의 교환을 볼 수 있습니다. 요청이 어떻게 보이는지에 대한 형식은 외부 문서에 하드 코딩되어 미리 정의 된 유형 을 반환 하도록 URI를 해석하는 많은 구현으로 이어집니다.사전 협상 된 일반적인 표현 형식을 사용하는 대신. 클라이언트가 이제 미리 정의 된 URI에 대해 특정 데이터 형식 (표현 형식이 아님)을 수신 할 것으로 예상하므로 서버가 변경되지 않습니다. 이 맞춤 데이터 형식 교환은 “데이터 형식”이 일반적으로 특정 API를 지원하기 때문에 클라이언트가 다른 API와 상호 작용하는 것을 방지합니다. 우리는 Peppol이 최근에 AS2를 기본 전송 프로토콜로 AS4로 대체하여 다시 옮겼지만 Corba, RMI 또는 SOAP와 같은 RPC 기술을 통해 과거 부터이 개념을 알고 있습니다.
실제 질문과 관련하여 데이터를 csv 파일로 보내는 것은 application/x-www-form-urlencoded
표현이나 유사한 것을 사용 하는 것과 다르지 않습니다 . Jim Webber는 모든 HTTP가 애플리케이션 도메인이 웹을 통해 문서를 전송하는 전송 프로토콜 일뿐 임을 분명히했다 . 클라이언트와 서버는 RFC 7111에text/csv
정의 된 대로 둘 다 지원해야합니다 . 이 CSV 파일은 구성 요소 업로드를 수행하기 위해 HTTP 메소드뿐만 아니라 양식 요소, 대상 요소 또는 요청을 보내는 속성을 정의하는 매체 유형을 처리 한 결과 생성 될 수 있습니다.
HTML , HAL Forms , halform , ion 또는 Hydra 와 같은 양식을 지원하는 두 가지 미디어 유형이 있습니다. 그러나 현재 입력 데이터를 text/csv
직접 자동으로 인코딩 할 수있는 미디어 유형을 알지 못 하므로 IANA의 미디어 유형 registry에 정의하고 등록해야 할 수도 있습니다 .
전체 매개 변수 세트의 업로드 및 다운로드는 문제가되지 않아야합니다. 앞에서 언급했듯이 클라이언트가 처리 할 새 컨텐츠를 검색하기 위해 URI를 사용하기 때문에 대상 URI는 관련이 없습니다. 영업일 기준으로 필터링하는 것도 어렵지 않아야합니다. 그러나 여기서 서버는 클라이언트가 단순히 선택할 수있는 모든 가능성을 가진 클라이언트 여야합니다. 최근 몇 년간 GraphQL과 RestQL이 진화하여 필터링 된 응답을 얻기 위해 특정 엔드 포인트를 대상으로하는 SQL과 같은 언어를 도입했습니다. 그러나 진정한 REST 의미에서 이는 REST 뒤에있는 아이디어를 위반합니다. 자원의 기본 데이터 모델.
특정 구성 매개 변수를 활성화하거나 비활성화하는 것은 이러한 여유를 제공하는 하이퍼 미디어 제어를 트리거하는 것입니다. HTML 양식에서 이것은 간단한 확인란이거나 목록 또는 해당 종류의 여러 줄로 선택 될 수 있습니다. 양식과 정의한 방법에 따라 전체 구성을 전송 PUT
하거나 변경 사항에 대해 현명하게 할 수 있으며를 통해 부분 업데이트 만 수행 할 수 PATCH
있습니다. 후자는 기본적으로 변경 된 표현의 계산을 업데이트 된 것으로 계산하고 현재 표현을 원하는 것으로 변환하는 데 필요한 단계를 서버에 공급합니다. PATH 스펙 에 따르면, 모든 단계가 적용되거나 전혀 적용되지 않도록 트랜잭션 내에서 수행해야합니다.
HTTP는 변경 사항을 적용하기 전에 서버가 수신 된 요청을 미리 검증하도록 허용하고 권장합니다. 들어 PUT 사양 상태 :
오리진 서버는 PUT 표현이 PUT에 의해 변경 될 수 있거나 변경되지 않을 대상 자원에 대한 서버의 제한 조건과 일치하는지 확인해야합니다. 이는 오리진 서버가 GET 응답에서 표시 메타 데이터의 값을 설정하기 위해 URI와 관련된 내부 구성 정보를 사용할 때 특히 중요합니다. PUT 표현이 목표 자원과 일치하지 않는 경우, 원 서버는 표현을 변환하거나 자원 구성을 변경하여 일관성을 유지하거나 표현이 부적합한 이유를 설명하기에 충분한 정보가 포함 된 적절한 오류 메시지로 응답해야한다. 409 (충돌) 또는 415 (지원되지 않는 미디어 유형) 상태 코드가 제안됩니다.
예를 들어, 대상 자원이 항상 “text / html”의 Content-Type을 갖도록 구성되고 PUT 인 표현이 “image / jpeg”의 Content-Type을 갖는 경우, 오리진 서버는 다음 중 하나를 수행해야합니다.
ㅏ. 새 매체 유형을 반영하도록 대상 자원을 재구성하십시오.
비. PUT 표현을 새로운 자원 상태로 저장하기 전에 자원의 형식과 일치하는 형식으로 변환합니다. 또는,
씨. 대상 리소스가 “text / html”로 제한됨을 나타내는 415 (지원되지 않는 미디어 유형) 응답으로 요청을 거부합니다. 새 표현에 적합한 다른 리소스에 대한 링크를 포함 할 수도 있습니다.
HTTP는 PUT 메소드가 사용자 에이전트 요청의 의도와 오리진 서버 응답의 의미로 표현할 수있는 것 이상으로 오리진 서버의 상태에 미치는 영향을 정확히 정의하지 않습니다. …
이 게시물을 요약하려면 클라이언트에게 필수 또는 지원되는 입력 매개 변수, 요청을 보낼 대상 위치, 사용할 조작 및 매체 유형에 대해 알려줄 수있는 기존 매체 유형을 사용해야합니다. 요청을 형식화하거나 IANA에 등록한 고유 한 요청을 정의해야합니다. 입력을 다음으로 변환하려는 경우 후자가 필요할 수 있습니다.text/csv
그런 다음 CSV 표현을 서버에 업로드하십시오. 변경 사항이 리소스에 적용되기 전에 유효성 검사가 수행되어야합니다. 실제 URI는 요청을 어디로 보낼 것인지를 결정하는 것 이외의 클라이언트와 관련이 없어야하며, 따라서 서비스 구현자가 자유롭게 선택할 수 있습니다. 이 단계를 수행하면 언제든지 서버 측을 자유롭게 변경할 수 있으며 사용 된 미디어 유형을 지원하는 클라이언트는 결과적으로 중단되지 않습니다.