I'm really new to API design and MVC concepts, but as far as I can tell, something like GET /api/products should return a list of products and GET /api/products/1 should return a single product. In terms of speed my feeling is that /api/products should return less information i.e. just id and name, whereas /api/products/1 should return more i.e. id, name, and description.
As far as I can see, the best way to handle this is to make certain fields of the product class not be returned in the /api/products endpoint. This is especially necessary in the case of /api/products?fields=name . I'm using ASP.Net Web Api 2 and have tried the following:
http://www.nuget.org/packages/WebApi.PartialResponse/ - installing this package caused an assembly version error.
Adding ShouldSerialize methods on the Product fields. For reasons I won't go into here, this method is a little cumbersome.
Looked at ASP.NET Web API partial response Json serialization but there doesn't seem to be a conclusive answer there.
ASP.NET WebApi and Partial Responses suggests using a product class with all nullable fields. I'm not sure I understand exactly what to do there.
Is there any simple way to do what I'm trying to do?
Otherwise could you suggest a better API design than what I'm doing?
You could also use WebApi.PartialResponse (http://www.nuget.org/packages/WebApi.PartialResponse/). It's a package I wrote which uses LINQ to JSON (Json.NET) to manipulate the returned objects. It uses the fields syntax used by Google in their API's, eg.:
fields=items/id,playlistItems/snippet/title,playlistItems/snippet/position
fields=items(id,snippet/title,snippet/position)
fields=items(id,snippet(title,position))
You can find more information on the GitHub project page: https://github.com/dotarj/PartialResponse.
I'd recommend using separate classes to map to when returning a list of entities.
Particularly as the problem is not just what you return to the user, but also what you select from the database.
So, make getting and entity return a Product object, and getting a list of entities return a ProductLink object or something similar.
Edit
As per jtlowe's comment, if you have many different methods returning slight variations of product properties, use anonymous classes (though I'd question whether this is necessarily a good design).
Consider something like this in your action
return from p in this.context.Products
select new
{
p.Id,
p.Name,
p.SKU
};
This:
Only selects the columns you need from the database.
Needs no additional classes defined for new variations of the product
This doesn't make it easy to pass the result of this statement around to other methods because you can only return it as IEnumerable, object or dynamic. If you are putting this in the controller then it may be good enough. If you are implementing a repository pattern, you'll be unable to return strongly typed lists if you use anonymous types.
Stumpled over this topic and just want to share my feelings - maybe it helps others :) I recommend to use something like OData.
You can implement it so that you can write /api/products?$select=Id,Name,Price
some advantages:
with OData you can use further functions, like $filter, $orderby to work with filters and sort it
$skip, $top, $count to get a nice paging
more $-functions :)
you can directly apply it to a IQueryable<T>. Why is this great? You reduce the result not just in the response of your API, but you even reduce the result your database generates, which makes your application much faster. - and you don't even have to change your query
some disadvantages:
you can't filter directly on columns that are calculated
setting it up will take a little time
hint: sometimes it's better to just use ODataQueryOptions<T> in the parameter instead of complete implementation.
Related
Good evening!
I am currently working on the backend of my application and I need to get a list of all properties of a certain datatype but only the ones in the current page.
listFiltersCms = _umbraco.ContentAtRoot().SelectMany(c => c.Descendants<DataFilters>()).ToList();
This line above gathers all the filters from all the pages, but I want the filters from a specific page (can be currentPage).
I have tried something like this:
var listFiltersCms = _umbraco.AssignedContentItem.SelectMany(c => c.Descendants<DataFilter>()).ToList();
But without any luck :( Any ideas?
Not entirely sure what you mean by "the backend of my application" - are you inside Umbraco or on a public website?
I ask because there is a fairly straightforward way of getting all info on a specific datatype, but it is not really meant to be used on public facing websites. It can be, but it might be taxing on the system as I believe it queries the database directly, which is not ideal.
Anyway, you might want to take a look at the DataTypeService:
https://our.umbraco.com/Documentation/Reference/Management/Services/DataTypeService/Index-v8
And here you can see what options you have for using it (not very explanatory, but I spot a few methods you could probably look into):
https://our.umbraco.com/apidocs/v8/csharp/api/Umbraco.Core.Services.IDataTypeService.html
If you decide to use the service in a scenario where there will be a lot of requests, maybe consider caching the output to spare the database.
The way I solved this issue was by getting the page in the correct model. In my case all I had to do was:
(_umbraco.AssignedContentItem as PageModel).FilterCustomMeasures;
I am using repository pattern in a .NET MVC project where I need to fetch data using the same function but in a two different structures(conditionally).
To be more specific, there are cases where I need to fetch the full version of the model having a bunch of properties but there are also cases where I need to fetch a frugal version of the model (mostly for security reasons).
The code so far:
public async Task<IEnumerable<AnswerMinimalDto>> GetQuestionsForUser(int userId)
{
IEnumerable<Answer> foundAnswers = await this.repository.getAnswersByUser(userId);
return Mapper.Map<IEnumerable<AnswerMinimalDto>>(foundAnswers);
}
So the mapping should happen conditionally:
....return Mapper.Map<IEnumerable<AnswerMinimalDto>>(foundAnswers);
or
....return Mapper.Map<IEnumerable<AnswerFullDto>>(foundAnswers);
Here we have two object oriented principles conflicted. First thought is to have two different methods to satisfy the Single Responsibility principle. On the other hand, by having two different methods doing the same job is a duplication.
I am going with the approach of a single method. What I've tried so far is to make an approach using Tuples to return both models and handle the required result from the controller (out can not apply since my method is async). But I am not really happy with the approach.
To the point, I wonder if there is any elegant/preferable way to return the data in different structure chosen conditionally.
Any help is welcome.
having two different methods doing the same job is a duplication
But they are not doing the same job! one gives you more data, another less data. That's two different things in my view.
Also trying to get controller to decide what to present to the client is a smell - business logic is spelled out to controller.
As you said - you can have 2 methods that give different data. But I would go further, and segregate the interfaces: one interface, two implementations. IRepository and FullRepositoryImpl and FrugalRepositoryImpl.
And let your DI decide which one is required at the moment, because I bet this is not a single occurrence where you need to present a limited set of data.
You can solve this simply using Generics:
public async Task<IEnumerable<T>> GetQuestionsForUser<T>(int userId)
{
IEnumerable<Answer> foundAnswers = await this.repository.getAnswersByUser(userId);
return Mapper.Map<IEnumerable<T>>(foundAnswers);
}
IEnumerable<AnswerMinimalDto> a = await GetQuestionsForUser<AnswerMinimalDto>(foundAnswers);
IEnumerable<AnswerFullDto> b = await GetQuestionsForUser<AnswerFullDto>(foundAnswers);
Though I do agree with a lot that trailmax says on this TBH.
IMO DTO objects and Automapper are code smells/anti patterns. Why don't you just return your underlying object?
Do you have a way of restricting the data returned by a REST API? For example, let's say I have a user search POST with an Expand parameter which accepts a string[] of child entities to include like "groups"
Let's say that groups has 10 attributes and I want to provide the ability to select only 2 of those group attributes like GroupId, GroupName as part of the request so the response only includes that data.
Do you have a good way of implementing this type of design?
Create a good old DTO (Data Transfer Object) and map your database fields into the DTO and return the DTO. It is a predetermined result (subset of fields).
-or-
I don't have access to my resource links at the moment, but there's a good course on Pluralsight for Web API 2 that discusses data-shaping. It involves creating and returning an ExpandoObject This would be the technique to allow the calling program to pick and choose. More flexibility, but more complexity.
Back story:
So I've been stuck on an architecture problem for the past couple of nights on a refactor I've been toying with. Nothing important, but it's been bothering me. It's actually an exercise in DRY, and an attempt to take it to such an extreme as the DAL architecture is completely DRY. It's a completely philosophical/theoretical exercise.
The code is based in part on one of #JohnMacIntyre's refactorings which I recently convinced him to blog about at http://whileicompile.wordpress.com/2010/08/24/my-clean-code-experience-no-1/. I've modified the code slightly, as I tend to, in order to take the code one level further - usually, just to see what extra mileage I can get out of a concept... anyway, my reasons are largely irrelevant.
Part of my data access layer is based on the following architecture:
abstract public class AppCommandBase : IDisposable { }
This contains basic stuff, like creation of a command object and cleanup after the AppCommand is disposed of. All of my command base objects derive from this.
abstract public class ReadCommandBase<T, ResultT> : AppCommandBase
This contains basic stuff that affects all read-commands - specifically in this case, reading data from tables and views. No editing, no updating, no saving.
abstract public class ReadItemCommandBase<T, FilterT> : ReadCommandBase<T, T> { }
This contains some more basic generic stuff - like definition of methods that will be required to read a single item from a table in the database, where the table name, key field name and field list names are defined as required abstract properties (to be defined by the derived class.
public class MyTableReadItemCommand : ReadItemCommandBase<MyTableClass, Int?> { }
This contains specific properties that define my table name, the list of fields from the table or view, the name of the key field, a method to parse the data out of the IDataReader row into my business object and a method that initiates the whole process.
Now, I also have this structure for my ReadList...
abstract public ReadListCommandBase<T> : ReadCommandBase<T, IEnumerable<T>> { }
public class MyTableReadListCommand : ReadListCommandBase<MyTableClass> { }
The difference being that the List classes contain properties that pertain to list generation (i.e. PageStart, PageSize, Sort and returns an IEnumerable) vs. return of a single DataObject (which just requires a filter that identifies a unique record).
Problem:
I'm hating that I've got a bunch of properties in my MyTableReadListCommand class that are identical in my MyTableReadItemCommand class. I've thought about moving them to a helper class, but while that may centralize the member contents in one place, I'll still have identical members in each of the classes, that instead point to the helper class, which I still dislike.
My first thought was dual inheritance would solve this nicely, even though I agree that dual inheritance is usually a code smell - but it would solve this issue very elegantly. So, given that .NET doesn't support dual inheritance, where do I go from here?
Perhaps a different refactor would be more suitable... but I'm having trouble wrapping my head around how to sidestep this problem.
If anyone needs a full code base to see what I'm harping on about, I've got a prototype solution on my DropBox at http://dl.dropbox.com/u/3029830/Prototypes/Prototype%20-%20DAL%20Refactor.zip. The code in question is in the DataAccessLayer project.
P.S. This isn't part of an ongoing active project, it's more a refactor puzzle for my own amusement.
Thanks in advance folks, I appreciate it.
Separate the result processing from the data retrieval. Your inheritance hierarchy is already more than deep enough at ReadCommandBase.
Define an interface IDatabaseResultParser. Implement ItemDatabaseResultParser and ListDatabaseResultParser, both with a constructor parameter of type ReadCommandBase ( and maybe convert that to an interface too ).
When you call IDatabaseResultParser.Value() it executes the command, parses the results and returns a result of type T.
Your commands focus on retrieving the data from the database and returning them as tuples of some description ( actual Tuples or and array of arrays etc etc ), your parser focuses on converting the tuples into objects of whatever type you need. See NHibernates IResultTransformer for an idea of how this can work (and it's probably a better name than IDatabaseResultParser too).
Favor composition over inheritance.
Having looked at the sample I'll go even further...
Throw away AppCommandBase - it adds no value to your inheritance hierarchy as all it does is check that the connection is not null and open and creates a command.
Separate query building from query execution and result parsing - now you can greatly simplify the query execution implementation as it is either a read operation that returns an enumeration of tuples or a write operation that returns the number of rows affected.
Your query builder could all be wrapped up in one class to include paging / sorting / filtering, however it may be easier to build some form of limited structure around these so you can separate paging and sorting and filtering. If I was doing this I wouldn't bother building the queries, I would simply write the sql inside an object that allowed me to pass in some parameters ( effectively stored procedures in c# ).
So now you have IDatabaseQuery / IDatabaseCommand / IResultTransformer and almost no inheritance =)
I think the short answer is that, in a system where multiple inheritance has been outlawed "for your protection", strategy/delegation is the direct substitute. Yes, you still end up with some parallel structure, such as the property for the delegate object. But it is minimized as much as possible within the confines of the language.
But lets step back from the simple answer and take a wide view....
Another big alternative is to refactor the larger design structure such that you inherently avoid this situation where a given class consists of the composite of behaviors of multiple "sibling" or "cousin" classes above it in the inheritance tree. To put it more concisely, refactor to an inheritance chain rather than an inheritance tree. This is easier said than done. It usually requires abstracting very different pieces of functionality.
The challenge you'll have in taking this tack that I'm recommending is that you've already made a concession in your design: You're optimizing for different SQL in the "item" and "list" cases. Preserving this as is will get in your way no matter what, because you've given them equal billing, so they must by necessity be siblings. So I would say that your first step in trying to get out of this "local maximum" of design elegance would be to roll back that optimization and treat the single item as what it truly is: a special case of a list, with just one element. You can always try to re-introduce an optimization for single items again later. But wait till you've addressed the elegance issue that is vexing you at the moment.
But you have to acknowledge that any optimization for anything other than the elegance of your C# code is going to put a roadblock in the way of design elegance for the C# code. This trade-off, just like the "memory-space" conjugate of algorithm design, is fundamental to the very nature of programming.
As is mentioned by Kirk, this is the delegation pattern. When I do this, I usually construct an interface that is implemented by the delegator and the delegated class. This reduces the perceived code smell, at least for me.
I think the simple answer is... Since .NET doesn't support Multiple Inheritence, there is always going to be some repetition when creating objects of a similar type. .NET simply does not give you the tools to re-use some classes in a way that would facilitate perfect DRY.
The not-so-simple answer is that you could use code generation tools, instrumentation, code dom, and other techniques to inject the objects you want into the classes you want. It still creates duplication in memory, but it would simplify the source code (at the cost of added complexity in your code injection framework).
This may seem unsatisfying like the other solutions, however if you think about it, that's really what languages that support MI are doing behind the scenes, hooking up delegation systems that you can't see in source code.
The question comes down to, how much effort are you willing to put into making your source code simple. Think about that, it's rather profound.
I haven't looked deeply at your scenario, but I have some thoughs on the dual-hierarchy problem in C#. To share code in a dual-hierarchy, we need a different construct in the language: either a mixin, a trait (pdf) (C# research -pdf) or a role (as in perl 6). C# makes it very easy to share code with inheritance (which is not the right operator for code-reuse), and very laborious to share code via composition (you know, you have to write all that delegation code by hand).
There are ways to get a kind of mixin in C#, but it's not ideal.
The Oxygene (download) language (an Object Pascal for .NET) also has an interesting feature for interface delegation that can be used to create all that delegating code for you.
I'd like to implement MVC while using LINQ (specifically, LINQ-to-entities). The way I would do this is have the Controller generate (or call something which generates) the result-set using LINQ, then return that to the View to display the data. The problem is, if I do:
return (from o in myTable select o);
All the columns are read from the database, even the ones (potentially dozens) I don't want. And - more importantly - I can't do something like this:
return (from o in myTable select new { o.column });
because there is no way to make anonymous types type-safe! I know for sure there is no nice, clean way of doing this in 3.5 (this is not clean...), but what about 4.0? Is there anything planned, or even proposed? Without something like duck-typing-for-LINQ, or type-safe anonymous return values (it seems to me the compiler should certainly be capable of that), it appears to be nearly impossible to cleanly separate the Controller from the View.
Use a view model layer. Your view has to know what it is going to display. I guess its possible to create a view that just formats a multi-dimensional array of data, but that isn't exactly the best reason to go with an MVC solution. You can however populate a view model with an anonymous object for consumption in your view.
Anonymous types are primarily designed to be used within a method. They are not suitable for communication between methods.
If you need to pass a set of data between two functions the best way is to create a new type wrapping the data or use a loser grouping like Tuple<T1,T2> or KeyValuePair<TKey,TValue>
How about this?
I assume that you have an entity class for your table 'myTable' (let's call it 'MyTableEntity'), so why don't you instantiate a new MyTableEntity object and use object initializer to fill only those columns you want?
return (from o in myTable select new MyTableEntity { AColumn = o.column });
This will not translate to a SELECT * as you asked, but you'll still have a way to pass a strongly-typed object to a view.
You have to be careful to just make use of the initialized properties inside the view and that's it.
Does this makes sense for you?
Since no one even attempted to answer my question, I will answer it myself..
It turns out, C# 4.0 supports duck-typing - they call it dynamic typing. However, in using dynamic types to return anonymous types, we lose the benefits of strong types:
Compile-time type-checking
Performance
Intellisense
I've opened a feature request to have strongly-typed anonymous return types here - if you think this would be a useful addition to C# 5, follow the link and let the .Net team know!
On .NET 4.0 Anonymous types can easily be converted to ExpandoObjects and thus all the problems is fixed with the overhead of the conversion itself.
Check out here
You can easily convert anonymous types into dynamic objects, here is the simple implementation of Donymous objects (Dynamic anonymous objects) that can populate from Anonymous object or DataReader.