ServiceStack Demande DTO design
Je suis un .Net développeur a utilisé pour développer des applications web sur les Technologies Microsoft. Je suis en train de me renseigner pour comprendre le RESTE de l'approche pour les services web. Jusqu'à présent, je suis amoureuse de la ServiceStack cadre.
Mais parfois, je me retrouve à écrire des services dans un mode que je suis habitué avec WCF.
J'ai donc une question qui me chiffonne.
J'ai 2 demande DTO est donc 2 services tels que:
[Route("/bookinglimit", "GET")]
[Authenticate]
public class GetBookingLimit : IReturn<GetBookingLimitResponse>
{
public int Id { get; set; }
}
public class GetBookingLimitResponse
{
public int Id { get; set; }
public int ShiftId { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int Limit { get; set; }
public ResponseStatus ResponseStatus { get; set; }
}
[Route("/bookinglimits", "GET")]
[Authenticate]
public class GetBookingLimits : IReturn<GetBookingLimitsResponse>
{
public DateTime Date { get; set; }
}
public class GetBookingLimitsResponse
{
public List<GetBookingLimitResponse> BookingLimits { get; set; }
public ResponseStatus ResponseStatus { get; set; }
}
Comme on le voit sur ces Demande DTO j'ai demande similaire DTO près de tous les services et cela semble ne pas SÉCHER.
J'ai essayé d'utiliser GetBookingLimitResponse
classe dans une liste à l'intérieur de GetBookingLimitsResponse
pour cette raison ResponseStatus
à l'intérieur de GetBookingLimitResponse
classe est dublicated dans le cas où j'ai une erreur sur GetBookingLimits
service.
Aussi j'ai des implémentations de services pour ces demandes comme :
public class BookingLimitService : AppServiceBase
{
public IValidator<AddBookingLimit> AddBookingLimitValidator { get; set; }
public GetBookingLimitResponse Get(GetBookingLimit request)
{
BookingLimit bookingLimit = new BookingLimitRepository().Get(request.Id);
return new GetBookingLimitResponse
{
Id = bookingLimit.Id,
ShiftId = bookingLimit.ShiftId,
Limit = bookingLimit.Limit,
StartDate = bookingLimit.StartDate,
EndDate = bookingLimit.EndDate,
};
}
public GetBookingLimitsResponse Get(GetBookingLimits request)
{
List<BookingLimit> bookingLimits = new BookingLimitRepository().GetByRestaurantId(base.UserSession.RestaurantId);
List<GetBookingLimitResponse> listResponse = new List<GetBookingLimitResponse>();
foreach (BookingLimit bookingLimit in bookingLimits)
{
listResponse.Add(new GetBookingLimitResponse
{
Id = bookingLimit.Id,
ShiftId = bookingLimit.ShiftId,
Limit = bookingLimit.Limit,
StartDate = bookingLimit.StartDate,
EndDate = bookingLimit.EndDate
});
}
return new GetBookingLimitsResponse
{
BookingLimits = listResponse.Where(l => l.EndDate.ToShortDateString() == request.Date.ToShortDateString() && l.StartDate.ToShortDateString() == request.Date.ToShortDateString()).ToList()
};
}
}
Comme vous le voyez je tiens également à utiliser la Fonctionnalité de Validation ici, donc je dois écrire des classes de validation pour chaque demande DTO j'ai. Donc, j'ai un sentiment que je devrais garder mon numéro de service à la basse par le regroupement des services similaires en un seul service.
Mais la question est ici que surgit dans mon esprit que dois-je envoyer plus d'informations que le client en a besoin pour la demande ?
Je pense que ma façon de penser doit changer parce que je ne suis pas heureux avec code actuel qui j'ai écrit à penser comme un WCF gars.
Quelqu'un peut me montrer la direction à suivre.
Vous devez vous connecter pour publier un commentaire.
Pour vous donner une idée des différences que vous devez penser lors de la conception de services de messagerie en ServiceStack je vais vous donner quelques exemples de comparer WCF/WebApi vs ServiceStack son approche:
WCF vs ServiceStack Conception d'API
WCF vous encourage à penser à des services web comme normal C# appels de méthode, de l'e.g:
C'est ce que le même contrat de Service pourrait ressembler dans ServiceStack avec le Nouvelle API:
Le concept le plus important à garder à l'esprit est que l'intégralité de la requête (aka Demande) est capturé dans le Message de Demande (c'est à dire Demande DTO) et non dans le serveur de signatures de méthode. L'évidence immédiate de l'adoption d'un message à base de modèle est que toute combinaison de ce qui précède appels RPC peuvent être atteints dans le 1 messages à distance, par un seul service de la mise en œuvre.
WebApi vs ServiceStack Conception d'API
De même WebApi favorise une similaire en C#comme Api RPC qui WCF:
ServiceStack Message API Basée sur la Conception
Tandis que ServiceStack vous encourage à conserver un Message de Conception basée sur:
De nouveau capturer l'essence de la Demande dans la Demande de DTO. Le message de base de la conception est également capable de se condenser 5 RPC distinctes WebAPI services en 2 basé sur le message ServiceStack ceux.
Groupe par l'Appel de la Sémantique et des Types de Réponse
C'est regroupées dans 2 services différents dans cet exemple basé sur Appel à la Sémantique et Types de Réponse:
Tous les biens de chaque Demande DTO a la même sémantique que c'est pour
FindProducts
chaque propriété agit comme un Filtre (par exemple, une ET, tandis queGetProduct
il agit comme un combinateur (par exemple, un OU). Les Services de retourIEnumerable<Product>
etProduct
types de retour, qui nécessitera un traitement différent dans l'appel-sites de Tapé dans l'Api.Dans WCF /WebAPI (et d'autres services RPC cadres) chaque fois que vous avez un client spécifique à condition que vous ajoutez un nouveau Serveur de signature sur le contrôleur qui correspond à cette demande. Dans ServiceStack message de l'approche fondée sur les cependant, vous devriez toujours penser à où cette fonction appartient et que vous êtes en mesure d'améliorer les services existants. Vous devez également penser à comment vous pouvez soutenir le client exigence spécifique dans un façon générique de sorte que le même service peut bénéficier à d'autres potentiels futurs cas d'utilisation.
Re-factoring GetBooking Limites des services de
Avec les informations ci-dessus, nous pouvons commencer à re-factoring vos services. Puisque vous avez 2 services différents qui renvoient à des résultats différents par exemple
GetBookingLimit
retourne 1 point etGetBookingLimits
retourne nombreux, ils doivent être conservés dans des services différents.Distinguer les Opérations de Service vs Types
Vous devez cependant avoir une séparation nette entre vos Opérations de Service (par exemple la Requête DTO) qui est unique pour chaque service, et est utilisé pour capturer les Services à la demande, et la DTO types de retour. Demande Otd sont généralement des actions, de sorte qu'ils sont des verbes, tandis que les DTO sont les types d'entités de données/-les contenants de sorte qu'ils sont des noms.
Retour générique réponses
Dans la Nouvelle API, ServiceStack réponses plus besoin d'un ResponseStatus bien depuis si ça n'existe pas le générique
ErrorResponse
DTO seront jetés et sérialisé sur le client à la place. Cela vous permet d'avoir vos Réponses contiennentResponseStatus
propriétés. Cela dit je re-facteur du contrat de vos nouveaux services pour:Pour les requêtes GET, j'ai tendance à les laisser sortir de la définition de la Route quand ils ne sont pas ambiguë, car c'est moins de code.
Garder un uniforme de la Nomenclature
Vous conseillons de réserver le mot Obtenir sur les services de requête sur unique ou de Clés Primaires des champs, c'est à dire quand une valeur donnée correspond à un domaine (par exemple, Id) il ne Obtient 1 résultat. Pour les services de recherche qui agit comme un filtre et renvoie plusieurs résultats correspondant qui tombe à l'intérieur d'une plage, j'utilise soit le Trouver ou de Recherche verbes pour indiquer que c'est le cas.
Objectif pour l'auto-description de Contrats de Service
Aussi essayer d'être descriptive avec chacun de vos noms de champ, ces propriétés font partie de votre API publique et devrait être auto-descriptif de ce qu'il fait. E. g. Juste en regardant le Contrat de Service (par exemple la Requête DTO) nous n'avons aucune idée de ce que Date n', j'ai supposé BookedAfter, mais il pourrait aussi avoir été BookedBefore ou BookedOn si elle ne retourne que les réservations effectuées à ce Jour.
L'avantage de ce qui est maintenant l'appel-les sites de votre tapé .NET clients devenir plus facile à lire:
Service de la mise en œuvre
J'ai enlevé le
[Authenticate]
attribut de votre Demande Otd depuis la place, vous pouvez simplement spécifier qu'une fois le Service de la mise en œuvre, qui ressemble aujourd'hui:Gestion des erreurs et de Validation
De l'info sur comment ajouter de validation vous avez l'option de juste jetez C# exceptions et appliquer vos propres personnalisations pour eux, sinon vous avez la possibilité d'utiliser le haut- Couramment Validation mais vous n'avez pas besoin de les injecter dans votre service comme vous pouvez le fil avec une seule ligne dans votre AppHost, e.g:
Validateurs sont no-touch et envahissantes libre ce qui signifie que vous pouvez les ajouter à l'aide d'une approche à plusieurs niveaux et de les maintenir sans modification de la mise en œuvre des services ou de la DTO des classes. Depuis il a besoin d'une classe supplémentaire, je voudrais les utiliser uniquement sur les opérations avec des effets secondaires (par exemple POST/PUT) que Se " ont tendance à avoir peu de validation et en jetant un C# Exception nécessite moins de la chaudière de la plaque. Donc un exemple d'un programme de validation, vous pourriez avoir est lors de la première création d'une réservation:
Selon les cas d'utilisation au lieu d'avoir un
CreateBooking
etUpdateBooking
Otd je re-utiliser la même Demande DTO pour les deux, auquel cas j'aurais nomStoreBooking
.5) How to design a Message-Based API
dans le commencer l'article de la wiki.La "Reponse Otd" semblent inutiles puisque ResponseStatus propriété est n'est plus nécessaire.. Cependant, je pense que vous pouvez toujours besoin d'une correspondance de classe de Réponse si vous utilisez du SAVON. Si vous supprimez la Réponse Otd vous n'avez plus besoin de pousser BookLimit en Réponse objets. Aussi, ServiceStack de TranslateTo() pourrait aider.
Ci-dessous est la façon dont je voudrais essayer de simplifier ce que vous avez posté...YMMV.
Faire un DTO pour BookingLimit - Ce sera la représentation de BookingLimit à tous les autres systèmes.
Les demandes et les Dto sont très important
N'est plus de retour Reponse objets...juste le BookingLimitDto