Progettazione di un'API per operazioni di servizio con parametri strettamente correlati

1

Ho difficoltà a decidere come progettare questa API di servizio.

public class GetCurrentValuesRequest
{
    public int ReferenceID { get; set; }
    public int[] FilterIDs { get; set; }
}

public class GetDefaultValuesRequest
{
    public int[] FilterIDs { get; set; }
}

public class GetValuesAsOfDateRequest
{
    public int ReferenceID { get; set; }
    public int[] FilterIDs { get; set; }
    public DateTime AsOf { get; set; }
}

public class GetValuesAsOfChangeSetRequest
{
    public int ReferenceID { get; set; }
    public int[] FilterIDs { get; set; }
    public long ChangeSetIDs { get; set; }
}

public class GetProposedValuesRequest
{
    public int ReferenceID { get; set; }
    public int[] FilterIDs { get; set; }
    public long ApprovalKey { get; set; }
}

public class GetValuesIfModifiedRequest
{
    public int ReferenceID { get; set; }
    public int[] FilterIDs { get; set; }
    public DateTime Since { get; set; }
}

public class GetValuesResponse
{
    public string[] Results { get; set; }
}

public class GetValuesIfModifiedResponse
{
    public string[] Results { get; set; }
    public bool IsModified { get; set; }
}

public interface IService
{
    GetValuesResponse GetValues(GetCurrentValuesRequest request);

    GetValuesResponse GetValues(GetDefaultValuesRequest request);

    GetValuesResponse GetValues(GetValuesAsOfDateRequest request);

    GetValuesResponse GetValues(GetValuesAsOfChangeSetRequest request);

    GetValuesResponse GetValues(GetProposedValuesRequest request);

    GetValuesIfModifiedResponse GetValuesIfModified(GetValuesIfModifiedRequest request);
}

Ho pensato di modificarlo per rendere le sottoclassi di richiesta / risposta IfModified della semplice risposta di richiesta GetValues e includendo solo una chiamata GetValues . Il server restituirebbe una risposta diversa a seconda della richiesta di input, ma che richiede all'utente di chiamare IService this:

var response = (GetValuesIfModifiedResponse)serviceClient.GetValues(new GetValuesIfModifiedRequest() { ... });

Ho anche pensato di posizionare IsModified nel GetValuesResponse semplice e di popolarlo solo se viene passato un GetValuesIfModifiedRequest . Ma sembra un po 'strano includerlo in un risultato di un metodo che in realtà non fa nulla con esso. Inoltre, potrebbe lanciare un utente se lo vede e si aspetta di poterlo usare nel proprio codice. bool? IsModified è migliore, ma non sono ancora interamente venduto su di esso.

Qualche suggerimento su come progettare al meglio questa API?

    
posta p.s.w.g 19.03.2013 - 20:40
fonte

2 risposte

1

Secondo me, il tuo unico oggetto di richiesta dovrebbe essere simile a questo:

public class GetValuesRequest
{
    public int[] FilterIDs { get; set; }
    public DateTime SearchDate { get; set; }
    public SearchType SearchType { get; set; }
}

public enum SearchType
{
    AsOf,
    Since
}

Puoi modificare questo a tuo gusto, ma il punto è che è stata presentata una sola data di ricerca e l'enumerazione fornisce un meccanismo di commutazione tra passato e futuro.

Puoi quindi restituire un oggetto in questo modo:

public class GetValuesResponse
{
    public string[] Results { get; set; }
    public CacheState CacheResult { get; set; }
}

public enum CacheState
{
    Modified,
    Unmodified,
    NotChecked
}
    
risposta data 19.03.2013 - 22:07
fonte
1

Sembra che tu stia cercando di creare una query dinamica su http. Hai guardato OData? Dato che stai usando WCF, c'è un supporto integrato a partire da 4.0, credo per l'implementazione di OData chiamato Dati WCF Servizi , tutto ciò che devi fare è restituire IQueryable dai tuoi metodi di servizio. Per comodità, è possibile creare query di supporto nella libreria client che avvolge le query OData. Quindi la tua interfaccia di servizio sarebbe ora come

public interface IService
{
    IQueryable<Values> GetValues();
}

E la tua libreria client dovrebbe contenere funzioni di aiuto che chiamano il servizio.

public class ServiceClient
{
   //Injected or initialized see docs under previous link on accessing a service
   private IService _service
   public IEnumerable<Values>GetFilteredValues(int[] filterIds)
   {
      //get the values matching passed in Ids.
      return from _service.GetValues().Where(v => filterIds.Contains(v.Id));
   }

   public IEnumerable<Values>GetFilteredValuesAsOf(int[] filterIds, DateTime asOf)
   {
      //get the values matching passed in Ids and created since the asOf date
      return from _service.GetValues().
             Where(v => filterIds.Contains(v.Id) && v.CreatedOn > asOf);
   }

}

La bellezza di questo è che la query avviene lato server. Se è supportato da un Database, il database lo gestisce.

    
risposta data 19.03.2013 - 22:22
fonte

Leggi altre domande sui tag