.Net Core Rest API Best practise - rest

I was wondering what the best practise would be concerning the following API structure:
OrderItemDepartment has a one to many relationship with OrderItemSection which in turn has a one to many relationship with OrderItem.
Dividing the api into controllers with each having CRUD actions e.g.:
OrderItemDepartmentsController
Get: OrderItemDepartments.
OrderItemSectionsController
Get: OrderItemSections.
OrderItemsController
Get: OrderItems.
..Or having a single controller serving the OrderItems, Departments and Sections via routing:
OrderItemsController
Get: OrderItems/Departments
Get: OrderItems/Sections
Get: OrderItems*

I doubt there's a single clear answer for this that will cover all cases, but in general it's a good idea to encapsulate responsibility an logic for each specific part of your application within it's own class.
You mention CRUD (Create, Read, Update, Delete), and that is a central point here; As the name sugests, these operations typically follow a certain pattern. If you are able t organize all of your contoller-classes in a similar way, you may be able to extract common logic from them, either into helper-classes or into interfaces that each controller can implement. This will in turn make your application more flexible and less messy if (when?) you have to expand it at a later time.
Using separate controllers in the top level of your app is also likely to make it easier to organize lower-level components. For example, you might have separate business- and / or repository-components corresponding to each controller, and yet each of these components may implement common interfaces. That way, each part of your application will consist of a separate but internally consistent "vertical slice" (e.g. controller, Business and Repository).
Now if you need to add new functionality to your application, you have a clear pattern which will be easy to understand, and speed up development: Add a Controller that implements the same common interfaces as those you already have, and do the same for new components in your business- and repository-layers, respectively.

Related

Why use interfaces

I see the benefit of interfaces, to be able to add new implementations via contract.
I dont see following problem:
Imagine you have interface DB with method "startTransaction".
Everything is fine you implement it in MySQL, PostgreSQL. But tomorrow you move to mongodb - then you have no transaction support.
What do you do?
1) Empty method - bad because you think you have transactions but u havent
2) Create your own - then you should have some parameters that will be different that regular "startTransaction" method.
And on top of that sometimes simple interfaces just doesnt work.
Example: You need additional parameters for different implementations.
If you're exposing the concept of transactions on your interface, then you must functionally support transactions no matter what, since users of the interface will logically depend on it. I.e., if a caller can start a transaction, then they expect to also be able to roll back a transaction of several queries. Since Mongo doesn't natively have any concept of rolling back transactions, there's one of two possibilities:
You implement the possibility of rolling back queries in code, emulating the functionality of transactions for a database which doesn't natively support it. (Whether that's even reliably possible in Mongo is a debatable topic.)
Your interface is working at the wrong level of abstraction. If your interface is promising functionality an implementation can't deliver, then either the interface or the implementation is unrealistic.
In practice, Mongo and SQL databases are such different beasts that you would either never make this kind of change without changing large parts of your business logic around it; or you specify your interface using an extremely minimal common-denominator interface only, most certainly not exposing technology-specific concepts on an abstract interface.
You are mostly correct, interfaces can be very useful, but also problematic in (fast) changing code, a best practice conserning interfaces is to keep them as small as possible.
When something can handle an transaction, create an interface only for handling an transaction. Split them up in as small as logically possible parts, in that way, when new classes emerge, you can assign them the specific interfaces that can determine their methods.
For the multiple parameter problem, this can indeed be problematic, see if you can determine if this specific value could be moved to a constructor, or indicates that the action that you are doing is indeed sightly different from the action that does not need this parameter.
I hope this helps, goodluck
You are right interfaces are used to add new implementations via contract but those implementations have to posses some similarity.
Let's take an example:
You cannot implement dog using human interface because dog is a living organism.
Same thing you are trying to do here.You are trying to implement a non-sql db using sql db implementation.

Domain Driven Design - Shared entities across bounded contexts

I am new to domain driven design and trying to learn and implement in my project. My project structure up till now similar to this.
Maintainance Folder Maintainance.Data(Class
Library) Maintainance.Domain(Class Library)
Maintainance.Domin.Tests(test project)
MovieBooking Folder MovieBooking.Data(Class
Library) MovieBooking.Domain(Class Library)
MovieBooking.Domain.Tests(test project)
SharedKernel Common things
Web Application MovieBooking MVC Web
Application(which have reference to MovieBooking Domain)
In Maintainance boundned context I am keeping all CRUD, GetAll type things for say Movie, Country, Category, Subcategory entities in Maintainance DBContext.
Now in MovieBooking data layer I will also need to use these entities (mostly to display name or dropdown fills in view, kind of subset needed - not all properties needed, only few like Id, name)
There are few ways I can access this entities in Movie booking Bounded Context
Via web services - Need to create web api for common entities like Movie,Country,Category,Subcategory and call web api in web project (to fill Dropdowns or get name from entities)
Via Reference Context (Seperate Dbcontext) - Need to configure Dbset and then map a database view (with only require fields) to Dbset
Example :
modelBuilder.Entity().ToTable(ViewName);
For (1) it can be long term implmentation solution for me
(2) I have to create view (with only few properties) for each require table and it will increase my number of views in my DB drastically as I have enterprise level application.
Is there any other way I can achieve this? Anything I am missing in DDD to look for ?
Option 2, while it will save you time, is actually a very bad idea from the DDD perspective as it allows for violations of the transactional boundary guarantees that each aggregate is meant to enforce\represent.
Option 1 seems a better option, although there are still quite a bit of wiggle room for interpretation based on your brief description of your proposed solution. If I understood correctly, it is generally recommended to follow the below:
Do not expose your aggregate state directly since this exposes internals and increases coupling. Simple create meaningful DTO's and use something like Automapper to map your Aggregates to DTO's easilly and with little effort before sending it over.
Have a duplicate of the DTO definition in your client. This will reduce coupling and allow for easier deployments.
I strongly recommend reading the DDD orange book although I have to say that I cannot recall specifically on which chapter this is discussed. You will also benefit a lot by reading about hexagonal architecture (and I would search for that term in the orange book to find more info about your question).
There is actually one alternative that I can think of: if you're publishing events from your BC's you can create a workflow to translate the domain events to "public" events and then in the other BC listen for the public events that you need to and store the data that you need somewhere inside there. The difficulty of this ranges from very easy to quite problematic depending on your infrastructure. Be aware that it is not a very good idea to re-use your domain events for transmitting data to other BC's since this closely couples the two BC's.
I hope this helps. Please do not hesitate to elaborate if I did not understood the question well enough.

Where does Search fit into the MVC software pattern?

I am implementing a database search algorithm which searches over many collections in a MongoDB and returns optimized results based on the state of the entire database. I have no problems with the implementation, but the nomenclature and how I should structure the file system is bugging me. Where in the model-view-controller pattern should I place read only operations? Is it a service? It has a controller but I hardly think it satisfies the criteria to be a model.
This question is extremely language dependant and the features that exist within that language. I will speak from a PHP point of view.
Search functions should go into the model, the model backs up as a data provider in the MVC pattern. A single central point from which to dish out instances of it self.
Some MVCs implement what is known as factory classes. They are specifically designed to sit outside of the MVCs normal pattern to be able to provide data: http://en.wikipedia.org/wiki/Factory_method_pattern . As someone who has used this pattern I can say it gets complicated and unmanageable very quickly. That is why I prefer to backup the model as a data provider itself, it merely requires class organisation.
Model View Controller architecture is pretty much the equivalent of a three or four tier solution in a client server setup and the same rules apply.
Complex and intensive database functionality lives with the tool that is best suited to the task and is most re-usable and in this case I would argue that the RDBMS would be the best option in the vast majority of RDBMS's as it is the RDBMS that best knows how to manipulate it's data, work out query plans etc...
It could also be argued that the model layer would be the most natural place from a purist coding point of view where you have all your data access in one layer.
It is highly unlikely that it would ever be advantageous to place this sort of functionality in the least re-usable layer i.e. the controller/view
This is of course only my opinion and I suspect you will get many alternative opinions but ( can not for the life of me think that from a performance point of view that yopur logic belongs anywhere other than at the database level
UPDATE
A model is the guardian of all data. if a view or controller wants data, it asks the model for that data. The view or controller shouldn't care about how the data is obtained or where it comes from. It's about separation of concerns. So that leaves the question. Do I place the code to query the database in the model or in the RDBMS?
Well of course you have to have a method in a model for the view or controller to call in the first place so of course you need a model but what goes inside that method and where the actual query SQL lives is up to the designer. The point is, that so long as the query lives at model or database level you are hiding the implementation from the view or controller and are free to change the implementation whenever you wish without having to worry about the potentially many places it is called from.
So model or RDBMS is the answer. The solution chosen depends on the MVC tools you are using and the RDBMS you are using. Also remember that a model does not have to consist of a single method which is what you are implying you may be thinnking from your comment.

How to expose read model from shared module

I am working on developing a set of assemblies that encapsulate parts of our domain that will be shared by many applications. Using the example of an order management system, one such assembly will contain all of the core operations an application can perform to/with an order. We are applying a simple version of CQS/CQRS so that all operations that change the state of the "system" are represented as public commands, such as CancelOrderCommand, ShipOrderCommand and CreateORderCommand. The command handlers are internal to the assembly.
The question I am struggling to answer is how to best expose the read model to consuming code?
The read model will be used by consuming code to perform queries. I don't know how all of the ways the read model will be used so the interface needs to be flexible to allow any query.
What complicates it for me is that I not only need to expose my aggregate root but there are also several "lookup" lists of related data that client applications may use. For example, each order has an associated OrderType which is data-driven (i.e., not an enum) and contains several properties that will drive some of our business rules that control what operations can/cannot be performed, etc. It is easy inside my module to manage this relationship; however, a client application that allows order creation will most likely need to display the list of possible OrderTypes to the user. As a result, I need to not only expose the list of Order aggregates but the supporting list of OrderTypes (and other lookup lists) from my read model.
How is this typically done?
I'm not sure what else to explain that will help trigger a solution, so please ask away...
I have never seen a CQRS based implementation expose a full dataset for ad-hoc querying so this is an interesting situation! In a typical CQRS scenario you would expose very specific queries because you may want to raise events when they are called (for caching for example - see this post for more details on that).
However since this is your design, let's not worry about "typical" or "correct" CQRS, I guess you just need a solution! One of the best new mechanisms for exposing data for flexible querying I have seen is the Open Data Protocol (OData). It will allow consumers to implement their own filtering, sorting and paging over a data source you expose.
Most implementations of this seem to deal with relational data. If you are dealing with a relational data source then OData might be a nice way to go. I suspect by your comment of "expose my aggregate root" that you might be using a document database? If so, there is one example I have seen of OData services on top of MongoDB: http://bloggingabout.net/blogs/vagif/archive/2012/10/11/mongodb-odata-provider-now-supports-arrays-and-nested-collections.aspx.
I hope that helps, OData is definitely worth looking into. It seems to be growing really quickly and is getting good support on both server and client technology platforms.

Zend_Rest_Controller and Zend_Rest_Route use cases

I'm following these tutorials thoroughly and must say they're great tutorials!
http://www.techchorus.net/create-restful-applications-using-zend-framework
I'm just confused about the whole concept of Zend_Rest abstract methods. In the examples, you only see
index
POST
GET
PUT
DELETE
While these functions make sense, I'm trying to figure out if the whole architecture is only limited to those abstract methods. I'm thinking about a use case where a consumer wants to use the API to update specific fields in lets say the user table, or another case where the consumer wants to update activity table. The business logic of these two tables are covered in one RESTful api controller. I would tackle this problem by creating specific update/post method for each table, and have function parameters to define which fields are being updated. Would this kind of implementation conform with REST and if so how do you go beyond POST,GET, PUT, DELETE methods?
REST architecture does support hierarchical relationships for resources, and your resources are not bound with your database in any way. Your “User” resource might have a subresource “Credentials” that maps to username and password fields in your users table, so you could do a PUT request on “domain.com/users/{userId}/credentials”. You will implement this by creating a controller, say UserCredentials, and the update logic would be in the putAction.
You will have to modify the routing for this to work in Zend though. See How to set up Hierarchical Zend Rest Routes?