Using DTO vs Serializating entities - json

I have already read this thread before asking the question, but this is a pretty old thread and lots of new ways for de serializing the entities are there now.
My first question is why we should not use the Entities in the Controller ? If the only reason is waste data travelling across the wire then it should not be an issue because there are ways to avoid this.
I am using flexjson.JSONSerializer for de serializing the entity and Gson.fromJSON() for serializing the json into entity instead of using DTO. My controller code looks like this..
#RequestMapping (value = "", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public void createStream(#RequestBody String streamData) {
StreamEntity streamEntity = null;
try {
streamEntity = streamService.createStream(streamData);
logger.info("Created Stream [id=%s, name=%s]", streamEntity.getId(), streamEntity.getStreamName());
} catch (Exception e) {
logger.info("Error occured while creating the stream[name=%s]: %s",streamEntity.getStreamName(), e.getMessage());
}
}
#RequestMapping (value = "/{id}", method = RequestMethod.GET)
public String fetchStream(#PathVariable(value = "id")final Long id) {
StreamEntity streamEntity = streamDAO.getById(id);
String json = StreamEntitySerializer.serialize(streamEntity);
return json;
}
Only purpose of using the entity in controller is for logging. Is there anything wrong/objectionable with the code ?

I think you have two questions....
Question 1: Why not expose the entity to the controller (aka Presentation Layer):
For large/complex project its bad form to use the Entity in the controller because it leads to business logic getting spread around your project. Once you pass the entity to your Presentation layer (aka Controllers), any controller can modify and save the data. Typically multiple controllers will need access to the same entities. This leads to code maintenance hell, because now you have to maintain your data CURD, anti-corruption and business logic in multiple places. Moving all your Business logic, the logic that manipulates the data, to a common package (aka Domain\Service Layer) makes maintaining the code much easier long term. By passing DTOs up the stack to the controllers, you'll end up with much cleaner code, that is much easier to test. Here is a good presentation about layered architectures : https://www.youtube.com/watch?v=aZp7C971uC8
Other reading:
http://www.dotnetcurry.com/showarticle.aspx?ID=786
http://www.methodsandtools.com/archive/archive.php?id=97
Question 2 Why not serialize the entity vs. converting it to a DTO and serializing that.
There are a ton of reasons not to do this, but here are the frist ones that come to mind.
Maintenance : By exposing your entities directly, your creating a hard link between how data is stored and the data objects your clients get. For example, what happens when you need to rename/delete a field in your entity. What happens when you change your database? Switching between MySQL and Mongodb gets a lot easier if the entities are getting converted to a DTO.
Testing : its much easier to mock a DTO instance than a Hibernate instance
Performance : Serializing an Entity can trigger all the lazy load fields to be pulled from that database, even if you don't need to expose that data. This can make tracking down performance issues hard. DTOs causes you to be explicit about which fields are transformed and serialized. Also since DTOs are normally smaller and simpler, which makes serialization faster.

Related

How to model a JSON with pair meta/result

I'm implementing multiple REST client wrappers (Java, C#, Objective-C and Python) for a REST service for which I don't have the source code access. In all of them I'm having problems with the modeling, so of course you can assume my flaw is in the OOP, not on the language syntax or smth. I wondered maybe someone could help me fixing this flaw or finding out if the REST service is the problem, and hopefully this topic can help others improving their OOP modeling.
The WebService will always return a JSON with the following structure:
{
"meta": {
"code": 200,
"message": "OK"
},
"result": [
{
...
},
{
...
},
...
]
}
}
The problem is: "meta" will always have the same model and the "result" will always be a list of objects, but these objects change depending on the Endpoint we access. So I have multiple classes, each for one Endpoint, and result will always end up being a list of one of these classes. So I thought of multiple ways of solving it, none of them I really liked. Any other alternatives besides the following methods? Thanks.
Method 1
Meta class with code and message fields, ServiceResponse class with meta field and result field as JSONData
Each specific class having a constructor with JSONData as parameter, which is parsed on create.
Problem
JSONData is not encapsulated as it has to be handled all the time, and the performance is bad because of parsing the same JSONData multiple times, since ServiceResponse doesn't hold the parsed objects.
Method 2
Making one ModelResponse for each different class I have. E.g. ProductsResponse with meta and a list of products, VenuesResponse with a meta and a list of products, etc.
Problem
Poor code reuse.
OK, after explaining the question here and thinking for a couple of hours about it, making PoCs and so on I came to what I think is a good efficient modeling.
I basically chose Method 2 and fixed the "poor code reuse" problem, by doing the following. I'll use a pseudo-language to be as general as possible so that anyone with knowledge in Object-Oriented Programming will understand:
abstract class ServiceResponse:
int code
string message
JsonReader _reader
void parseMeta():
_reader.beginObject()
...
_reader.endObject()
abstract void parseResult() // will be implemented by child classes
public ServiceResponse(JsonReader reader):
_reader = reader
_reader.beginObject()
...
parseMeta()
...
parseResult()
...
_reader.endObject()
Then for each kind of response I create a class that inherits from ServiceResponse, such as:
class ProductsResponse extends ServiceResponse:
List<Products> products
public ProductsResponse(JsonReader reader):
parent(reader)
override void parseResult():
_reader.beginArray();
...
_reader.endArray();
And then I have a ServiceEndpoints class which has one method for each endpoint. Through the WS documentation I know which endpoint will return which type of response, so I can instantiate the right class (ProductsResponse, VenuesResponse, etc) and return the right type of list.

Using RIO and Sqlite-net in MvvmCross

In the excellent mvvmcross-library I can use RIO binding to prevent unreadable code:
public INC<String>Title = new NC<String>();
Then I can read and write values using Title.Value. Makes the models much more readable.
Normally, this property would be written as:
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
RaisePropertyChanged("Title");
}
}
But when I want to use sqlite-net, these fields cannot be streamed to the database because they are not basic types with a getter and setter.
I can think of a few options how to get around that:
Make a new simple object that is similar to the model, but only with
the direct db-fields. And create a simple import-export static
method on the model. This also could prevent struggling with complex
model-code that never needs to relate to the actual database.
Make sqlite-net understand reading NC-fields. I read into the code of the mapper, but it looks like this is going to be a lot of work because it relies on the getter-setter. I did not find a way to insert custom mapping to a type, that could be generic.
Remove RIO and just put in all the code myself instead of relying on RIO.
Maybe someone has some advice?
Thanks Stuart. It was exactly my thought, so I did implement it that way: my (DB) Models do not contain RIO. Only my viewmodels do, and they reference a Model that is DB-compatible.
So, for posterity the following tips:
- Do not use RIO in your models that need to be database-backed.
- Reference models in your viewmodels. In the binding you can use the . (dot) to reference this model.
This keeps them nicely separated. This gives you also another advantage: if you need to reuse a model (because the same object might be displayed twice on the screen), but under different circumstances, it is much easier to handle this situaties to find this already instantiated model.

Separating data from the UI code with Linq to SQL entities

If it's important to keep data access 'away' from business and presentation layers, what alternatives or approaches can I take so that my LINQ to SQL entities can stay in the data access layer?
So far I seem to be simply duplicating the classes produced by sqlmetal, and passing those object around instead simply to keep the two layers appart.
For example, I have a table in my DB called Books. If a user is creating a new book via the UI, the Book class generated by sqlmetal seems like a perfect fit although I'm tightly coupling my design by doing so.
What I do is to have all my DataAccess (LINQ-to-SQL in your case) in one project and then I have another business project which uses the DataAccess project, thereby segrating the DataAccess project form the UI layer.
In your example for books, my business layer would have a class called Book:
public class Book
{
private IAuthorRespository _authorRepository = new LinqToSqlAuthorRepository();
private IBookRespository _bookRepository = new LinqToSqlBookRepository();
public int BookId { get { return _bookId; }}
private int _bookId;
public virtual string BookName{get;set;}
public virtual string ISBN {get;set;}
// ...Other properties
public Book()
{
// When creating a new book
_bookId = 0;
}
public Book(int id)
{
// For an existing book
_bookId = id;
Load();
}
protected void Load()
{
BookEntity book = _bookRepository.GetBook(BookId);
BookName = book.BookName;
ISBN = book.ISBN;
}
public void Save()
{
BookEntity book = MapEntityFromThisClass();
_bookRepository.Save(book);
}
public Author GetAuthor()
{
return _authorRepository.GetAuthor();
}
}
This then means that your UI is totally separated from the actual data access and that all of your Book logic is contained sensibly within a class.
You can make this further separated by using IoC with a system such as Microsoft Unity or Castle so that you don't have to write = new LinqToSqlXYZ(); and can instead write something along the lines of IoC.Resolve<IBookRepostory>(); (depending on your implementation). This then means your Book class is not tied down to LINQ-to-SQL anymore either.
Linq to Sql offers a 1:1 mapping between entities and your database tables. It could be argued that the entities themselves are a level of abstraction away from the database, and that is what you are tied down to.
If you are making a 1:1 duplication of the entities offered up by linq to sql, then it may mean that its not worth having them there, because you are still just as tied to those classes as you are to the entities offered by linq to sql.
By creating another layer, you are also elminating the benefits of change tracking provided by linq to sql, meaning you have to copy any changes from your classes into the entities provided by linq to sql to perform data operations.
If you would like to abstract away the DataContext type code from any presentation or business layers, and control the interface to your data more tightly, then the repository pattern is good. You can always have your repository return the entity types created by linq to sql, which means you are not duplicating types, you also get change tracking, but you are still keeping the code that controls the DataContext inside the repository.
You may consider projecting the data into a different class for the benefit of your presentation (a view model), or business logic. This is the route I tend to go down, if I want to use linq to sql, but I don't want a 1:1 mapping between the entities and my view models.

Should repositories expose IQueryable to service layer or perform filtering in the implementation?

I'm trying to decide on the best pattern for data access in my MVC application.
Currently, having followed the MVC storefront series, I am using repositories, exposing IQueryable to a service layer, which then applies filters. Initially I have been using LINQtoSQL e.g.
public interface IMyRepository
{
IQueryable<MyClass> GetAll();
}
Implemented in:
public class LINQtoSQLRepository : IMyRepository
{
public IQueryable<MyClass> GetAll()
{
return from table in dbContext.table
select new MyClass
{
Field1 = table.field1,
... etc.
}
}
}
Filter for IDs:
public static class TableFilters
{
public static MyClass WithID(this IQueryable<MyClass> qry, string id)
{
return (from t in qry
where t.ID == id
select t).SingleOrDefault();
}
}
Called from service:
public class TableService
{
public MyClass RecordsByID(string id)
{
return _repository.GetAll()
.WithID(id);
}
}
I ran into a problem when I experimented with implementing the repository using Entity Framework with LINQ to Entities. The filters class in my project contains some more complex operations than the "WHERE ... == ..." in the example above, which I believe require different implementations depending on the LINQ provider. Specifically I have a requirement to perform a SQL "WHERE ... IN ..." clause. I am able to implement this in the filter class using:
string[] aParams = // array of IDs
qry = qry.Where(t => aParams.Contains(t.ID));
However, in order to perform this against Entity Framework, I need to provide a solution such as the BuildContainsExpression which is tied to the Entity Framework. This means I have to have 2 different implementations of this particular filter, depending on the underlying provider.
I'd appreciate any advice on how I should proceed from here.
It seemed to me that exposing an IQueryable from my repository, would allow me to perform filters on it regardless of the underlying provider, enabling me to switch between providers if and when required. However the problem I describe above makes me think I should be performing all my filtering within the repositories and returning IEnumerable, IList or single classes.
Many thanks,
Matt
This is a very popular question. One that I constantly ask myself. I've always felt it best to return IEnumerable rather than IQueryable from a repository.
The purpose of a repository is to encapsulate the database infrastructure so the client need not worry about the data source. However, if you return IQueryable you are at the mercy of the consumer as to what kind of query will get run against your db, and whether they will do something that the LINQ provider doesn't support.
Take paging for example. Lets say you have a Customer entity and your database could have hundreds of thousands of customers. Which code would you rather have your client write?
var customers = repos.GetCustomers().Skip(skipCount).Take(pageSize).ToList();
OR
var customers = repos.GetCustomers(pageIndex, pageSize);
In the first approach you make it impossible for the repository to restrict the number of records retrieved from the data source. Also, your consumer has to calculate the skipCount.
In the second approach you provide a more coarse grained interface to your client. Now your repository can enforce some constraints on the pageSize in order to optimize the query. You also encapsulate the calculation of the skipCount.
However, that being said, in your situation your client is your service. So I suppose the question really comes down to a separation of concerns. Where is it better to perform such validation logic? Well that answer may very well be "in the service". But what about the answer to "Where is it better to contain query logic?". To me the answer is clearly "The Repository". That is its intended area of expertise.

How do you implement Pipes and Filters pattern with LinqToSQL/Entity Framework/NHibernate?

While building by DAL Repository, I stumbled upon a concept called Pipes and Filters. I read about it here, here and saw a screencast from here. I am still not sure how to go about implementing this pattern. Theoretically all sounds good , but how do we really implement this in an enterprise scenario?
I will appreciate, if you have any resources,tips or examples ro explanation for this pattern in context to the data mappers/ORM mentioned in the question.
Thanks in advance!!
Ultimately, LINQ on IEnumerable<T> is a pipes and filters implementation. IEnumerable<T> is a streaming API - meaning that data is lazily returns as you ask for it (via iterator blocks), rather than loading everything at once, and returning a big buffer of records.
This means that your query:
var qry = from row in source // IEnumerable<T>
where row.Foo == "abc"
select new {row.ID, row.Name};
is:
var qry = source.Where(row => row.Foo == "abc")
.Select(row = > new {row.ID, row.Name});
as you enumerate over this, it will consume the data lazily. You can see this graphically with Jon Skeet's Visual LINQ. The only things that break the pipe are things that force buffering; OrderBy, GroupBy, etc. For high volume work, Jon and myself worked on Push LINQ for doing aggregates without buffering in such scenarios.
IQueryable<T> (exposed by most ORM tools - LINQ-to-SQL, Entity Framework, LINQ-to-NHibernate) is a slightly different beast; because the database engine is going to do most of the heavy lifting, the chances are that most of the steps are already done - all that is left is to consume an IDataReader and project this to objects/values - but that is still typically a pipe (IQueryable<T> implements IEnumerable<T>) unless you call .ToArray(), .ToList() etc.
With regard to use in enterprise... my view is that it is fine to use IQueryable<T> to write composable queries inside the repository, but they shouldn't leave the repository - as that would make the internal operation of the repository subject to the caller, so you would be unable to properly unit test / profile / optimize / etc. I've taken to doing clever things in the repository, but return lists/arrays. This also means my repository stays unaware of the implementation.
This is a shame - as the temptation to "return" IQueryable<T> from a repository method is quite large; for example, this would allow the caller to add paging/filters/etc - but remember that they haven't actually consumed the data yet. This makes resource management a pain. Also, in MVC etc you'd need to ensure that the controller calls .ToList() or similar, so that it isn't the view that is controlling data access (otherwise, again, you can't unit test the controller properly).
A safe (IMO) use of filters in the DAL would be things like:
public Customer[] List(string name, string countryCode) {
using(var ctx = new CustomerDataContext()) {
IQueryable<Customer> qry = ctx.Customers.Where(x=>x.IsOpen);
if(!string.IsNullOrEmpty(name)) {
qry = qry.Where(cust => cust.Name.Contains(name));
}
if(!string.IsNullOrEmpty(countryCode)) {
qry = qry.Where(cust => cust.CountryCode == countryCode);
}
return qry.ToArray();
}
}
Here we've added filters on-the-fly, but nothing happens until we call ToArray. At this point, the data is obtained and returned (disposing the data-context in the process). This can be fully unit tested. If we did something similar but just returned IQueryable<T>, the caller might do something like:
var custs = customerRepository.GetCustomers()
.Where(x=>SomeUnmappedFunction(x));
And all of a sudden our DAL starts failing (cannot translate SomeUnmappedFunction to TSQL, etc). You can still do a lot of interesting things in the repository, though.
The only pain point here is that it might push you to have a few overloads to support different calling patterns (with/without paging, etc). Until optional/named parameters arrives, I find the best answer here is to use extension methods on the interface; that way, I only need one concrete repository implementation:
class CustomerRepository {
public Customer[] List(
string name, string countryCode,
int? pageSize, int? pageNumber) {...}
}
interface ICustomerRepository {
Customer[] List(
string name, string countryCode,
int? pageSize, int? pageNumber);
}
static class CustomerRepositoryExtensions {
public static Customer[] List(
this ICustomerRepository repo,
string name, string countryCode) {
return repo.List(name, countryCode, null, null);
}
}
Now we have virtual overloads (as extension methods) on ICustomerRepository - so our caller can use repo.List("abc","def") without having to specify the paging.
Finally - without LINQ, using pipes and filters becomes a lot more painful. You'll be writing some kind of text based query (TSQL, ESQL, HQL). You can obviously append strings, but it isn't very "pipe/filter"-ish. The "Criteria API" is a bit better - but not as elegant as LINQ.