I have a question about tracking activity and where it belongs.
With a lot of my domain commands, you also might want to track the activity and modifications made by users to a particular context or object.
For example:
lets say we have a items domain/context where we can create and edit items. Users are going to make requests to the api to do this. We might want to track who created an item and an modifications made to it.
In a typical CRUD model, you'd probably find the created by field in the domain object/table
Something doesn't feel right when using DDD to have the activity in the domain object. The activity log feels like a general service that would cross many boundaries? Is it right to have the activity log of who changed what in the domain object. It would feel quite clean and focused without it. The activity logging seems specific to the applications case, not the domain?
So:
Should the activity tracking be in the domain object?
If it shouldn't how do you go about handling this in one command/request. I keep hearing people saying about you should only touch 1 boundary in a command/request.
I would think of this activity log as any other piece of data. You would put it together with the business logic around it. Why do you need this information in the first place? Is your items context going to implement business logic that needs the activity log? If not, then I'd say it doesn't belong in that context.
If what you are trying to achieve with this log is some data analysis that needs the activity from several contexts, then I would say publish events from your business operations (every time a user does something with one of the contexts) and have your activity tracking context listen to them and store the activity in a way that serves this purpose.
If, instead, your items context needs to apply some sort of logic, based on the past activity, then keep it in that context in a format that allows you to implement this business logic.
It's also possible that you actually need both. Some context might just publish the events and not store the activity, while others will publish the events and also track the activity for their own internal needs.
Related
For the first i want to sorry for my english. I'm learning domain driven design and trying to implement some concepts in an application i'm working on. My task is not so complex to fully implement DDD on all the levels but i really like it's principles and the core idea and try to use it.
Lets say app is selling books. So i have a Book entity and BooksCollection or BooksRepository. I'm working on frontend and that collection or updates to it is coming from server. And i want to represent it on BooksScreen in BooksList which consists of BookCard. Press on that card for the first calls something like selectBook which changes the selectedBookId in collection and for the second navigates user to BookDetails screen where the data of selected book is represented and the user can do some actions related to domain logic.
The first question is where do i put the loading state of that BooksCollection and according actions to change it ? Loading state is not a domain logic as i understand, it's not an entity status like "todo done" or something. But i need to show a loading indicator in the UI list when the collection updates, error for loading error and success respectively.
And the second is where do i put the the same loading state for single Book ?
I separate it cause for collection i may store that state in some application related class e.g. "BooksScreenState" or something with less stupid name. But what if i decide to show state for each specific card in the UI e.g. that specific card failed to load. Or i have a single User in app and his data can be loading, he can be authorized or not et cetera.
So i can summarize that to something like "how to connect domain and application logic to present a UI".
An interesting question. I don't usually think to apply DDD to the UI level because for the most part, the UI isn't full of business rules and also because I mostly use reactjs and UI frameworks are usually very prescriptive and don't allow much in the way of flexibility.
To answer your question though: If you did want to get a "loading" status in your UI (that's designed using DDD), it'd have to be attached to a "View" object or some representation of the "view"; because that fits the UL (ubiquitous language) better. Think of how you have described it in a little snippet of your question:
But what if i decide to show state for each specific card in the UI
That means your card is an object (entity or value object) that has a enumerable state of loading, loaded, error. You can queue on that object in your UI to display a desired representation of that field.
So, both your questions have essentially the same answer. Since you are loading the UI, your state is only relevant to UI objects and not entities that are in the domain model like "Books" that are represented in the backend. Even if you had a front-end representation of "Books" - like in javascript for example - having a loading state still makes more sense in the view object in the view layer.
Note that there's some simplification/flexibility to this answer because it's also valid for your design to have a View that's an aggregate that contains a Books. Those Book objects could have a "loading" state on them. All of this is still restricted to the UI layer though and such an aggregate and it's specific design will depend on the flexibility your UI-framework allows.
I've created a solution where I created an authorization object which controls what can a user handle or watch in the program. This authorization object is defined with 3 elements:
Process
Activity
Material group
Through transaction 'PFCG' the BC creates the profiles according the requests that users make to have permission to some module of the program. For example, a user or a group of users will access to process 'A1' (Data update), activity '01' (Aproval) and material group 'A0A00001'. This means that these users could only aprove for process 'A1' the data for material group 'A0A00001'.
My problem here is that managers of the areas have told me that they feel uncomfortable making requests to the BC for permissions because they think that they should manage those profiles, and if they want to change those permissions they would like to have the control of them directly instead of making requests.
This is a situation where I don't know what to do, I have thought that I would make Z tables and a Z program to emulate those permissions exactly as they are handled now with transaction 'PFCG' but I feel like I'm reinventing the wheel.
Another thing that I have thought is to create a Z program that would be a layer of transaction 'PFCG' to automate the profiles for this authorization objects but in this case I don't know where to start because I would have to investigate if is there a BAPI for creating profiles and how to manage all the issues related with this management.
The other thing is leave it like that and do nothing, but sincerely I don't know what to do.
Do you have any suggestion on this issue? What can be done in this situation?
I'm using Vuex & Vuejs (flux architect) for a CRM single page application.
In contact page i'm showing a list of tasks related to current contact and at sidebar i have a list of task for current logged in user.
These collection of tasks are kept in separate stores. I don't know which is best solution:
After update post request search in both list and update task object if it's present and mutate state.
After update post request use an global event bus and each store should listen and update task object if needed.
It really depends of your requirements, but one thing I can tell is that using two separated stores + bus is defeating the whole purpose of Redux.
If the tasks in your application share the same scope and can be assigned to you or other users that you may be visiting/managing, you can have all the tasks from your scope (your team, for example) and display it on different places using different getters with Array.filter functions.
If the number of tasks is too big to have it all loaded, I'd approach it doing one single tasks list in the store, being populated from a single url.
ie:
- Give me all the tasks I have + the tasks of current user I'm managing
- Give me all the tasks I have + the tasks that matches this search
Although this can get messy if the requirements are more complicated and can get confusing. But try to structure your application with one single store if possible and avoid bus, as it is only recommended for small size applications.
I am working on one chatroom [all to all] application in Elixir using OTP Genserver and getting messages from js client as user gets registered with their names as first phase. Now, just bit not sure what would be the best approach to store these names at my elixir server somehow and send regular updates to client with list of users online or database storage. Please suggest the best approach.
I agree with bitwalker that ETS is a good fit.
Here's a short summary of what I did in production. It wasn't a chat server, but a server push with a couple of thousand of users connecting via long polling. Pushed data was divided in some 50 categories, and users were able to choose which ones they want. At peak times the server pushed new messages each 2 secs, and processed > 2000 reqs/sec.
Essentially, I kept a gen_server for each user, where I held pending messages and user's configuration (basically a list of selected channels). This was beneficial with long polling, since user's data is decoupled from the user's request, so the data remains while requests are transient. However, I think this approach is also good for permanent connections, such as websockets, since there might still be occasional disconnections, and keeping a more stable user's data gives you a chance of resuming after reconnect.
Obviously, when a request arrives, you need to find the user specific process, and for this, ETS is a good fit, since you don't have a single process bottleneck. Instead of manually working with ETS, I'd recommend using gproc in conjunction with via tuples. Basically, when starting a user's gen_server, you can provide name: {:via, :gproc, {:n, :l, key}} where key is some custom key (arbitrary term) you make based on your internal user's id(:n and :l indicate a unique name on the local node). You can then use that same via tuple when issuing calls/casts, and gen_server will use gproc to find the corresponding process.
Finally, you need to have some timeout/disconnect logic to cleanup user processes. In my case, I simply terminated a user's process if there was no activity from the web layer (no end-user came for data in some time). Gproc will automatically remove entries for terminated process from its internal ETS table. It's probably best to supervise user processes under a temporary strategy.
I realize all of this is still a bit vague, but I hope it makes some sense. Keep in mind that this is not the ultimate pattern (there's no such thing of course), but I think it's a reasonable first attempt.
You may also want to take a look at Phoenix web framework that has an interesting pub-sub facility in form ofTopics. I didn't try this out myself yet, but it seems interesting, and may even simplify some of the stuff I discussed above, or at least help for pushing notifications from chatroom to all users.
Sounds like a good use case for ETS.
A simpler approach might be to use an Agent to store the online users information, but it depends quite a lot on what you need from the storage mechanism you choose.
I'm trying to wrap my head around how to design a RESTful API for creating object graphs. For example, think of an eCommerce API, where resources have the following relationships:
Order (the main object)
Has-many Addresses
Has-many Order Line items (what does the order consist of)
Has-many Payments
Has-many Contact Info
The Order resource usually makes sense along with it's associations. In isolation, it's just a dumb container with no business significance. However, each of the associated objects has a life of it's own and may need to be manipulated independently, eg. editing the shipping address of an order, changing the contact info against an order, removing a line-item from an order after it has been placed, etc.
There are two options for designing the API:
The Order API endpoint intelligently creates itself AND its associated resources by processing "nested resource" in the content sent to POST /orders
The Order resource only creates itself and the client has to make follow-up POST requests to newly created endpoints, like POST /orders/123/addresses, PUT /orders/123/line-items/987, etc.
While the second option is simpler to implement at the server-side, it makes the client do extra work for 80% of the use-cases.
The first option has the following open questions:
How does one communicate the URL for the newly created resource? The Location header can communicate only one URL, however the server would've potentially created multiple resources.
How does one deal with errors? What if one of the associons has an error? Do we reject the entire object graph? How is that error communicated to the client?
What's the RESTful + pragmatic way of dealing with this?
How I handle this is the first way. You should not assume that a client will make all the requests it needs to. Create all the entities on the one request.
Depending on your use case you may also want to enforce an 'all-or-nothing' approach in creating the entities; ie, if something falls, everything rolls back. You can do this by using a transaction on your database (which you also can't do if everything is done through separate requests). Determining if this is the behavior you want is very specific to your situation. For instance, if you are creating an order statement you may which to employ this (you dont want to create an order that's missing items), however if you are uploading photos it may be fine.
For returning the links to the client, I always return a JSON object. You could easily populate this object with links to each of the resources created. This way the client can determine how to behave after a successful post.
Both options can be implemented RESTful. You ask:
How does one communicate the URL for the newly created resource? The Location header can communicate only one URL, however the server would've potentially created multiple resources.
This would be done the same way you communicate linkss to other Resources in the GET case. Use link elements or what ever your method is to embed the URL of a Resource into a Representation.