REST URI 규칙-자원을 작성하는 동안 단수 또는 복수의 자원 이름


529

REST에 익숙하지 않고 일부 RESTful 서비스에서 업데이트 / 가져 오기 / 삭제 및 작성에 다른 리소스 URI를 사용하는 것으로 나타났습니다. 와 같은

  • 작성- / resource (단일)를 사용하여 일부 위치에서 POST 메소드와 함께 / resources 사용 (복수 관찰 )
  • 업데이트 -PUT 방법으로 / resource / 123 사용
  • Get- GET 메소드와 함께 / resource / 123 사용

이 URI 명명 규칙에 대해 약간 혼란 스럽습니다. 자원 생성을 위해 복수 또는 단수를 사용해야하는 것은 무엇입니까? 그것을 결정할 때 기준은 무엇입니까?


9
이 주제에 따라, 나는 기사에서 유명한 REST API를 몇 가지 예를 수집 한 : inmensosofa.blogspot.com/2011/10/...를 .
jjmontes

3
아래의 모든 답변을 읽은 후에 도달 한 결론 : (a) 일관성이 있고, (b) 단일 클래스 및 테이블 이름에 직접 매핑되고, (c) 일부 복수 명사는 영어에서 불규칙한 (예측할 수 없음)
Will Sheppard

단수 테이블 명명 규칙에 대한 링크는 이 답변 을 참조하십시오. 정확한 문제를 언급 한 다른 기사가 있습니다. Rest API Developer의 딜레마 -고맙습니다 @ 소터
Will Sheppard

답변:


281

사용의 전제 /resources는 "모든"자원을 나타내는 것입니다. 을 수행 GET /resources하면 전체 컬렉션을 반환 할 수 있습니다. POSTing to (으 /resources)로 컬렉션에 추가하고 있습니다.

그러나 개별 리소스는 / resource에서 사용할 수 있습니다. 을 수행하면 GET /resource이 요청은 의미가 없지만 /resource/123완벽하게 이해되므로 오류가 발생할 수 있습니다.

사용 /resource대신하는 것은 /resources당신이 말하는, 파일 시스템 및 파일의 모음 작업을하고 있다면 당신이 이런 짓을 했을까하는 것과 비슷 /resource개인과 "디렉토리"입니다 123, 456거기에 파일을 저장합니다.

어느 쪽이든 옳고 그른 것이 아니라 가장 좋아하는 것을 따라 가십시오.


55
좋은 답변입니다! 그러나 Windows의 "기본"디렉토리에는 복수 이름이 있습니다. "프로그램 파일", "사용자", "문서", "비디오"등과 같이 웹 사이트 URL에서 여러 이름이 훨씬 더 자주 발생합니다.
Dmitry Gonchar

50
사실상 대부분의 사람들과 API는 사실상 복수를 유지하는 사실상의 관습입니다. Ids는 하나의 자원 자동차 / ID를 지정합니다
PositiveGuy

205
"둘 중 어느 쪽이든 옳고 그른 것이 아니라 가장 좋아하는 것을 따라 가십시오." 아 유명한 선이 너무 자주 들리고 사람들의 말에 귀를 기울이고 피곤합니다. 더 나은 해결책과 좋은 관행이있는 곳에서 협약은 중요하고 공동체간에 건설적으로 논의되어야한다. URI에서 리소스 이름에 복수형과 단수형을 모두 사용하는 경우 사용자와 API 뒤의 코드가 단일 경로와 복수형을 구분하기 위해 경로와 논리에서이를 설명해야하기 때문에 코드와 API가 복잡해집니다. 항상 복수를 사용하면 아무런 문제가 없습니다.
PositiveGuy

30
@TomaszPluskiewicz 귀하는 고객 이 관심을 갖지 않는 것이 전적으로 옳습니다 . 우리 소프트웨어 개발자 로서 관심 을 가져야하며 , 컨벤션에 대한 건설적인 토론이 가치가 있다는 WTF의 의견에 동의합니다.
트래비스 D

12
따라서 누군가가 한 단어로 답변을하고 받아 들일 수 있으므로이 모든 것을 다시 읽을 필요는 없습니다.
Ben George

623

나에게는 코드가 양쪽 끝에있을 것이기 때문에 코드에 직접 매핑 할 수있는 스키마를 갖는 것이 좋습니다 (자동화하기 쉽습니다).

GET  /orders          <---> orders 
POST /orders          <---> orders.push(data)
GET  /orders/1        <---> orders[1]
PUT  /orders/1        <---> orders[1] = data
GET  /orders/1/lines  <---> orders[1].lines
POST /orders/1/lines  <---> orders[1].lines.push(data) 

22
이것의 어려움 또는 용이성은 HATEOS를 존중하지 않기 때문입니다. 복수인지 단수인지 또는 다른 것이 중요하지 않습니다. 서버에서 보낸 URI를 클라이언트에서 "빌드"하지 말고 서버에서 보낸 URI를 존중해야합니다. 그런 다음 코드에 대해 0 매핑을 수행하십시오.
richard

7
@richard 클라이언트는 여전히 맵핑을 수행해야합니다. HATEOS에서는 URI 구성과의 관계 (rel)를 나타내는 이름으로 매핑해야합니다. 그런 다음 rel, method (동사) 및 Content-Type이 리소스 미디어를 구성합니다. 좋은 URI 디자인이 필요하지는 않습니다. 클라이언트가 rel 이름을 우선시하더라도 API 개발자는 여전히 URI 구성을 위해 사람이 읽을 수있는 좋은 표준이 필요합니다.

4
이것은 내 의견으로는 더 나은 대답입니다. 내가 항상 복수 대신 Singular를 사용하는 것을 선호한다는 것을 제외하고. User.getList (), User.getById, User.delete 등
이스턴 몽크

3
나는 단순함을 좋아한다. 이 매핑은 또한 경로에 대한 문서화 및 테스트를 작성하기 매우 쉽다는 이점이 있습니다.
delos

5
이것은 나에게 의미가 있습니다. 그러나 우리는 데이터베이스 우선 상점이므로 데이터베이스 스키마에서 코드 및 API 엔티티를 생성합니다. 그리고 데이터베이스 표준은 단일 테이블 이름을 옹호하는 경향이 있으므로, 우리는이를 계속 사용하지만 여전히이 답변과 동일한 논리를 따릅니다.
안드레 C. 안데르센

274

나는 이것을하는 데 요점을 보지 못했고 그것이 최고의 URI 디자인이 아니라고 생각합니다. RESTful 서비스 사용자는 목록에 액세스하는지 또는 목록의 특정 리소스에 관계없이 목록 리소스의 이름이 동일 할 것으로 기대합니다. 목록 리소스를 사용하든 특정 리소스를 사용하든 관계없이 동일한 식별자를 사용해야합니다.


69
이것이 내가 생각하는 한 가장 좋은 대답입니다. API 디자이너가 "get resource # 123"이라고하는 언어 적 정확성을 좋아하지만 API의 클라이언트를 작성하고 도움말 문서를 작성할 때 추가적인 코딩 번거 로움이 있습니다. (GET / api / people vs. GET / api / person / 123? euuuchh.) .... "get resource # 123"과 같이 생각하는 대신 "자원 모음에서 가져 오기 # 123 "와 일치합니다.
워렌 루막

5
복수 / 단수 자원을 구별하는 것은 언어 적 정확성이 아니라 규모에 관한 것입니다. / employees / 12는 id가 '12'인 직원 리소스의 하위 집합으로 읽습니다 (예 : 최근 해고 된 직원에 대한 저장된 검색어). ID가 '12'인 직원으로 위의 내용을 읽으면 하위 집합을 어떻게 표현 하시겠습니까? 유일한 옵션은 객체 자체와 객체를 포함하는 URI의 더 복잡한 광석 구별 모음을 만드는 것입니다 (단수 대 복수).
Erik

9
최근 해고 된 직원 (또는 모든 하위 집합)에 대한 검색 쿼리를 나타 내기 위해 / employees / 12를 선택하면 디자인이 잘못 될 수 있습니다. 어떤 종류의 하위 집합도 자신의 권리로 적절한 이름을 가진 리소스로 소개하는 것이 좋습니다.
Jan Deinhard

3
이것은 고객에 대한 이해와 아무 관련이 없습니다. URL이 다른 여러 가지 문제를 해결하는 것입니다. 그리고 충돌하지 않고 모든 HTTP 메소드에 응답 할 수 있습니다. 항목 모음 인 리소스와 항목 자체를 나타내는 리소스를 가질 수 있습니다. 모두를 위해 나는 컬렉션의 자원이 될 수있다 신경 example.org/166316e2-e1and 이 수집 한 특정 항목 example.org/20d68348-ccc-001c4200de . 클라이언트는 URL을 구성해서는 안됩니다 (확장되지 않고 RESTful하지 않으며 링크 관계 유형의 목적입니다).
Erik

4
임의의 URL이 예쁘지 않다고 생각되면, 복수의 이름을 가진 컬렉션 리소스와 단수의 이름을 가진 개별 항목을 자유롭게 식별하십시오. 영어 URL이 마음에 들지 않고 자연어가 단수 / 복수 표기법을 지원하지 않는 경우 다른 언어를 사용하여 선호하는 언어로 정의하십시오. 모든 언어를 사용하여 '/ the-collection-of- bla / 2321 '대 서면'bla / 61 ' 그리고 GET / PUT / DELETE / POST / PATCH 등을 보낼 때이 두 개의 서로 다른 리소스는 완전히 다른 결과를 나타냅니다.
Erik

77

복수형

  • 단순 -모든 URL은 동일한 접두어로 시작합니다
  • 논리 - orders/주문의 색인 목록을 가져옵니다.
  • 표준 -가장 널리 채택 된 표준과 압도적 인 대다수의 공용 및 개인 API가 뒤 따릅니다.

예를 들면 다음과 같습니다.

GET /resources -자원 항목의 목록을 반환

POST /resources -하나 이상의 자원 항목을 작성합니다

PUT /resources -하나 이상의 자원 항목을 업데이트합니다

PATCH /resources -하나 이상의 리소스 항목을 부분적으로 업데이트

DELETE /resources -모든 자원 항목을 삭제합니다

단일 자원 항목의 경우 :

GET /resources/:id- :id매개 변수를 기반으로 특정 자원 항목을 리턴합니다.

POST /resources/:id -지정된 ID를 가진 하나의 자원 항목을 작성합니다 (검증 필요).

PUT /resources/:id -특정 자원 항목을 업데이트

PATCH /resources/:id -특정 자원 항목을 부분적으로 업데이트

DELETE /resources/:id -특정 자원 항목을 삭제합니다

단수의 옹호자들에게 다음과 같이 생각하십시오. 누군가에게 물어보고 order한 가지 또는 물건의 목록을 기대 하시겠습니까 ? 그렇다면 왜 입력 할 때 서비스가 목록을 반환해야 /order합니까?


10
단수 : - : 여기 더 상세한 예를 경우, 시스템의 일부가 하나의 객체 인 경우 예를 들어, 사용자 / 1 / 당신이 레이블이 하나의 객체를 단일 양식을 사용할 수 있습니다 아바타 (예를 들어 아바타) (0-1, 존재 여부) 에 유래를 .com / a / 38296217 / 860099 .
BTW-

클래스 이름과 테이블 이름에 대한 매핑은 어떻습니까? (참조 다른 대답을 )
윌 셰퍼드에게

@WillSheppard-클래스 이름은 단수 형태가 가장 좋고 테이블 이름은 복수 형태가 가장 좋습니다. 예를 들어 Order하나의 순서를 참조하는 객체의 단일 인스턴스를 처리하는 클래스의 좋은 이름입니다. OrderList여러 Order인스턴스 를 처리하는 클래스의 이름입니다 . Orders Table많은 주문의 데이터베이스 테이블에 대한 좋은 이름입니다.
Eric Knudtson

/ 주문을 받고 싶지만 / 1 만 원함
jim smith

@ jim-smith 그렇다면 GET / users / 1 사용자 모음에서 / 1을 요청하지 않는 이유는 무엇입니까?
Rohmer

49

단수형

편의 사물에는 불규칙 복수형 이름이있을 수 있습니다. 때때로 그들은 하나도 없습니다. 그러나 단수 이름은 항상 있습니다.

예를 들어 CustomerAddress를 통한 CustomerAddress

이 관련 리소스를 고려하십시오.

이것은 /order/12/orderdetail/12보다 읽기 쉽고 논리적 /orders/12/orderdetails/4입니다.

데이터베이스 테이블

자원은 데이터베이스 테이블과 같은 엔티티를 나타냅니다. 논리적 단수 이름이 있어야합니다. 다음은 테이블 이름에 대한 답변 입니다.

클래스 매핑

수업은 항상 단수입니다. ORM 도구는 클래스 이름과 동일한 이름으로 테이블을 생성합니다. 점점 더 많은 도구가 사용됨에 따라 단일 이름이 표준이되고 있습니다.

REST API 개발자의 딜레마 에 대해서 더 읽어보세요.


39
단수 이름은 항상있다 /clothe/12/trouser/34 :
거트 아놀드

18
@GertArnold 단어 clothe는 동사입니다. Rest API는 일반적으로 자원에 대해 말할 때 명사를 고수하고 조치를 설명 할 때 동사를 사용합니다. 단수형 clout은 고풍 적이며보다 적합하게 대체 될 수 있습니다 garment.
Steve Buzonas 2016 년

@SteveBuzonas 그리고 바지와 선글라스?
코레이 투 게이

32

가장 보편적 인 관행은 복수가 사용되는 RESTful api /api/resources/123이지만, 복수의 이름보다 단수의 이름이 더 적절하고 표현적인 경우가 있습니다. 일대일 관계의 경우입니다. 구체적으로 대상 항목이 가치 객체 (도메인 기반 디자인 패러다임) 인 경우.

모든 자원이 일대일로 accessLog가치 객체로 모델링 될 수 있다고 가정하자. 즉 개체가 아니기 때문에 ID가 없다. 로 표현 될 수 있습니다 /api/resources/123/accessLog. 일반적인 동사 (POST, PUT, DELETE, GET)는 의도와 관계가 실제로 일대일이라는 사실을 적절하게 표현합니다.


4
좋은 시도. 그러나 "accessLogEntries"로 더 좋습니다. :-)
Tom Russell

8
@TomRussell 왜? 이것의 의미는 중요합니다. 식별자로 리소스에 액세스 할 때도 복수를 사용하는 이유를 이해하지만 일대일 또는 일대일의 경우 오해의 소지가 있습니다. 다중 위치 회사의 직원을 관리하는 API를 고려하십시오. 각 직원은 한 곳에서 일합니다. GET /users/123/location사용자가 근무하는 위치를 가져와야합니다. GET /users/123/locations실제로 소비자로서 오도 되지 않습니까?
캐리 켄달

1
@CarrieKendall 나는 당신의 요점을 참조하십시오. 이후 accessLog속성 또는 값으로 모델화 라기보다 엔티티는 단수한다. 오버 엔지니어링을 받았다면, 로그 엔트리는 하나의 엔티티가 될 것 /api/accessLogEntries?resource=123입니다.
Tom Russell

동의하지만, 나는 그것이 모든 것을 복수화하는 관습을 어기는 것이라고 생각합니다. 까다로운 것입니다. 나에게는 API가 간단하다는 것이 중요합니다. 즉, 문서는 이미 간단한 구현을 보완해야합니다.
Carrie Kendall

저는 시스템이나 데이터베이스 사용자보다 프로그래머에 가깝기 때문에 컨벤션을 따르지 않고 이야기를하는 API를 좋아합니다. 그러나 자동화 된 문서의 의미는 실제입니다.
Tom Russell

26

단일 형식이 일반적으로 허용되는 데이터베이스 테이블 이름의 유행 추세를 따르십시오. 그곳에 다녀 왔으니 재사용하자.

테이블 이름 딜레마 : 단수와 복수 이름


8
Das Auto는 Die Autos보다 낫습니다. 또한 영어 복수 관습은 일치하지 않습니다.
FlavorScape

7
리소스 네임 스페이스는 구현이 아니라 시맨틱의 문제입니다. 따라서 DB 테이블 비유를 사용하는 것은 그리 운이 좋지 않습니다. 또한 DB로 작업 할 때 테이블 만 조작하지만 내용 (행)에 영향을 줄 수는 있지만 REST에서는 단일 리소스를 직접 조작 해야하는 제약이 없습니다 .
arpadf

3
나는 이것이 좋은 비유라고 생각하지만, 단수 또는 복수를 갈 것인지를 결정하는 것보다 더 중요한 것은 당신이 선택한 것과 일치하는 것입니다. 사용자에 삽입하지 않고 사용자에서 선택하지 않습니다. REST 리소스에도 동일한 규칙이 적용되어야합니다. 수행중인 작업에 따라 이름을 바꾸지 마십시오.
Todd Menier

3
테이블 이름뿐만 아니라 OO의 클래스 이름과 비슷합니다 (클래스는 고객이 아닌 고객이라고 함).
bytedev

이 경우 의미 체계는 단순히 "이미 정의 된"경향을 받아들이기에는 너무 중요합니다.
Cattani Simone

19

너무 많은 사람들이 복수 명사 악 대차를 타는 것을보고 놀랐습니다. 단수에서 복수로 변환 할 때 불규칙 복수 명사를 관리하고 있습니까? 당신은 고통을 즐기십니까?

참조 http://web2.uvcs.uvic.ca/elc/studyzone/330/grammar/irrplu.htm를

불규칙 복수형에는 여러 유형이 있지만 가장 일반적입니다.

복수의 예를 형성하는 명사형

Ends with -fe   Change f to v then Add -s   
    knife   knives 
    life   lives 
    wife   wives
Ends with -f    Change f to v then Add -es  
    half   halves 
    wolf   wolves
    loaf   loaves
Ends with -o    Add -es 
    potato   potatoes
    tomato   tomatoes
    volcano   volcanoes
Ends with -us   Change -us to -i    
    cactus   cacti
    nucleus   nuclei
    focus   foci
Ends with -is   Change -is to -es   
    analysis   analyses
    crisis   crises
    thesis   theses
Ends with -on   Change -on to -a    
    phenomenon   phenomena
    criterion   criteria
ALL KINDS   Change the vowel or Change the word or Add a different ending   
     man   men
     foot   feet
     child   children
     person   people
     tooth   teeth
     mouse   mice
 Unchanging Singular and plural are the same    
     sheep deer fish (sometimes)

5
나는 여기서 우려를 이해하지 못한다. 프로그래밍 방식으로 단수를 복수로 변경해서는 안됩니다. 상기 복수 형태의 대부분은 잘 알려져 있으며, 걱정해서는 안된다. 영어 지식이 부족한 사람은 변수의 일부를 잘못 철자하게됩니다. 또한 논리에 따라 단일 코드를 사용하여 소스 코드의 컬렉션을 참조하는 것이 좋습니다.
kishor borate

1
앵글로 스피어 내에서도 종종 문제가 될 정도로 불규칙한 영어 단어가 있으며 색인 / 인덱스 / 인덱스, 버텍스 / 버텍스 / 버텍스, 매트릭스 / 매트릭스 / 매트릭스, 반경 / 반경 / radii 등. 어쨌든 REST 경로를 복수로 만드는 요점은 보이지 않습니다. 왜냐하면 그들이 모두 일관되게 단수라면 모든 사람에게 더 분명하기 때문입니다.
44 분

@kishorborate, 복수를 URI로 사용하면 영어를 모국어로 사용하는 사람들에게도 오류가 발생하기 쉽습니다. damd에서 알 수 있듯이 인덱스 / 인덱스 / 표시와 같은 복수는 더 많은 문제를 야기하고 있습니다. 그리고 셀 수없는 명사들이 있습니다. 셀 수없는 명사와 복수를 섞는 것도 또 다른 문제입니다. 프로그래머가 이것에 더 많은 시간을 소비하기 어려운 이유는 무엇입니까? 모든 것에 단수형을 사용하는 것이 좋습니다. / {id}가 있으면 API는 단일 레코드를 반환해야합니다. 다음에 / {id}가 없으면 API는 컬렉션을 반환해야합니다.
Daming Fu

3
@DamingFu 단수형 리소스에 항상 관련된 ID가있는 것은 아닙니다. 예. / user / {id} / nickName 그것을 보면 nickNames 또는 단일 nickName 목록을 반환할지 여부가 확실하지 않습니까? 따라서 API는 복수 형식을 사용할 때 더욱 직관적입니다. 그렇습니다. 불규칙 복수형을 가진 단어는 거의 없습니다. 복수형을 읽는 사람에게는 문제가되지 않습니다. API 서명을 작성할 때만 문제가됩니다. 그러나 그러한 단어의 빈도는 높지 않으며, 어떤 단어의 복수 형태를 찾는 데 시간이 걸리지 않습니다. API를보다 직관적으로 만들기 위해서는 수용해야합니다.
kishor borate

15

API 소비자의 관점에서 엔드 포인트는 예측 가능해야합니다.

이상적으로는 ...

  1. GET /resources 리소스 목록을 반환해야합니다.
  2. GET /resource 400 레벨 상태 코드를 반환해야합니다.
  3. GET /resources/id/{resourceId} 하나의 리소스가있는 컬렉션을 반환해야합니다.
  4. GET /resource/id/{resourceId} 자원 객체를 반환해야합니다.
  5. POST /resources 리소스를 일괄 생성해야합니다.
  6. POST /resource 자원을 만들어야합니다.
  7. PUT /resource 자원 객체를 업데이트해야합니다.
  8. PATCH /resource 변경된 속성 만 게시하여 리소스를 업데이트해야합니다.
  9. PATCH /resources 변경된 속성 만 게시하는 리소스를 일괄 업데이트해야합니다.
  10. DELETE /resources모든 자원을 삭제해야합니다. 농담 : 400 상태 코드
  11. DELETE /resource/id/{resourceId}

이 접근 방식은 가장 유연하고 기능이 풍부하지만 개발에 가장 많은 시간이 소요됩니다. 따라서 급한 경우 (항상 소프트웨어 개발의 경우) 엔드 포인트 resource또는 복수형의 이름을 지정하십시오 resources. 단수형은 모든 복수형이 's'로 끝나는 것이 아니기 때문에 프로그래밍 방식으로 검사하고 평가할 수있는 옵션을 제공하기 때문에 선호합니다.

무엇이든, 가장 일반적으로 사용되는 실습 개발자가 선택한 이유는 복수형을 사용하는 것입니다. 이것은 궁극적으로 내가 선택한 경로이며 인기있는 api를 githuband 처럼 보면 twitter이것이 그들이하는 일입니다.

결정 기준은 다음과 같습니다.

  1. 시간 제약은 무엇입니까?
  2. 소비자는 어떤 작업을 수행 할 수 있습니까?
  3. 요청 및 결과 페이로드는 어떤 모양입니까?
  4. 리플렉션을 사용하고 코드에서 URI를 구문 분석하고 싶습니까?

따라서 그것은 당신에게 달려 있습니다. 당신이하는 일이 무엇이든


1
등이 보인다 복수의 개발자가 모든 자원이 본질적으로 약간의 컬렉션의 일부 있다고 가정하는 것 때문에 형태가 선택되었다. 그러나 "허용 된 규칙"은 POST /users단일 사용자를 작성하여 콜렉션에 추가해야 함을 나타냅니다 . 동의하지 않습니다. 정확히 하나의 사용자를 작성해야하는 사용자 POST /users목록 (1의 목록 인 경우에도) POST /user을 작성해야합니다. 복수 리소스와 단일 리소스 엔드 포인트가 공존 할 수없는 이유는 없습니다. 그들은 다른 행동을 묘사하며, 그들의 기능을 누구도 놀라게해서는 안됩니다.
11:20에

경로에 리소스 ID를 지정하는 규칙이 없습니까? 그렇다면 널리 무시되는 것 같습니다. 예를 들어 POST users/<id>새 사용자를 만듭니다.
Tom Russell

1
@TomRussell은 일반적으로 서버가 ID를 생성하므로 아직 POST 할 ID를 모를 것입니다.
Alex

3
@TomRussell은 클라이언트가 새 리소스를 만들 때 (일종의) ID를 결정할 때 PUT /users/<id>대신에 사용하는 것이 더 일반적 입니다 POST. POST"컬렉션에 추가하고 ID를 그 일부로 결정"이라는 해석이 있습니다. PUT"이 ID로이 자원을 갱신 (또는 추가)"한다는 해석이 있습니다. 이 원리에 대한 자세한 설명은 restcookbook.com/HTTP%20Methods/put-vs-post 를 참조하십시오 .
Jochem Schulenklopper

트위터 API와의 비교가 모든 종점에 복수형을 사용하기 때문에 공정하지 않다고 생각합니다. 동일한 요소에 대해 복수형과 단수형을 혼합하지 않습니다.
Andrew T Finnell

7

내 두 센트 : 복수에서 단수로 또는 그 반대로 시간을 보내는 방법은 CPU 사이클을 낭비합니다. 나는 구식이 될 수도 있지만 내 시대에는 같은 것이라 불렀습니다. 사람들에 관한 방법을 어떻게 찾습니까? 바람직하지 않은 부작용없이 사람과 사람 모두를 정기적으로 처방하지는 않습니다.

영어 복수는 매우 임의적 일 수 있으며 코드를 불필요하게 방해합니다. 하나의 명명 규칙을 고수하십시오. 컴퓨터 언어는 자연 언어를 흉내내는 것이 아니라 수학적으로 명확해야합니다.


2
이것은 엔드 포인트 "자동 생성 / 혼합"을 시도하는 코드를 다룹니다 (복수 / 단수를 가정하고 매핑을 시도하는 의견이 많은 라이브러리가 있습니다). 그러나 이는 복수형에 관계없이 올바른 단어를 선택하는 것 이상 으로 명시 적으로 선택된 엔드 포인트 이름 에 적용됩니다 .
user2864740

6

단순성과 일관성을 위해 단일 형식을 사용하는 것이 좋습니다.

예를 들어 다음 URL을 고려하십시오.

/ 고객 / 1

고객을 고객 수집으로 취급하지만 단순성을 위해 수집 부분이 제거됩니다.

또 다른 예:

/ 장비 / 1

이 경우 장비는 올바른 복수형이 아닙니다. 따라서 장비 수집으로 취급하고 단순화를 위해 수집을 제거하면 고객 사례와 일치합니다.


2
POST / customer는 유일한 고객을 대체하는 것처럼 들립니다. 이것은 단일 리소스 이름을 사용함에있어 가장 큰 슬픔입니다.
Andrew T Finnell

2
@ andrew-t-finnell POST /customer바로 그 일을하기로되어 있지 않습니까? 단일 고객을 삽입 하시겠습니까?
donmutti

단일 고객을 고객 모음에 삽입합니다. POST /customer마치 the고객에게 POST하는 것처럼 읽습니다 . 고객 모음이 아닙니다. 그러나 복수형 또는 복수형이 선호됨을 인정합니다. 다른 답변과 같이 혼합되지 않은 한. 그것은 매우 혼란 스러울 것입니다.
앤드류 T 피넬

이 경우 "고객에게 POST"는 의미가 없습니다. POST는 대체되지 않고 삽입됩니다. 어쩌면 POST / customer / 1 인 경우 딜레마를 볼 수는 있지만 REST 관점에서 그다지 의미가 없습니다. 무엇을 삽입하고 있습니까? / customer / 1 / invoice 또는 / customer / 1 / receipt 등이됩니다.

5

경로의 ID는 목록의 색인과 동일하게보아야하며 그에 따라 이름 지정이 진행되어야합니다.

numbers = [1, 2, 3]

numbers            GET /numbers
numbers[1]         GET /numbers/1
numbers.push(4)    POST /numbers
numbers[1] = 23    UPDATE /numbers/1

그러나 일부 리소스는 경로가 하나만 있거나 사용자가 둘 이상에 액세스 할 수 없으므로 경로에 ID를 사용하지 않으므로 목록에 없습니다.

GET /dashboard
DELETE /session
POST /login
GET /users/{:id}/profile
UPDATE /users/{:id}/profile

4

명명 규칙을 사용하면 일반적으로 "하나만 골라 고수"라고 말하는 것이 안전합니다.

그러나 많은 사람들에게 REST를 설명한 후 엔드 포인트를 파일 시스템의 경로 로 나타내는 것이 가장 표현적인 방법입니다.
상태가없고 (파일이 존재하거나 존재하지 않음) 계층 적이며 단순하며 친숙합니다. 로컬 또는 http를 통해 정적 파일에 액세스하는 방법을 이미 알고 있습니다.

이러한 맥락에서 언어 규칙은 다음과 같은 범위 내에서만 가능합니다.

디렉토리는 여러 파일 및 / 또는 하위 디렉토리를 포함 할 수 있으므로 이름 복수 형식 이어야 합니다.

그리고 나는 그것을 좋아한다.
반면 디렉토리는 디렉토리이지만 원하는 경우 "자원 또는 다중 자원"으로 이름을 지정할 수 있습니다. 그것은 정말로 중요한 것이 아닙니다.

중요한 것은 "resourceS"라는 디렉토리에 "123"이라는 파일을 넣은 경우 (을 통해) 파일을 /resourceS/123통해 액세스 할 수 없다는 것 /resource/123입니다.

현재 액세스하는 리소스의 수에 따라 복수에서 단일로 변경하는 것이 현명하게 만들려고하지 마십시오. 계층 적 시스템.

참고 : 기술적으로 "기호 링크"를 만들 수 있으므로를 /resources/123통해 액세스 할 수도 /resource/123있지만 전자는 여전히 존재해야합니다!


3

한 번 봐 가지고 구글자원 이름 : API 디자인 가이드 명명 자원에 대한 또 다른 테이크를.

한마디로 :

  • 컬렉션은 복수형으로 명명됩니다.
  • 개별 리소스는 문자열로 이름이 지정됩니다.
|--------------------------+---------------+-------------------+---------------+--------------|
| API Service Name         | Collection ID | Resource ID       | Collection ID | Resource ID  |
|--------------------------+---------------+-------------------+---------------+--------------|
| //mail.googleapis.com    | /users        | /name@example.com | /settings     | /customFrom  |
| //storage.googleapis.com | /buckets      | /bucket-id        | /objects      | /object-id   |
|--------------------------+---------------+-------------------+---------------+--------------|

이 주제에 대해 생각하고 있다면 읽을 가치가 있습니다.


2

Postman (또는 유사한 툴)을 사용하여 리소스 API를 개발하고 테스트하는 경우 GET에서 PUT으로 POST 등을 전환 할 때 URI를 편집 할 필요가 없습니다. .


1
Postman이 콜렉션을 제공하므로 나에게 논쟁이되지 않으므로 모든 자원을 다른 콜렉션 항목으로 저장하고 개별적으로 테스트 할 수 있습니다. 컬렉션에서 리소스를 선택하기 만하면 매번 매개 변수 / 방법 / 등을 편집 할 필요가 없습니다.
Wirone

1

두 표현 모두 유용합니다. 나는 편의를 위해 단기간 동안 단수를 사용했는데, 활용은 어려울 수 있습니다. 엄격하게 단일 REST API를 개발 한 경험을 통해 엔드 포인트를 소비하는 개발자는 결과의 모양이 확실하지 않습니다. 이제 응답의 모양을 가장 잘 나타내는 용어를 사용하는 것을 선호합니다.

모든 리소스가 최상위 수준이면 단일 표현으로 벗어날 수 있습니다. 변곡을 피하는 것이 큰 승리입니다.

관계에 대한 쿼리를 나타 내기 위해 일종의 딥 링크를 수행하는 경우 엄격한 규칙을 사용하여 API를 작성하는 개발자에게 도움을 줄 수 있습니다.

내 규칙은 URI의 각 수준에서 상위 리소스와의 상호 작용을 설명하고 있으며 전체 URI는 검색 대상을 암시 적으로 설명해야한다는 것입니다.

다음과 같은 모델이 있다고 가정합니다.

interface User {
    <string>id;
    <Friend[]>friends;
    <Manager>user;
}

interface Friend {
    <string>id;
    <User>user;
    ...<<friendship specific props>>
}

클라이언트가 특정 사용자의 특정 친구의 관리자를 얻을 수있는 리소스를 제공해야하는 경우 다음과 같이 보일 수 있습니다.

GET /users/{id}/friends/{friendId}/manager

다음은 몇 가지 예입니다.

  • GET /users -글로벌 사용자 콜렉션에 사용자 자원을 나열하십시오.
  • POST /users -글로벌 사용자 콜렉션에서 새 사용자 작성
  • GET /users/{id} -글로벌 사용자 콜렉션에서 특정 사용자를 검색
  • GET /users/{id}/manager -특정 사용자의 관리자 확보
  • GET /users/{id}/friends -사용자의 친구 목록을 얻습니다.
  • GET /users/{id}/friends/{friendId} -사용자의 특정 친구를 얻으십시오
  • LINK /users/{id}/friends -이 사용자에게 친구 연결 추가
  • UNLINK /users/{id}/friends -이 사용자로부터 친구 연결을 제거

각 레벨이 수행 될 수있는 상위에 어떻게 맵핑되는지 확인하십시오. 동일한 객체에 대해 다른 부모를 사용하는 것은 반 직관적입니다. 에 리소스를 검색하면 GET /resource/123새 리소스를 생성해야한다는 표시가 없습니다.POST /resources


1

나는 대부분의 사람들이 복수를 사용할 것인지 단수를 사용할 것인지를 결정하는 사이에 있다는 것을 알고 있습니다. 여기서 해결되지 않은 문제는 고객이 사용중인 클라이언트를 알아야하며 항상 실수를 할 가능성이 있다는 것입니다. 이것은 내 제안에서 비롯된 것입니다.

둘 다 어때요? 그리고 그것은 전체 API에 단수를 사용하고 복수 형태로 된 요청을 단수 형태로 전달하는 경로를 만듭니다. 예를 들면 다음과 같습니다.

GET  /resources     =     GET  /resource
GET  /resources/1   =     GET  /resource/1
POST /resources/1   =     POST /resource/1
...

당신은 그림을 얻는다. 아무도 잘못하지 않고 최소한의 노력만으로도 고객은 항상 올바른 결과를 얻을 수 있습니다.


1
302 리디렉션을 수행하고 캐시가 모든 것을 두 번 저장하는 경우 캐시를 잘못 설정 한 것입니다. 캐시는 302 리디렉션을 저장하지 않아야합니다.
wynnset

2
고객이 항상 사용 /resources하고로 리디렉션되는 /resource경우 잘못한 것입니다. 다른 사람이 귀하의 API를 사용하는 경우 올바른 URL을 직접 사용하거나 리디렉션 (작동하지만 잘못됨) 할 수 있으며 잘못된 방식으로 연 사람입니다.
maaartinus

당신이 "틀린"의 의미로 확실하지 않은-그것은 매우 주관적입니다. 작동하기 때문에 실제로 잘못되지 않습니다.
wynnset

유지 관리 비용, 이해 비용 및 필요한 코드 양이 증가합니다.
윌 셰퍼드

1

이론적으로는 무엇이든지 모호성이있을 수 있기 때문에 {id}URL 의 일부가 하위 리소스와 겹치는 것을보고 싶지 않습니다 id. 서로 다른 개념 (식별자와 하위 리소스 이름)을 혼합하고 있습니다.

비슷한 문제가 종종에서 볼 수 있습니다 enum당신은 폴더가있을 때, 상수 또는 다른 개념이 (혼합 예를 들어 구조물, 폴더 Tigers, Lions그리고 Cheetahs다음도라는 폴더 Animals같은 수준은 - 하나의 부분 집합으로이 말도 안돼 다른).

일반적으로 엔드 포인트의 마지막 명명 된 부분은 한 번에 하나의 엔티티를 처리하는 경우 단수 여야하고 엔티티 목록을 처리하는 경우 복수 여야합니다.

따라서 단일 사용자를 다루는 엔드 포인트 :

GET  /user             -> Not allowed, 400
GET  /user/{id}        -> Returns user with given id
POST /user             -> Creates a new user
PUT  /user/{id}        -> Updates user with given id
DELETE /user/{id}      -> Deletes user with given id

그런 다음 사용자에 대한 쿼리를 수행하기위한 별도의 리소스가 있으며 일반적으로 목록을 반환합니다.

GET /users             -> Lists all users, optionally filtered by way of parameters
GET /users/new?since=x -> Gets all users that are new since a specific time
GET /users/top?max=x   -> Gets top X active users

다음은 특정 사용자를 다루는 하위 리소스의 예입니다.

GET /user/{id}/friends -> Returns a list of friends of given user

친구를 사귀십시오 (다 대다 링크).

PUT /user/{id}/friend/{id}     -> Befriends two users
DELETE /user/{id}/friend/{id}  -> Unfriends two users
GET /user/{id}/friend/{id}     -> Gets status of friendship between two users

모호성이 없으며 자원의 복수 또는 단수 이름은 사용자가 기대할 수있는 것 (목록 또는 객체)에 대한 힌트입니다. 에 대한 제한은 없으므로 id이론적 new으로 (잠재적 미래) 하위 리소스 이름과 겹치지 않고 ID 를 가진 사용자를 가질 수 있습니다.


1

Singular를 사용하고 "Business Directory"와 같은 영어 규칙을 활용하십시오.

"Book Case", "Dog Pack", "Art Gallery", "Film Festival", "Car Lot"등 많은 것들이이 방식으로 읽 힙니다.

이것은 URL 경로를 왼쪽에서 오른쪽으로 편리하게 일치시킵니다. 왼쪽의 상품 유형입니다. 오른쪽에 유형을 설정하십시오.

않습니다 GET /users정말 지금까지 사용자 세트를 가져? 보통은 아닙니다. 키와 사용자 이름이 포함 된 스텁 세트를 가져옵니다. /users어쨌든 실제로는 아닙니다 . 사용자 인덱스이거나 "사용자 인덱스"입니다. 왜 그렇게 부르지 않습니까? 그것은이다 /user/index. set 유형의 이름을 지정 했으므로 쿼리 매개 변수 (예 : user/phone-list또는)에 의존하지 않고 사용자의 다른 투영을 보여주는 여러 유형을 가질 수 있습니다 /user/mailing-list.

그리고 User 300은 어떻습니까? 아직 /user/300입니다.

GET /user/index
GET /user/{id}

POST /user
PUT /user/{id}

DELETE /user/{id}

마지막으로 HTTP는 단일 요청에 대한 단일 응답 만 가질 수 있습니다. 경로는 항상 단수의 무언가를 말합니다.


-1

나에게 복수형은 컬렉션을 조작하는 반면, 단수형은 해당 컬렉션 내의 항목을 조작합니다 .

수집GET / POST / DELETE 메소드를 허용합니다

GET / PUT / DELETE 방법을 허용하는 항목

예를 들어

POST on / students 는 학교에 새로운 학생을 추가 할 것입니다.

에 삭제 / 학생 학교의 모든 학생을 제거합니다.

/ student / 123의 DELETE 는 학교에서 학생 123을 제거합니다.

중요하지 않은 것처럼 느껴질 수도 있지만 일부 엔지니어는 때때로 ID를 잊어 버립니다. 경로가 항상 복수이고 삭제를 수행 한 경우 실수로 데이터를 지울 수 있습니다. 단수의 ID가 없으면 404 경로를 찾을 수 없습니다.

API가 여러 학교를 노출해야하는 경우 예제를 추가로 확장하려면

DELETE에 / 학교 / ABC / 학생들은 학교에서 모두에게 학생을 제거합니다 abc.

올바른 단어를 선택하는 것이 때로는 어려운 일이지만, 수집을 위해 복수를 유지하는 것을 좋아합니다. 예 cart_items또는 cart/items올바른 느낌. 반대로 삭제 cart는 카트 오브젝트를 삭제하지만 카트 내의 항목은 삭제하지 않습니다.).


어쨌든 / cart와 / cart / item (s)이 분할되어서는 안됩니까? 그렇다면 전체 장바구니 (예 : 삭제) 또는 개별 항목을 처리 할 수 ​​있습니까?
Rob Grant

@RobertGrant "/ carts / items / 123"이 아닌가? (예 : "장바구니"가 아닌 "장바구니"가 규칙이 '항상 복수형'인 이유는 무엇입니까?)
user2864740

1
프로덕션 코드를 체크인하면 모든 사람의 장바구니 항목을 삭제할 수 있다고 명명 규칙보다 더 큰 문제가 있다고 주장합니다. 그들이 ID보다 's'를 기억할 가능성은 훨씬 적습니다.
Andrew T Finnell

누구나 단순히 전체 컬렉션을 삭제하는 엔드 포인트를 작성 했습니까? 나에게 매우 위험한 것처럼 보이며 아마도 REST가 실제로 배치 삭제를 지원하지 않는 이유 일 것입니다. (배열을 객체로 감싸 야합니다). 나는 절대적으로 전체 콜렉션을 삭제하는 엔드 포인트를 필요한 경우, 내가 URI는 POST와 유사한 매우 매우 독특한, 확실히 아니었다 있는지 확인하십시오 것
CNPS

-1

어때요?

/resource/(아니요 /resource)

/resource/ "resource"라는 폴더가 있고 "resouce"폴더라는 것을 의미합니다.

또한 데이터베이스 테이블의 명명 규칙이 동일하다고 생각합니다. 예를 들어 'user'라는 테이블은 "user table"이며 "user"라는 것이 포함되어 있습니다.


-2

복수 ( /resources)와 단수 ( /resource/{id})를 모두 사용하는 것이 좋습니다. 왜냐하면 논리 수집이 자원 수집 작업과 단일 자원 작업 간의 논리를 더 명확하게 구분한다고 생각하기 때문입니다.

이것의 중요한 부작용으로, 누군가 API를 잘못 사용하는 것을 막을 수 있습니다. 예를 들어, 사용자가 다음과 같이 ID를 매개 변수로 지정하여 자원을 잘못 가져 오려고 시도하는 경우를 고려하십시오.

GET /resources?Id=123

이 경우 복수 버전을 사용하는 경우 서버는 대부분 Id 매개 변수를 무시하고 모든 리소스 목록을 반환합니다. 사용자가주의하지 않으면 호출이 성공했다고 생각하고 목록의 첫 번째 자원을 사용합니다.

반면에 단수형을 사용할 때 :

GET /resource?Id=123

서버는 ID가 올바른 방식으로 지정되지 않았기 때문에 오류를 반환 할 가능성이 높으며 사용자는 무언가 잘못되었음을 인식해야합니다.


1
왜 이디엄을 섞고 있습니까? 첫 번째 단락에서 올바른 URI 표기법을 사용하고 쿼리 매개 변수로 전환 하시겠습니까? 쿼리 매개 변수를 사용하여 ID가 ​​123 인 리소스를 얻는 것은 전적으로 기본이 아닙니다.
Andrew T Finnell

그것은 분명히 실수였습니다. 지금 답변을 업데이트했습니다. 알아 주셔서 감사합니다.
pberggreen

다시 downvoted 후, 나는 내가 쓴 것을 보았고 원래 게시물이 정확하다는 것을 깨달았습니다. 내 요점은 사용자가 잘못된 일을하면 복수 + 단수를 사용하면 실제로 복수 만 사용하는 더 나은 오류 메시지를 제공한다는 것입니다.
pberggreen

여전히 이것이 문제를 혼란스럽게 생각합니다. 복수를 사용하는 아이디어는 그것이 모음이라는 것입니다. 그리고 끝에있는 숫자는 컬렉션에 대한 인덱스입니다. 자체적으로 리소스를 얻는 경우 어떻게됩니까? 복수형과 단수형을 함께 사용하는 것은 상당히 혼란 스럽다. / resources / 123의 말 : 리소스 버킷에서 리소스 123을 가져옵니다.
Andrew T Finnell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.