I'm making a project that uses both WebAPI and ASP.NET MVC templates. My MVC sends requests to the WebAPI where the logic happens. For my WebAPI, I have created request/response models (they are used in the services). I need an advice, if it's worth to share this request/response models for WebAPI and MVC, or if there are some good practises to do such things. Thanks!
This is actually a very common situation in Micro-Service architecture. Generally, it is best to decouple your front end from your back end, much the same way an app is when calling any other api (e.g. Spotify's api). But if you do decouple them then you will need to have a copy of the request and response objects in the calling app as well as the api. They don't have to be exactly the same but they need to be close enough to send the request with all required info, and then catch the response and deserialize it back into the object you need in the front end.
The down side is that you end up having to change models two places every time a change has to happen. That or you start creating versioned routes and gradually deprecate the old ones.
Honestly, good practice for design when you are dealing with an API and MVC is separation. Typically you would have your API completely segregated from anything else front end or client wise, as think about it, an API is a self contained system. Like any API such as Google Maps API, theoretically you could call it from a mobile app, a web application, or another separate system so you define expectations for requests and it's up to each client to match the outgoing request model.
MVC models, in the base interpretation, should be for displaying information on the client, so they should be specific to each view and what the view needs, hence view model. You may need some or all of the data to display that an API sends so it's good practice to have the model fit only what the view needs, rather than have a bunch of data in memory that you possibly will never use.
In general, I find a good approach to be have a core project framework which has shared models which match the database, data models. You can use these base definitions, think an Address model which matches a database table which will not change in meaning, to create API models in the service layer for requests/response and data access, and additionally use in definition of view models. Shared core resources but completely separate models which fit the definition of what you are doing in that application layer.
Related
I want to create application with layered architecture. I have separate
Model project with only model classes
Data project responsible for CodeFirst configuration, migrations, etc.,
Service project responsible for business logic, and preserving the data in the database using EF
Dto project with classes used between Web app and service
Web project with asp.net mvc application.
My goal was to separate these projects so that Web project knows nothing about Model and Data - it just consumes Service using Dto classes, so the Web project should just reference Service and Dto. Everything was great until I configured Asp.Net Identity - in order to configure authorization I had to reference Data and Model project which I had wanted to avoid. Is it possible to achieve my goal, and (if so) how to do it.
My second question is: is my desing ok from the separation of concerns point of view?
I might separate all the ASP.NET Identity things into its own project housing both the EF data access and identity models. Think of it as separating the concerns more topically or by the subject matter, rather than by function.
So your web app would then reference Service, Dto, and Identity- and everybody seems to have their own corner of the world.
The goal, imo, is not necessarily to divvy up code by similar functionality, but to eliminate dependencies where none are needed, and to hide (or rather protect) domain knowledge into isolated and authoritative blocks.
Yes, your design is basically solid and generally works well.
I have a WebAPI web service, which acts as a business logic layer for client applications (WinForms and Mobile).
Now I want to create an MVC application which will act as presentation layer only, and I am having doubts weather this architecture makes sense or does it break MVC concepts.
If it makes sence, what is the right/correct way of interaction between MVC application (as a presentation layer) and WebAPI service (as a business logic layer)?
Will appreciate if anyone can give me some code examples.
It's fine if you use mvc this way, your controllers can access the webapi and serve the data to the templates.
You might also consider angularjs as views/templates and the controllers there can call the webapi for data.
While I think other answers are accurate, here is some other concerns you may think of.
First, your WebAPI is probably where your business are implemented. Indeed, you may already deal with:
Business related exception
Validation
Operations available
etc.
Your Api is what should not change, unless the business rule behind a certain functionnality changes too.
What I want to point out here is one thing:
Keep your user interface completely independant from your API
The risk of using an MVC app with a WebApi
All the code together = mutiple reasons to change the same thing
By using an MVC app, you could be tempted to package the WebApi and the MVC app in the same solution. You would also be able to deploy all your stuff together. But doing it this way, you may end up with a big bunch of code where parts are not evolving at the same speed (i.e: user interface will change oftently, but do the Api will change every time a UI fix is need. NO. And do every changes to the API will impact the UI. No.)
All code together enables shortcuts
What I mean by that, is that if everything is package together, a developer could be tempted to call some method directly instead of calling the API that should be the only valid facade. Any shortcut taken can lead will lead to code duplication, bugs, validation error, etc.
Again: do not package your MVC app with your API.
Solutions
Use a Javascript framework
The other suggestions are good. AngularJS, ReactJS, EmberJS are good frameworks. (There are other, pick the one that fits your needs) But again, it will be a good choice for your architecture because you will create a clear separation between your UI app and your API app which are separated concerns. Your business logic will be well protected, and you will be sure that your code is only call via HTTP calls, the only valid facade of your API. In other words, you make sure nobody will take shortcuts.
Use .NET MVC app in its own project
If you still want to use .NET MVC, I would suggest that you call your API via HTTP: no shortcuts. I would create a different solution and with a separated MVC project where calls to the API would be made using the HttpClient or something like RestSharp. What you want here is to avoid to bind your UI to your API code. You want to bind your UI to the contract define by the API facade (api controllers) not their implementation.
I think better, of course if it possible in your situation, to use one of the JavaScript MVC frameworks.
I think AngularJS, ReactJS or EmberJS will be the most coolest variants for your purpose. I don't think that calling ASP.MVC actions and then do another call to WEB API from there it's good idea, imho.
I want to finally decouple as much as i can my existing ASP.NET MVC projects.
They use multiple approaches as the time went by and i was learning:
Standard MVC, controller actions return separate views to browser.
Controller actions returning FAT partialviews and jquery updating pages.
Controller actions returning just JSON/XML data and jquery does the job of updating the UI
Now i want to move on to more dynamic front-ends by using heavier javascript approaches, by putting libraries like Knockout,Angular,Backbone e.t.c into the game. But i also want to be flexible enough and fast, if i want to just return a ready partialview from my controller actions.
So i was thinking of centralising my business layer NOT in the form of having common projects in my MVC projects, BUT having a Central WEB API endpoint above my business layer and DAL which will serve my various front ends (it can be MVC, console app, informs e.t.c)
This:
DAL -> Business Layer -> WEB API
After that i want to know how to connect to WEB API output from various points:
Pure JS: Directly from WEB Api endpoints with ajax calls
2. .NET apps (MVC,WinForms e.t.c): How exactly?
My question is mostly about #2 above. I want specific use cases on how to consume my central WEP API from within windows Forms or MVC controller actions
This is called a Service Oriented Architecture.
For #2, you have the following options to call RESTful services from a .NET client (be it ASP.NET MVC or WinForms):
Using an HttpClient.
Use RestSharp. This is a helper lib which covers most of the basic operations, including request/response serialization and deserialization. Note that in newer versions JSON.NET support has been removed (for some reason I'm not remembering now... anyway, it's in a Google Groups discussion).
Either way I recommend looking into the async/await pattern which HttpClient fully supports. It will make your life a lot easier, especially for the WinForms stuff.
About #1, there's nothing stopping you from having the JavaScript front-end calling into the Web API. Just be careful with CORS, as I assume you might need it (by having multiple web clients, possibly deployed on different domains).
I am new to asp.net mvc. I want to divide presentation layer with logic layer. I know it is already done in asp.net mvc but I want to have presentation layer on another machine. I don't know if this what I want to do, is possible, but just wanna ask. I want something like this: User enters address 123.123.123.123/Home then that request is redirected to presentation layer. Presentation layer is then asking "Logic Server" for data(from database or smthing) and logic server returns it back to presentation layer which presents the page to the client.
My overall goal is to make framework which allows us to do this easily.
And my questions:
1. Is it worth doing it?
2. Is it possible with asp.net mvc ?
3. Is there anything like this?
I wanna also extend that framework to work independent from technology. And the presentation layer would be a "connector"
You can do this by having some kind of Service Oriented Architecture. In your MVC app you have a services layer, this could talk to a WCF service or something similar on your network. Your WCF service would then talk to another machine for data storage, do the required business logic and return simple DTO's.
Is it worth doing? This depends on you. Is there a good reason to do this? It shouldn't be that hard, and if you write your MVC app correctly the services layer will abstract away the fact that the service is on another machine or the same machine so you have some flexibility to change your mind later.
Is it possible? Yup
Is there anything like this? I'm sure there are plenty of people out there who are doing/have done what I have described
Quite strange architecture.
You can indeed use SOA. It has many advantages and it's well studied and supported.
However, I wouldn't use SOA for the presentation layer (and I don't remember to have seen that never).
You'd normally have the business logic in a layer, and expose it as Web Services (that's SOA), and all the presentation (in this case creating MVC view models, and returning the rendered views to the browser) in the same application. (See note at the bottom)
It has no sense to separate the Presentation in a SOA layer, because you cannot reuse it for anything else. I.e. you cannot use that presentation layer for a windows application, or to use it for a java web application.
However, if your business logic is exposed in a SOA layer, then you can use it with any kind of UI you want: windows forms, WPF, or even a Java Web Application.
Apart form this there is a tigh knot between routes, and controllers in MVC. You cannot easily achive what you want to do. However, you can easily make an MVC presentation layer (routes, controllers and viewws), which uses the business layer exposed as SOA from your controllers. That's much more natural.
Is it possible: of course, but non-standard and har to do.
Is it worth: No it isn't. Your canot reuse it with a different techonlogy. Which is the advantage?
Is something like this: neve seen it!
NOTE: having a single app doesn't mean having a single layer. But you don't need to separate them in different applications or SOA layers. If you use MVC correctly you'll have a very clear separation between Views (which render the result for the browser) and controllers (which prepare the View Models for rendering the Views) and the Business layer (which can be in a different app, exposed as SOA services, and consumed from this controllers). In fact, it's hardly impossible to make a bad use of MVC if you have into account that you need View Models, which are objects specifically created for the view to be rendered, instead of using directly the business entities.
For example a vie model can have a customer's data to edit it, but probably will have several lists of options for populating drop down lists. If you don't use view models, you'll soon have problems.
Struggling with this one today.
Rewriting a web-based application; I would like to do this in such a way that:
All transactions go through a web services API (something like http://api.myapplication.com) so that customers can work with their data the same way that we do / everything they can do through our provided web interface they can also do programmatically
A class library serves as a data layer (SQL + Entity Framework), for a couple of design reasons not related to this question
Problem is, if I choose not to expose the Entity Framework objects through the web service, it's a lot of work to re-create "API" versions of the Entity Framework objects and then write all the "proxy" code to copy properties back and forth.
What's the best practice here? Suck it up and create an API model class for each object, or just use the Entity Framework versions?
Any shortcuts here from those of you who have been down this road and dealt with versioning / backwards compatibility, other headaches?
Edit: After feedback, what makes more sense may be:
Data/Service Layer - DLL used by public web interface directly as well as the Web Services API
Web Services API - almost an exact replica of the Service Layer methods / objects, with API-specific objects and proxy code
I would NOT have the website post data through the web services interface for the API. That way leads to potential performance issues of your main website. Never mind that as soon as you deploy a breaking API change you have to redeploy the main website at the same time. There are reasons why you wouldn't want to be forced to do this.
Instead, your website AND web services should both communicate directly to the underlying business/data layer(s).
Next, don't expose the EF objects themselves. The web service interface should be cleaner than this. In other words it should try and simplify the act of working with your backend as much as possible. Will this require a fair amount of effort on your part? yes. However, it will pay dividends when you have to change the model slightly without impacting currently connected clients.
It depends on project complexity and how long you expect it to live. For small, short living projects you can share domain objects across all layer's. But if it's big project, and you expect it to exist, work well, and update for next 5 years....
In my current project (which is big), I first started with shared entities across all layers, then i discovered that I need separate entities for Presentation, and now (6 month's passed) I'm using separate classes for each layer (persistence, service, domain, presentation) and that's not because i'm paranoid or was following some rules, just I couldn't make all work with single set of classes across layers... Make you conclusions..
P.S. There are tools that can help you convert your objects, like Automapper and Value Injecter.
I would just buck up and create an API specifically aimed at the needs of the application. It doesn't make much sense to what amounts to exposing the whole DB layer. Just expose what needs to be exposed in order to make the app work, and nothing else.