Comment implémenter un appel de service de suppression à l’aide de ServiceStack

J’ai quelques questions relatives à la mise en œuvre du service REST à l’aide de ServiceStack.

  1. Pour l’opération GET, je définis ma requête DTO comme suit:

    [Route("/Customer/{ID}", Verbs = "GET")] public class GetCustomer : IReturn { .... .... } 

Ici, “GetCustomer” est une requête DTO et “GetCustomerResponse” est une réponse DTO. Mais pour l’opération PUT / POST / DELETE, j’ai juste besoin de savoir si l’opération a été validée avec succès et si “non”, quelle est l’exception. Alors, quelle devrait être ma demande de définition pour POST / PUT / DELETE? Devrait-il utiliser IReturnVoid comme indiqué ci-dessous?

 [Route("/Customer/{ID}", Verbs = "DELETE")] public class DeleteCustomer : IReturnVoid { .... .... } 

Si je dois utiliser IReturnVoid, comment puis-je récupérer les informations sur les exceptions susceptibles de se produire lors de la validation de mon opération?

Dans le document de traitement des erreurs pour la stack de services, il est écrit et je cite ci-dessous

Types de réponse d’erreur

La réponse d’erreur renvoyée lors de la levée d’une exception varie selon qu’un DTO {RequestDto} Response de nom conventionnel existe ou non.

S’il existe:

La réponse {RequestDto} est renvoyée, quel que soit le type de réponse de la méthode de service. Si le {RequestDto} Response DTO a une propriété ResponseStatus, elle est remplie, sinon aucun ResponseStatus ne sera renvoyé. (Si vous avez décoré la classe et les propriétés {ResponseDto} Response avec les atsortingbuts [DataContract] / [DataMember], alors ResponseStatus doit également être décoré pour être rempli).

Sinon, si ce n’est pas le cas:

Un ErrorResponse générique est renvoyé avec une propriété ResponseStatus renseignée.

Les clients du service traitent de manière transparente les différents types de réponse d’erreur et, pour les formats sans schéma tels que JSON / JSV / etc, il n’y a pas de différence visible entre le renvoi d’un ResponseStatus dans un ErrorResponse personnalisé ou générique, car ils produisent tous les deux la même réponse sur le réseau.

Ce que je ne comprends pas, c’est quel devrait être le type de retour pour ma méthode Delete dans la mise en œuvre de mon service? Comment puis-je implémenter ma méthode de suppression sans définir la réponse de suppression DTO tout en pouvant récupérer les informations sur l’erreur ‘ErrorResponse’?

  1. Est-il possible de définir route avec le verbe “DELETE”? J’ai la mise en œuvre suivante.

Route:

 [Route("/DeleteCustomer/{ID}", Verbs = "DELETE")] public class DeleteCustomer : IReturn { public int ID { get; set; } } 

Mise en œuvre de la méthode:

 public DeleteContactResponse Delete(DeleteContact request) { ..... } 

Mais chaque fois que j’appelle cette suppression en utilisant mon client, j’obtiens toujours une exception “NotFound”. J’ai essayé différents clients mais avec tout ce que j’ai l’erreur 404.

Un des liens de référence disponible dans le document Servicestack réutilise les verbes “GET” et “DELETE”.

Un autre lien suggère que tous les navigateurs ne supportent pas l’opération de suppression.

Je me demande donc comment l’opération de suppression devrait être implémentée?

Reportez-vous à cette réponse précédente pour savoir comment concevoir une API REST-ful avec ServiceStack .

CustomerRestExample contient un exemple complet et autonome de service REST ServiceStack client:

Définition du service client

Voici un exemple de DTO d’itinéraires et de demandes personnalisés de ce à quoi un service REST client typique pourrait ressembler:

 [Route("/customers", "GET")] public class GetCustomers : IReturn {} public class GetCustomersResponse { public List Results { get; set; } } [Route("/customers/{Id}", "GET")] public class GetCustomer : IReturn { public int Id { get; set; } } [Route("/customers", "POST")] public class CreateCustomer : IReturn { public ssortingng Name { get; set; } } [Route("/customers/{Id}", "PUT")] public class UpdateCustomer : IReturn { public int Id { get; set; } public ssortingng Name { get; set; } } [Route("/customers/{Id}", "DELETE")] public class DeleteCustomer : IReturnVoid { public int Id { get; set; } } 

Modèle OrmLite POCO:

 public class Customer { [AutoIncrement] public int Id { get; set; } public ssortingng Name { get; set; } } 

Essentiellement, les itinéraires personnalisés identifient la ressource, tandis que HTTP VERB indique l’opération sur cette ressource. En regardant les requêtes HTTP, cela est un peu plus clair:

 GET /customers -> return all Customers POST /customers -> Create a new Customer GET /customers/1 -> return Customer 1 PUT /customers/1 -> Update Customer 1 DELETE /customers/1 -> Delete Customer 1 

Mise en place du service client

Avec les définitions du DTO ci-dessus en place, nous pouvons maintenant mettre en œuvre ce service REST client en ajoutant une implémentation pour chaque DTO de demande – dans cet exemple, en utilisant OrmLite :

 public class CustomerService : Service { public object Get(GetCustomers request) { return new GetCustomersResponse { Results = Db.Select() }; } public object Get(GetCustomer request) { return Db.SingleById(request.Id); } public object Post(CreateCustomer request) { var customer = new Customer { Name = request.Name }; Db.Save(customer); return customer; } public object Put(UpdateCustomer request) { var customer = Db.SingleById(request.Id); if (customer == null) throw HttpError.NotFound("Customer '{0}' does not exist".Fmt(request.Id)); customer.Name = request.Name; Db.Update(customer); return customer; } public void Delete(DeleteCustomer request) { Db.DeleteById(request.Id); } } 

Exemple d’utilisation du client

Avec l’implémentation du service REST client ci-dessus, nous pouvons réutiliser le DTO de demande avec les clients du service .NET de ServiceStack pour fournir une API typée de bout en bout sans code-gen, c’est-à-dire:

 var client = new JsonServiceClient(BaseUri); //GET /customers var all = client.Get(new GetCustomers()); // Count = 0 //POST /customers var customer = client.Post(new CreateCustomer { Name = "Foo" }); //GET /customer/1 customer = client.Get(new GetCustomer { Id = customer.Id }); // Name = Foo //GET /customers all = client.Get(new GetCustomers()); // Count = 1 //PUT /customers/1 customer = client.Put( new UpdateCustomer { Id = customer.Id, Name = "Bar" }); // Name = Bar //DELETE /customers/1 client.Delete(new DeleteCustomer { Id = customer.Id }); //GET /customers all = client.Get(new GetCustomers()); // Count = 0 

Les commentaires ci-dessus incluent les opérations HTTP effectuées dans chaque exemple de service client.

J’ai trouvé le correctif pour ma deuxième question en suivant les deux liens suivants: 1. Link1 2. Link2

Je ne comprends pas bien ce correctif, mais les modifications ci-dessus ont fonctionné pour moi et je peux maintenant appeler la fonction de suppression à partir de tous les clients.

Pour la 1ère question, veuillez vous reporter en détail à la réponse de @mythz ci-dessous.