REST 웹 서비스에서 작업을 트리거하기 위해 어떤 HTTP 동사를 사용해야합니까?


80

RESTful 웹 서비스를 구현하고 있으며 사용 가능한 조치 중 하나는입니다 reload. 구성, 캐시 등을 다시로드하는 데 사용됩니다.

우리는 다음과 같이 간단한 GETURI로 시작했습니다 . ${path}/cache/reload(매개 변수는 전달되지 않고 URI 만 호출됩니다). GET 요청으로 데이터를 수정해서는 안된다는 것을 알고 있습니다.

RESTful 웹 서비스에서 조치 / 명령을 호출하는 데 사용할 올바른 동사는 무엇입니까?

다시로드는 자체 캐시 / 구성 등을 다시로드하는 REST 웹 서비스의 명령입니다. 클라이언트에 정보를 반환하는 방법이 아닙니다.

아마도 내가하려는 것은 REST가 아니지만 여전히이 방법으로 수행 해야하는 것입니다. reload방법은 응용 프로그램의 범위에서 의미가있는 실제 예일 뿐이며 대부분의 답변에 초점을 맞췄지만 실제로 CRUD를하지 않지만 여전히 데이터를 변경하는 작업을 트리거 할 동사를 알아야했습니다. 상태.

나는 Stack Overflow abot 주제에 대한이 상세한 답변을 발견했습니다 : https://stackoverflow.com/questions/16877968/


1
"다시로드"는 앱이 표시 할 데이터를 새로 고치는 의미입니까? 다시로드하는 것과 데이터를 다시 얻는 것 사이에 차이점이 있습니까?
Sean Redmond

1
@SeanRedmond 아니요, 데이터가 클라이언트로 전송되지 않습니다. 실제로 클라이언트는 REST 웹 서비스에 실행하고 내부 명령 (재로드)을 요청합니다. "데이터베이스에서 많은 구성이 변경되었으므로 REST 웹 서비스에서 메모리로 다시로드하십시오".
Renato Dinhani

교차 사이트 복제 : stackoverflow.com/q/15340946/319403
cHao

적절한 요청에 헤더 매개 변수 사용을 고려 했습니까? 이것은 캐시 리프레시와 매우 흡사합니다 ...
Guran

답변:


25

나는 없다고 생각 적절한 이 거래 정말하지 않기 때문에이 작업에 대한 동사 "편안하고." "s"및 "t"는 "상태 이전"을 나타내며 여기에 아무것도 전송되지 않습니다. 또는 가장 엄격한 정의에 따르면 PUT 및 POST와 같은 동사는 항상 명사와 함께 사용되며 "재로드"에는 동사 만 있습니다.

이 리로드는 RESTful이 아닐 수 있지만 여전히 유용 할 수 있으며,이를 수행하고 비정상적이라고 설명하거나 설명하는 방법을 선택했을 것입니다. GET이 가장 단순 할 것입니다. 그러나 의견에는 상당한 회의론이 있기 때문에, 다른 일이 제대로 수행되지 않아서이 재로드 작업이 필요한지 여부를 고려해야합니다.


나는 이것이 RESTful하지 않지만 유용 할 수 있음에 동의합니다. 그래도 PUT에 조언을해야한다고 생각합니다. 이것은 아마도 dem 등원이지만 nullmpotent가 아니기 때문입니다.
Aaron Greenwald

@Aaron, idempotent와 nullimpotent의 비교는 모두 좋고 훌륭하지만 그것이 중요하지 않은 시점을 어떻게 결정합니까?
Craig

@Craig 여러 번 실행하는 경우 dem 등원입니다. 한 번 실행하는 것과 동일한 효과가 있습니다. 한 번 또는 여러 번 실행하면 서버에서 0 번 실행하는 것과 동일한 영향을 미치면 nullipotent입니다. en.wikipedia.org/wiki/Idempotence
Aaron Greenwald

5
@AaronGreenwald "notimpotent"[하지-IM-poht-NT] [하지-IM-pawr-TNT] - 형용사 - . "중요"1. 단어에 플레이 "중요하지,"형용사의 반의어 2. 유머 감각 ... ;-)
Craig

@Craig 나는 완전히 놓친 :)
아론 그린 월드

75

RESTful이 되려면 동사가 동작을 수행한다고 생각하지 말고 클라이언트가 무언가를 한 후에 리소스가 원하는 상태 를 생각하십시오.

위의 예 중 하나를 사용하면 이메일을 보내는 이메일 대기열이 있습니다. 클라이언트가 해당 전자 메일 대기열을 일시 중지 또는 중지 상태 또는 다른 상태로 설정하려고합니다.

따라서 클라이언트는 해당 자원의 서버에 새로운 상태를 PUT합니다. 이 JSON만큼 간단 할 수 있습니다

PUT http://myserver.com/services/email_service HTTP/1.1
Content-Type: text/json

{"status":"paused"}

서버는 현재 상태 (예 : "실행 중")에서 "일시 중지 된"상태 / 상태로 이동하는 방법을 알아냅니다.

클라이언트가 리소스에 대해 GET을 수행하는 경우 현재 상태 (예 : "일시 중지됨")를 반환해야합니다.

이런 식으로하는 이유와 REST가 그렇게 강력한 이유는 서버 상태를 유지하는 방법을 떠나기 때문입니다.

클라이언트는 "현재 상태입니다" 라고 말하고 서버는이를 달성하는 방법을 알아냅니다. 데이터베이스의 간단한 뒤집기 일 수 있습니다. 수천 개의 조치가 필요할 수 있습니다. 클라이언트는 신경 쓰지 않으며 알 필요가 없습니다.

따라서 서버가 어떻게하고 클라이언트가 신경 쓰지 않는지를 완전히 다시 작성 / 재 디자인 할 수 있습니다. 클라이언트는 내부 요소가 아닌 리소스의 다양한 상태 (및 해당 표현) 만 인식하면됩니다.


2
내가 걱정하는 한 이것은 정답입니다. 서버에서 데이터를 새로 고치는 것은 dem 등원 작업이 아니며 GET사용하기에 완전히 부적절한 동사입니다. PUT작업이 캐시의 "재로드 된 상태"를 "재로드 된"으로 업데이트하는 것으로 생각 될 수 있으므로 가장 적합한 동사입니다.
Jez

@Jez 여기에 대한 답변 중에서 나는 이것을 선호합니다. 이메일 은유와 집착, 그것은 아무 렇게 않습니다 은 "전송"상태로 퍼팅 대신에 불과하여 메일을 보낼 생각에 처음에는 이상한 느낌이 보내는 그것을 (작업을). 하지만 생각하면 "보낼 편지함"에 넣는 것과 똑같습니다. 실제로 메일 시스템 자체는 메일을 보내라고 지시 할 때 내부적으로 큐를 대기 중일 수 있습니다. 따라서 API를 사용하면 메일을 "보내기"상태로 만들 수 있으며 API는 그 이상으로 설명 할 의무가 없습니다.
Craig

따라서 확장하여 메시지를 아직 보내지 않으려면 날짜 / 시간과 함께 "예약 된"상태로 설정해야합니다. 완료되지 않은 경우, "초안"상태 등으로 설정하거나 암시 적으로 / 기본적으로 설정합니다.
Craig

...이 경우 PUT은 dem 등원이어야하지만 POST는 그러한 제약 조건이 없으므로이 경우 POST보다 PUT을 선호한다고 생각합니다.
Craig

1
그렇게 할 수는 있지만 궁극적으로 사각형 구멍을 둥근 구멍에 맞추려고합니다. 클라이언트가 서버를 트리거하여 무언가를 "재로드"해야하는 이유는 없습니다. 건축 설계가 열악합니다. 서버는 각 호출 또는 고정 된 시간 간격으로 내부 상태를 업데이트 할 수 있습니다. 클라이언트가 자원 상태에 대한 실제 요청과 무관하게 무언가를 다시로드하도록 서버에 지시하는 것은 RESTful 아키텍처가 아닙니다.
Cormac Mulhall

32

허용되는 답변을 포함하여 다른 답변 중 일부는 GET을 사용하는 것이 좋습니다 (열심히는 아니지만).

동의하지 않습니다.

우선, 이것이 이상적이지 않고 실제로 RESTful하지 않다고 말하는 다른 모든 사람들은 정확합니다. 적절한 RESTful 시나리오에서는 서버의 자원을 조작하고 해당 자원을 추가, 업데이트, 삭제, 검색하는 중입니다. PUT은 요청 완료시 리소스가 무엇인지 나타내는 페이로드를 보내야하며 POST는 서버에 추가 할 리소스를 나타내는 페이로드를 보내야합니다. 그리고 GET은 서버의 리소스를 반환해야합니다.

RESTful하지 않은 RPC (원격 프로 시저 호출)가 있습니다. 서버에서 무언가를 수행하려고합니다. 따라서 순수 RESTful API를 작성하려는 경우 수행중인 작업을 재고해야합니다.

즉, 때로는 규칙을 약간 구부릴 필요가 있습니다. 특히 대중에게 노출되지 않을 내부 API를 개발하는 경우 그 가치가 있다고 판단 할 수 있습니다.

그렇다면 RPC가 dem 등 (Idempotent) 인지 아닌지에 따라 PUT 또는 POST를 권장합니다 .

일반적으로 HTTP PUT은 SQL UPDATE에 매핑되고 HTTP POST는 SQL INSERT에 매핑되지만 엄격하게 사실은 아닙니다. HTTP PUT이 dem 등원이어야하고 HTTP POST가 필요하지 않다는 더 올바른 방법. 즉, 부작용없이 원하는만큼 동일한 PUT 요청을 호출 할 수 있습니다. 일단 전화를 걸면 다시 전화하는 것이 무해합니다. 그러나 각 POST가 서버의 데이터를 다시 변경한다는 의미가 아닌 한 POST 요청을 반복해서 호출하면 안됩니다.

귀하의 경우,이 다시로드 기능이 필요한 경우, UT 등한 것처럼 들리므로 PUT을 권장합니다. 그러나 나는 아직도 당신이 그것을 필요로하지 않는 것에 대해 다른 사람들이 말한 것을 고려할 것을 촉구합니다.


6

POSTPUT웹 서버에 엔티티를 제출하는 데 사용되는 HTTP 동사입니다. 을 사용 PUT하면 제출 된 엔티티가 지정된 URI에서 리소스에 대한 (신규) 표현이며 원하는 것에 맞지 않습니다. POST엔터티가 리소스에 대한 보조 데이터 인 전통적인 양식 처리기를위한 것이므로 이것이 승자입니다. 엔티티에는 명령 또는 조치가 포함됩니다 (예 : "action = reload").

즉, 해당 명령은 REST 인터페이스를 통해 노출되어서는 안됩니다. 다른 채널 (예 : 파일 시스템, DB 클라이언트)을 통해 데이터를 변경할 수 있기 때문에 "다시로드"가 필요한 것 같습니다. 캐시는 투명해야합니다. 또한 HTTP 요청은 원자 적이어야하며 다른 채널을 통해 전송 된 메시지도 고려해야합니다. 구성 설정에 "재로드"명령을 제공하는 것은 불필요한 복잡성으로 보입니다. 취성 디자인이 필요합니다. 한 채널에 전체 대화가 포함되어 있지 않기 때문에 다른 채널을 통한 업데이트 후 정리에 "다시로드"노출이 더럽습니다. 대신 다음 중 하나를 고려하십시오.

  • REST를 통해 완전히 업데이트
  • 명령을 다른 채널에 노출
  • 행동 자동화

다른 제한 사항에 따라 이러한 옵션 중 일부가 실행되지 않을 수 있습니다.

" PUT 대 POST의 POST "도 참조하십시오 .


감사합니다. 사실 "재로드"방법은 공개용이므로 편집의 "내부"를 제거했습니다. 방금 웹 서비스 자체를 의미한다는 것을 의미했습니다. "행동"을 게시하는 것이 좋은 방법이라고 생각합니다.
Renato Dinhani

@ RenatoDinhaniConceição : "내부"가 없어도 여전히 냄새가납니다. 디자인이 좋은지 아닌지에 대해 새로운 질문을하는 것이 좋습니다.
outis

4

나는 왜 클라이언트 요청이 그런 식으로 새로 고치기 위해 명시 적으로 호출해야하는지 논쟁 할 것이다. 좀 더 일반적인 GET 구현 (즉, 데이터를 가져 오지만 서비스가 데이터를 가져 오기 전에 데이터를 새로 고침)에서 숨겨진 로직이거나 클라이언트에서 멀리 떨어진 백엔드의 다른 트리거에 의해 숨겨진 것처럼 들립니다.

결국, 데이터 / 구성은 후속 호출에서 최신 상태 일 필요가 있으므로 데이터 새로 고침을위한 게으른 대 열망에 더 많이 의존 할 것입니다. 분명히 나는 ​​여기에서 많은 것을 가정하고 있지만, 그러한 명시적이고 독립 된 호출의 필요성을 재평가하기 위해 한 걸음 물러 설 것입니다.


내 편집을보십시오. "reload"는 데이터를 반환하는 명령이 아닙니다. REST 웹 서비스 자체를 나타냅니다. 일반적으로 내 질문은 REST 웹 서비스에서 작업을 트리거하는 것과 관련이 있습니다. 다른 예는 다음과 같습니다 email_queue/stop_sending_emails.. RESTful 인터페이스를 사용하여 무언가를 명령하고 있습니다.
Renato Dinhani

5
여전히 동의합니다. 로컬 프로세스에서 SIGHUP 을 호출하면 컴퓨터가 해당 신호에 액세스 할 수있는 로컬로 로그인 한 누군가를 신뢰해야하므로 의미가 있습니다. 그러나 상태 비 저장 인터넷 액세스 가능 프로토콜의 경우? 웹 서비스는 폴링 또는 파일 모니터링을 통해 필요에 따라 자동으로 다시로드되어야합니다. 이 전화 완전히 불필요합니다.

1
동의한다. 구성 및 캐싱과 같은 것은 클라이언트에게 투명해야합니다. 엔드 포인트가 호출 될 상황에 대해보다 구체적으로 설명해야 할 수도 있습니다.
Benjamin Hodgson '11

3

행동을 자원처럼 취급하지 않겠습니까? 따라서 캐시를 업데이트하려면 시스템에서 새 조치를 POST하십시오.

순수 주의자의 경우 전용 URL을 가질 수 있습니다. 날짜, 상태, 사용자 등을 포함하여 데이터베이스를 확장하고 실제 작업을 데이터베이스 (또는 스토리지)에 기록 할 수 있습니다.

일반적인 시스템 전체 작업 / actions / {action}

자원 유형 / actions / {resource} / {action}에 특정한 조작

자원 / actions / {resource} / {id} / {action}에 특정한 조작

귀하의 경우 캐시는 아마도 시스템 전체 / actions / reload_cache 일 것입니다


0

REST 웹 서비스에서 작업을 트리거하기 위해 어떤 HTTP 동사를 사용해야합니까?

REST 서비스의 세부 사항을 고려할 때 이러한 휴리스틱을 고려하는 것이 종종 유용합니다. 웹 사이트에서이를 어떻게 구현 하시겠습니까?

HTML은 기본적으로 GET 및 POST 요청 만 설명 할 수 있습니다. 검색을 시작할 수 있습니다.

GET적절한? 이 질문에 대답하기 위해 클라이언트와 중간 구성 요소가 수행 할 수있는 가정에 대해 생각해야합니다 GET. 의 의미 GET안전하다

클라이언트는 대상 자원에 안전한 방법을 적용한 결과로 오리진 서버에서 상태 변경을 요청하지 않으며 예상하지 않습니다. 마찬가지로, 안전한 방법을 합리적으로 사용한다고해서 원산지 서버에 해를 입거나 재산 손실 또는 비정상적인 부담이 발생하지는 않습니다.

따라서 클라이언트와 중간 구성 요소는 자신의 우려를 충족시키기 위해 필요한만큼 자주 GET 요청을 호출 할 수있는 재량권을 갖습니다. 스파이더는 리소스를 무차별 적으로 GET하여 인덱스를 업데이트 할 수 있습니다. 캐시는 프리 페치 할 수 있습니다. 신뢰할 수없는 네트워크에서는 최소한의 응답을 보장하기 위해 필요한만큼 손실 된 메시지를 재 시도 할 수 있습니다.

구성, 캐시 등을 다시로드하는 데 사용됩니다.

이것들이 비싼 일이라면, 클라이언트가 자신의 재량으로 이러한 요청을 발행하기를 원하지 않을 것입니다.

POST반면에 사실상 제약이 없습니다. 이는 일반 고객이 할 수있는 가정을 크게 줄입니다. 추론적인 POST 요청을하는 구성 요소는 그렇게하지 못하기 때문에 구성 요소를 얻지 못합니다.

PUT, PATCH, DELETE...이보다 명확한 의미로 위험한 방법은 POST; 적절한 지 여부는 자원 모델에 따라 다릅니다.

명심해야 할 중요한 아이디어는 HTTP 메소드가 문서 도메인에 속한다는 것입니다 ( Jim Webber의 2011 talk 참조 ). . 따라서 작업을 수행 할 수 있도록 문서를 구성하는 방법에있어 많은 자유가 제공됩니다.

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