Nel mio progetto web api 2, se voglio usare la libreria OData (che sembra impressionante e molto allettante) per le interrogazioni su alcune proprietà, questo costringerebbe il lato client a conoscere le proprietà esatte dei miei modelli di database. È una buona pratica? C'è un modo per evitare questo disaccoppiamento?Query con OData senza esporre i modelli ORM?
Per i seguenti modelli:
public class LetterEntity
{
public int Id {get; set;}
public string Title {get; set;}
public string Content {get; set;}
public string Source {get; set;}
public DateTime SendingTime {get; set;}
public string AnotherWierdString {get; set;
...
}
public class LetterDTO
{
public int Id {get; set;}
public string Title {get; set;}
public string LetterContent {get; set;}
public string Source {get; set;}
public DateTime SendingTime {get; set;}
}
public class LetterInsideFolderDTO
{
public string Title {get; set;}
public string Source {get; set;}
}
public class LettersController : ApiController
{
// In this approach method, I hate the fact that a LetterEntity must be used for the query.
[HttpGet]
[Route("api/letters")]
[EnableQuery]
public IQueryable<LetterInsideFolderDTO> Get(ODataQueryOptions<LetterEntity> query)
{
IQueryable<Letter> letters = db.Letters;
var afterQuery = query.ApplyTo(letters)
IQueryable<LetterInsideFolderDTO> dtos = afterQuery.ProjectTo<LetterInsideFolderDTO>(afterQuery)
return dtos;
}
// Is there a way to do something like the following?:
[HttpGet]
[Route("api/letters")]
[EnableQuery]
public IQueryable<LetterInsideFolderDTO> Get(ODataQueryOptions<LetterDTO> query)
{
IQueryable<Letter> letters = db.Letters;
// Convert the query to work on the entities somehow? Should I use a mapping between LetterDTO to LetterEntity?
// I only have a map from LetterEntity to LetterDTO
var afterQuery = query.ApplyTo(letters)
IQueryable<LetterInsideFolderDTO> dtos = afterQuery.ProjectTo<LetterInsideFolderDTO>(afterQuery)
return dtos;
}
}
A causa del fatto che in questo momento prendo modello Entità direttamente nella query clienti, v'è una forte accoppiamento tra client e server. Per esempio se voglio interrogare ed ottenere tutte le lettere che ha "abc" all'interno del campo Content
, ho bisogno di rotta verso il seguente:
api/letters/?$filter=contains(Content,'abc')
Se domani decido di cambiare la proprietà da "Contenuto" a "LetterContent" il codice di tutti i client sarà rotto.
Come posso superarlo?
Grazie!
EDIT:
Vi prego di fare un esempio concreto, non capisco ancora cosa hateoas sono (se questo aiuta a risolvere questo problema), Come può servizio di documentazione di aiuto a me? Impegnerà comunque i clienti a cambiare il loro codice se deciderò di cambiare i miei modelli EDM?
Un altro modo è non usare ODATA :), perché ODATA, il client deve conoscere EdmModel (schema ODATA) prima di fare query :) –
Basta esporre il DTO che sarebbe essenzialmente un ResourceModel. Vedere https://spring.io/understanding/HATEOAS –
@CuongLe esiste un'altra alternativa per molte query diverse? Non voglio un'azione diversa per ogni query sul mio server –