2010-01-20 18 views
13

Solo quería recibir comentarios sobre cómo planeo diseñar mi API. Métodos ficticios a continuación. Aquí está la estructura:REST Web Services API Design

GET http://api.domain.com/1/users/ <-- returns a list of users 
POST http://api.domain.com/1/users/add.xml <-- adds user 
POST http://api.domain.com/1/users/update.xml <-- updates user 
DELETE (or POST?) http://api.domain.com/1/users/delete.xml <-- deletes user 

Preguntas:

  1. ¿Está bien usar solo GET y POST?
  2. ¿Es una buena idea que confíe en el nombre de archivo para indicar qué operación debo hacer (por ejemplo, agregar.xml para agregar)? ¿Sería mejor hacer algo como esto: POST http://api.domain.com/1/users/add/data.xml?
  3. ¿Cuál es una buena manera de mantener estos recursos versionados? En mi ejemplo, yo uso a/1/después del nombre de dominio para indicar la versión 1. Las alternativas serían: http://api1.domain.com ... o ... o http://api-1.domain.comhttp://apiv1.domain.com ... o http://api-v1.domain.com ... o ... o http://api.domain.com/v1/
  4. ¿Cuál es la mejor manera de autenticarse?
+0

[API REST Arquitectura - Buenas Prácticas] (http://dasunhegoda.com/rest-api-architecture-best-practices/1049/) – Techie

Respuesta

7

1) En su diseño probablemente no. ¡POST no es idempotente! Por lo tanto no se debe utilizar para la actualización o la eliminación, en lugar de utilizar PUT y DELETE del Rest

2) Una mejor opción es utilizar la cabecera Content-Type en la llamada WS, como: application/xml

3) también en la cabecera Content-Type u puede utilizarlo: aplicación-v1.0/xml

4) No estoy seguro si es el mejor, pero probablemente la forma más sencilla es utilizar HTTP incorporado en la autenticación mecanismos en RFC 2617. Un ejemplo: AWS Authentication

+1

1: PUT es una mejor opción para la actualización. –

+0

su razonamiento sobre (1) es débil. POST no es "no idempotente", no es "necesariamente idempotente". Como él define la semántica del lado del servidor, su POST podría ser idempotente y eso es genial con http y el mundo en general. –

+0

@NasBanov De la documentación de w3.org Http Methods http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html. Eche un vistazo a la sección 9.1.2 Métodos Idempotentes. La publicación nunca se muestra como un posible Método Idempotente. –

0
  1. En reposo, el HTTP "verbo" se usa para denotar el tipo de operación: usted no será capaz de expresar todas las operaciones CRUD con solamente "GET" y "POST"

  2. no: la URL del recurso generalmente es donde debería aparecer el "identificador del documento"

  3. La versión del "documento" se puede transmitir en un encabezado de respuesta HTTP al crear/modificar dicho recurso. Debería ser el deber del servidor identificar de manera única los recursos; tratar de hacerlo en el lado del cliente demostrará ser un desafío desalentador, es decir, mantener la coherencia.

Por supuesto, hay muchas variaciones sobre el tema ...

0

Realicé la autenticación basada en los encabezados. Algo como

X-Username:happy-hamster 
X-Password:notmyactualpassword 

Si le preocupa la seguridad, hágalo a través de SSL. Existen otras implementaciones, por supuesto. Por ejemplo, Amazon con su S3: http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTAuthentication.html

Si no tiene la capacidad de realizar solicitudes PUT y DELETE, se considera una buena práctica hacer un túnel a través de POST. En este caso, la acción se especifica en URL.Si no recuerdo mal, RoR hace exactamente esto:

POST http://example.com/foos/2.xml/delete 

o

POST http://example.com/foos/3.xml/put 

... 

<foo> 
    <bar>newbar</bar>  
</foo> 

Es un offtop poco, pero en cuanto a control de versiones y descansar en general es posible que desee echar un vistazo a CouchDB. Aquí es un good book available on-line

39

Antes de cavar en el reposo, aquí hay algunos términos que realmente necesita para captar:

de recursos - La cosas/datos que desea poner a disposición en su API (en su caso, un " Usuario ")

URI - Una identificación universalmente única para un recurso. No debe mencionar nada sobre el método que se está realizando (por ejemplo, no debe contener "agregar" o "eliminar"). Sin embargo, la estructura de su URI no hace que su aplicación sea más o menos RESTANTE; esta es una idea errónea común.

Interfaz uniforme - Un conjunto fijo de operaciones puede realizar en sus recursos, en la mayoría de los casos esto es HTTP. Existen definiciones claras para cada uno de estos métodos HTTP.

Lo más inquietante que tienen sus URI es que tienen información sobre la operación que se está realizando en ellos. ¡Los URI son identificaciones y nada más!

Tomemos un ejemplo del mundo real. Mi nombre es Nathan. "Nathan" podría considerarse mi identificación (o en términos de descanso URI - a los fines de este ejemplo supongo que soy el único "Nathan"). Mi nombre/ID no cambia en función de cómo te gustaría interactuar conmigo, p. Mi nombre no cambiaría a "NathanSayHello" cuando quisiste saludarme.

Pasa lo mismo con REST. Su usuario identificado por http://api.domain.com/users/1 no cambia a http://api.domain.com/users/1/update.xml cuando desea actualizar ese usuario. El hecho de que quiera actualizar ese usuario está implícito en el método que está utilizando (por ejemplo, PUT).

Aquí es mi sugerencia para sus URIs

# Retrieve info about a user 
GET http://api.domain.com/user/<id> 

# Retrieve set all users 
GET http://api.domain.com/users 

# Update the user IDed by api.domain.com/user/<id> 
PUT http://api.domain.com/user/<id> 

# Create a new user. The details (even <id>) are based as the body of the request 
POST http://api.domain.com/users 

# Delete the user ID'd by api.domain.com/user/<id> 
DELETE http://api.domain.com/user/<id> 

En cuanto a sus preguntas:

  1. Uso PUT y DELETE cuando sea apropiado y evite la sobrecarga de POST para manejar estas funciones, ya que rompe HTTP's definition of POST. HTTP es tu interfaz uniforme. Es su contrato con el usuario de API sobre cómo pueden esperar interactuar con su servicio. Si rompe HTTP, rompe este contrato.

  2. Eliminar "agregar" por completo. Utilice el encabezado Content-Type de HTTP para especificar el tipo de mime de los datos publicados.

  3. ¿Se refiere a la versión de su API o la versión del recurso? ETag y otros encabezados de respuesta se pueden usar para versionar los recursos.

  4. Muchas opciones aquí. Basic HTTP Auth (fácil pero inseguro), Digest Auth, autenticación personalizada como AWS. OAuth también es una posibilidad. Si la seguridad es de importancia principal, uso certificados SSL del lado del cliente.

+3

+1 en respuesta, pero: PUT/DELETE deben ser idempotentes, no POST. POST puede ser lo que le plazca. "Idempotente" solo significa que si la operación se repite dos veces, produce el mismo resultado - en matemática que es 'f (f (x)) = f (x)'. En nuestro caso, si se hacen dos PUT idénticos para el mismo recurso, el resultado debe ser el mismo que si solo se hiciera 1. POST por otro lado, dependiendo de la semántica dada por el desarrollador, puede tener diferentes resultados (por ejemplo, POST dos veces puede enviar 2 correos electrónicos) –

+0

tiene toda la razón. que debería decir "falta general de idempotencia", ya que la mayoría de las veces está creando recursos (o en su ejemplo un trabajo para enviar un correo electrónico) que definitivamente no es idempotente. ajustará la publicación en consecuencia. – nategood