DDD: Where to Place Interfaces (ports) - domain-driven-design

I know that IRepository has to put in domain folder, but for the rest of the interfaces such as: IQueryBus, ICommandBus... should I put them in Application folder?
I've seen a lot examples where some of them put this kind of interfaces in domain like /domain/bus/IQueryBus, /domain/bus/ICommandBus and other put them in /application/bus/IQueryBus /application/bus/ICommandBus. I'm not sure what is the best option and why. Also I've read this article https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/ that explain: It’s important to note that the Ports (Interfaces) belong inside the business logic, while the adapters belong outside. so, if I understood very well all interfaces have to put in domain folder?

First of all , we have to distinguish the aspect of the port:
Driver ports (primary ports). They are interfaces offering the use cases of our application. So they belong to the application layer. They are called by the driver adapters and they are implemented by the application layer.
Driven ports (secondary ports). Here it depends. A driven port is an abstraction (interface) for doing some task that is performed by an external actor outside your application. If such task is logic that is independent of whatever domain, then the port interface belongs to the application layer (for example a port for authentication and authorization). If the tasks are logic of the domain of your application, then the port belongs to the domain.

I will refer to the word context as a space that can be a package or a folder or whatever container you can use to separate concepts.
You should put each interface in the context determined by its purpose.
Generic interfaces like ICommandBus can be put inside an "infrastructure" context, the interfaces offering domain behavior inside the domain context, if inside it you have a more specific context inside the domain context use that one.
That kind of interfaces are like bridges between contexts, so, each context has its own interfaces offering functionalities implemented in a different context.

Related

DDD: Using External Websocket

I am trying to design a microservice using DDD approach.
Microservice has an aggregate whose state/logic depends on the data received over WS connection to a thrid-party server. WS is used because of latency issues.
According to my understanding, DDD seems to indicate that external APIs have to go through application layer. Except WS connection instantiation, there will be lot of to and fro for dataflow with this approach in application layer. Not sure how to go about this.
A web-socket is a form of connection between your microservice and another component. There are other forms of connections as well, e.g. request/response and message queues. Connectivity is an infrastructural matter, therefore its implementation (instantiation or receiving data) should reside not in the application layer but in an infrastructural layer.
Once data is received through web-socket channel, it should be packed into an application service.
According to my understanding, DDD seems to indicate that external APIs have to go through application layer
External API invocations, much like web-sockets, should be implemented in an infrastructural layer. If an API is used to retrieve data, it should probably be abstracted away as a repository (in line with DDD principles: repository interface in domain layer, concrete repository invoking API in infrastructure layer). And application service calls repository interface.

How to correctly use port and interfaces in a UML2 component diagram

I haven't understood well how to use port, connector and interfaces in a UML2 component Diagram.
I understand that a component can be a physical or a logical component, is the same with interfaces? For example a required import becomes a required interface in component diagram or a simple usage as in class diagram? And also I don't understand the concept of a port as an interaction point: is only a representation of enter and exit point in amicroservice?
To understand I've made two very typical scenarios in applications (I'm a java developer).
Scenario 1
A typical facade pattern where my client application needs to call several web services (rest or soap) through a facade.
I try to represent in a component diagram:
1a) is this diagram correct?
1b) Between Client and facade component is the use of interfaces correct or I only need a simple <>? Phisically ther's no interface, but only a class import, but logically even the facade component expose an API (different from web service API). Port is not needed because client and facade are not pieces of software totally indipendent, am I right?
1c) Between Facade and Services I need ports because we connect to various indipendent pieces of software (maybe not event our software). Is right?
Scenario 2
Now I made a second scenario also very typical in a java web application.
An MVC application that need to call an EJB (a remote class with an interface) for business puroposes.
My component diagram:
2a) In this case a enclosed my userInterfaces in a presentation component a made a delegation connection between various UI and the entire component. Is this the right way to use it?
2b) Between presentation and business component is the same situation of scenario1 when a I call the web services and the use of the port is needed?
If my component diagrams are wrong, please help me understand my errors and how to make a correct component diagrams for those scenarios.
This is almost ok. Your Delegate class looks superfluous. Delegation is a more abstract concept:
(sorry for that pinkish label; tool issue)
So you just draw a <<delegate>> relation from the port towards the class, component or property which inside the component will take responsibility. You can also delegate to internal interfaces as you did.
I looked up UML 2.5 for delegation. On p.189:
A delegation Connector is a Connector that links a Port to a role within the owning EncapsulatedClassifier. It represents the forwarding of requests (Operation invocations and Signals). A request that arrives at a Port that has a delegation Connector to one or more Properties or Ports on Properties will be passed on to those targets for handling.
Delegation Connectors can be used to model the hierarchical decomposition of behavior, where services provided by an EncapsulatedClassifier may ultimately be realized by one that is nested multiple levels deep within it.
As a ConnectableElement, the effective provided Interfaces (see 11.2.3) of a Port are its provided interfaces, and the effective required Interfaces are its required Interfaces. However, for a delegating Port, i.e., a Port that is at an end of a delegation Connector and is not on a role and that is not a behavior Port, the effective provided Interfaces are its required interfaces and its effective required Interfaces are its provided interfaces. Consequently a delegating Port behaves, for connection, as though it had an internal “face” that is the conjugate of its external “face.”
If several Connectors are attached on one side of a Port, then any request arriving at this Port on a link derived from a Connector on the other side of the Port will be forwarded on links corresponding to these Connectors. It is not defined whether these requests will be forwarded on all links, or on only one of those links.
There's more about ports around that page.

AUTOSAR: expressing crypto services during modelling

I'm new in AUTOSAR, I'm working on a project and my only concern is modeling (Software Components layer), without Basic Software implementation. I'm looking for a way to specify crypto information in the model (a way to specify that a specific communication has to be treated by the Crypto Service Manager). Does someone know a way to do so? Any tips or advice would be accepted.
The principle is same as with other services, model a SwcServiceDependency that aggregates a CryptoServiceNeeds. Create RoleBasedPortAssignments to indicated which PortPrototypes shall be used to interact with the Csm.
The SWC defines a way to specify the Crypto Service Needs of an SWC. This is defined in the standard/AUTOSAR_TPS_SoftwareComponentTemplate.pdf
But the actual sighing and authentication is done in the BSW by first routing incoming SecuredIPdus by the PduR to the SecOC, which will forward authentication to the CryptoStack (Csm, Cry, CryIf, CAL / CrySHE). They'll return an (authenticated) IPdu back to the PduR, which routes it up to Com, which provides you the ISignalGroups and ISignals. To transmission is just the opposite way, where the SecOC gets an IPdu and delivers back a SecuredIPdu, which is routed by PduR down to the If to the -Driver to transmit.
On the receiving side, failed authentication will, the same as other failures usually cause the IPdu to be discared to higher layers, which looks like a message was never received.
This BasicSW parts are defined in the SystemDescription, which is defined in the standard/AUTOSAR_TPS_SystemTemplate.pdf

Communication between RESTful API's on same server with NodeJS

I am building two sets of services on a website (all written in NodeJS on the server), both are using a RESTful approach. For the sake of modularity I decided to make both services separate entities. The first service deals with the products of the site and the second specifically deals with user related functions. So the first might have functions like getProducts, deleteProduct etc... The second would have functions like isLoggedIn, register, hasAccessTo etc... The product module will make several calls to the user module to make sure that the person making the calls has the privilege to do so.
Now the reason I separated them like this, was because in the near future I foresee a separate product range opening up, but will need to use the same user system as the first (even sharing the same database). The user system will use a database that spans the entire site and all subsequent products
My question is about communication between these projects and the users project. What is the most effective way of keeping the users module separate without suffering any significant speed hits. If the product API made a call to the user API on the same server (localhost), is there a signifcant cost to this, versus building the user API into each of the subsequent projects? Is there a better way to do this through interprocess communication maybe? Is simply having the users API run as its own service an effective solution?
If you have two nodes on same server (machine) then you have not bad performance in terms of network latency because both are on localhost.
Then, nodes will be communicating using a rest api, so on the underground, you will use node js sockets. You could use unix sockets instead of http sockets because are faster BUT are worst to debug, so I recommend you don't to that (but it's ok know alternatives).
And finally, your system looks like an "actor design pattern". At first glance this design patter is a little difficult to understand but you could have a look at this if you want more info about actor model pattern:
Actor model for NodeJS https://github.com/benlau/nactor
Actor model explanation http://en.wikipedia.org/wiki/Actor_model

socket.io rooms or namespacing?

I am investigating nodejs/socket.io for real time chat, and I need some advice for implementing rooms.
Which is better, using namespace or using the room feature to completely isolate grops of chatters from each other?
what is the real technical difference between rooms and namespace?
Is there any resource usage difference?
This is what namespaces and rooms have in common (socket.io v0.9.8 - please note that v1.0 involved a complete rewrite, so things might have changed):
Both namespaces (io.of('/nsp')) and rooms (socket.join('room')) are created on the server side
Multiple namespaces and multiple rooms share the same (WebSocket) connection
The server will transmit messages over the wire only to those clients that connected to / joined a nsp / room, i.e. it's not just client-side filtering
The differences:
namespaces are connected to by the client using io.connect(urlAndNsp) (the client will be added to that namespace only if it already exists on the server)
rooms can be joined only on the server side (although creating an API on the server side to enable clients to join is straightforward)
namespaces can be authorization protected
authorization is not available with rooms, but custom authorization could be added to the aforementioned, easy-to-create API on the server, in case one is bent on using rooms
rooms are part of a namespace (defaulting to the 'global' namespace)
namespaces are always rooted in the global scope
To not confuse the concept with the name (room or namespace), I'll use compartment to refer to the concept, and the other two names for the implementations of the concept. So if you
need per-compartment authorization, namespaces might be the easiest route to take
if you want hierarchically layered compartments (2 layers max), use a namespace/room combo
if your client-side app consists of different parts that (do not themselves care about compartments but) need to be separated from each other, use namespaces.
An example for the latter would be a large client app where different modules, perhaps developed separately (e.g. third-party), each using socket.io independently, are being used in the same app and want to share a single network connection.
Not having actually benchmarked this, it seems to me if you just need simple compartments in your project to separate and group messages, either one is fine.
Not sure if that answers your question, but the research leading up to this answer at least helped me see clearer.
It's an old question but after doing some research on the topic I find that the accepted answer is not clear on an important point. According to Guillermo Rauch himself (see link):
although it is theoretically possible to create namespaces dynamically on a running app you use them mainly as predefined separate sections of you application. If, on the other hand you need to create ad hoc compartments, on the fly, to accommodate groups of users/connections, it is best to use rooms.
It depends what you wanna do.
The main difference is that rooms are harder to implement.
You must make a method for join the rooms with each page reload.
With namespaces you just need to write var example = io.connect('http://localhost/example'); in your javascript client and client are automatically added in the namespaces.
Example of utilization:
rooms: private chat.
namespaces: the chat of the page.
Rooms and namespaces segment communication and group individual sockets.
A broadcast to a room or to a namespace will not reach everyone just the members.
The difference between namespaces and rooms is the following:
Namespaces: are managed in the frontend meaning the user, or an attacker, joins through the frontend and the joining and disconnecting is managed here.
Rooms: are managed in the backend, meaning the server assigns joining and leaving rooms.
The difference is mainly who manages them
To decide what to use you must decide if the segmentation should be managed in the frontend or in the backend
There can be rooms within namespaces, which helps to organize the code but there cannot be namespaces inside of rooms. So namespace is a top level segmentation and rooms is a lower level one.
Namespaces allow you to create objects with the same name, but they would be separate as they will live in different namespaces, otherwise known as scopes.
This is the same thought process you should have with Socket.IO namespaces. If you are building a modular Node web application, you will want to namespace out the different modules. If you look back at our namespace code, you will see that we were able to listen for the same exact events in different namespaces. In Socket.IO, the connection event on the default connection and connection event on a /xxx namespace are different. For example, if you had a chat and comment system on your site and wanted both to be real time, you could namespace each. This allows you to build an entire Socket.IO application that lives only in its own context.
This would also be true if you were building something to be packaged and installed. You cannot know if someone is already using certain events in the default namespace, so you should create your own and listen there. This allows you to not step on the toes of any developer who uses your package.
Namespaces allow us to carve up connections into different contexts. We can compare this to rooms, which allow us to group connections together.We can then have the same connection join other rooms, as well.
Namespaces allow you to create different contexts for Socket.IO to work in. Rooms allow you to group client connections inside of those contexts.

Resources