40

私は、Microsoft Technologies で Web アプリケーションを開発するために使用される .Net 開発者です。Web サービスの REST アプローチを理解するために自分自身を教育しようとしています。これまでのところ、私は ServiceStack フレームワークが大好きです。

しかし、WCF で慣れ親しんだ方法でサービスを作成することがあります。だから私は私を悩ませている質問があります。

私は2つのリクエストDTOを持っているので、次のような2つのサービスがあります:

[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; }
}

これらのリクエスト DTO に見られるように、ほぼすべてのサービスに対して同様のリクエスト DTO があり、これは DRY ではないようです。

サービスでエラーが発生した場合に備えて、内部のクラスが重複しているため、内部GetBookingLimitResponseのリストでクラスを使用しようとしました。GetBookingLimitsResponseResponseStatusGetBookingLimitResponseGetBookingLimits

また、次のようなこれらのリクエストのサービス実装があります。

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()
        };
    }
}

ご覧のとおり、ここでも検証機能を使用したいので、すべてのリクエスト DTO に対して検証クラスを作成する必要があります。そのため、類似サービスを 1 つのサービスにグループ化して、サービス数を低く抑える必要があると感じています。

しかし、ここで私の頭に浮かんだ質問は、その要求に対してクライアントが必要とするよりも多くの情報を送信する必要があるかということです。

WCFの人間のように考えて書いた現在のコードに満足していないので、考え方を変えるべきだと思います。

誰かが従うべき正しい方向を教えてくれますか.

4

2 に答える 2

10

ResponseStatus プロパティが不要になったため、「Reponse Dtos」は不要のようです。. ただし、SOAP を使用する場合は、対応する Response クラスが必要になる可能性があると思います。Response Dtos を削除すると、BookLimit を Response オブジェクトに押し込む必要がなくなります。また、ServiceStack の TranslateTo() も役立ちます。

以下は、あなたが投稿したものを単純化しようとする方法です... YMMV.

BookingLimit の DTO を作成する - これは、他のすべてのシステムに対する BookingLimit の表現になります。

public class BookingLimitDto
{
    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; }
}

リクエストと Dtos は非常に重要です

[Route("/bookinglimit", "GET")]
[Authenticate]
public class GetBookingLimit : IReturn<BookingLimitDto>
{
    public int Id { get; set; }
}

[Route("/bookinglimits", "GET")]
[Authenticate]
public class GetBookingLimits : IReturn<List<BookingLimitDto>>
{
    public DateTime Date { get; set; }
}

Reponse オブジェクトを返さなくなりました... BookingLimitDto だけです

public class BookingLimitService : AppServiceBase 
{ 
    public IValidator AddBookingLimitValidator { get; set; }

    public BookingLimitDto Get(GetBookingLimit request)
    {
        BookingLimitDto bookingLimit = new BookingLimitRepository().Get(request.Id);
        //May need to bookingLimit.TranslateTo<BookingLimitDto>() if BookingLimitRepository can't return BookingLimitDto

        return bookingLimit; 
    }

    public List<BookingLimitDto> Get(GetBookingLimits request)
    {
        List<BookingLimitDto> bookingLimits = new BookingLimitRepository().GetByRestaurantId(base.UserSession.RestaurantId);
        return
            bookingLimits.Where(
                l =>
                l.EndDate.ToShortDateString() == request.Date.ToShortDateString() &&
                l.StartDate.ToShortDateString() == request.Date.ToShortDateString()).ToList();
    }
} 
于 2013-04-11T04:49:13.280 に答える