I am keen on using ServiceStack and have created a little test app with a simple customer service:
[Route("/customers/{id}")]
public class GetCustomer : IReturn<Customer>
{
public int Id { get; set; }
}
[Route("/customers/search")]
public class FindCustomers : IReturn<List<Customer>>
{
public string LastName { get; set; }
public int Age { get; set; }
public string? City { get; set; }
}
public class CustomerService : IService
{
public object Get(GetCustomer request)
{
var db = new WebServDb();
var customer = db.FirstOrDefault<Customer>("WHERE Id=@0", request.Id);
return customer;
}
public object Get(FindCustomers request)
{
var db = new WebServDb();
var customers = new List<Customer>();
if (request.City.HasValue)
customers = db.Fetch<Customer>("WHERE LastName=@0 AND Age=@1 AND City=@2", request.LastName, request.Age, request.City);
else
customers = db.Fetch<Customer>("WHERE LastName=@0 AND Age=@1", request.LastName, request.Age);
return customers;
}
}
The FindCustomers request DTO contains 3 properties that can be used to search for customers. Based on which properties are set I need to query the DB differently. So what is the best way to do this? For example, if I add another property such as:
[Route("/customers/search")]
public class FindCustomers : IReturn<List<Customer>>
{
public string LastName { get; set; }
public int Age { get; set; }
public string? City { get; set; }
public string? ZipCode { get; set; }
}
to the FindCustomers DTO, I would also have to change the service Get method to:
public object Get(FindCustomers request)
{
var db = new WebServDb();
var customers = new List<Customer>();
if (request.City.HasValue && request.ZipCode.HasValue)
customers = db.Fetch<Customer>("WHERE LastName=@0 AND Age=@1 AND City=@2 AND ZipCode=@3", request.LastName, request.Age, request.City, request.ZipCode);
else if (request.City.HasValue)
customers = db.Fetch<Customer>("WHERE LastName=@0 AND Age=@1 AND City=@2", request.LastName, request.Age, request.City);
else
customers = db.Fetch<Customer>("WHERE LastName=@0 AND Age=@1", request.LastName, request.Age);
return customers;
}
So for each property I add/remove from the request DTO I need to modify my Get method. Is there better way do this? A more generic way to check for properties set and querying the DB?
Would it be better to have specific request DTOs such as FindCustomersByLastNameCity, FindCustomersByLastNameZipCode, etc. as well as corresponding specific Get methods in the CustomerService?