CQRS and DDD: File uploads - api

I'm new to the concept of DDD and CQRS and can't find a final solution how to upload images, or files in general, in a clean way.
Imagine the following scenario:
In an online portal there is a support request formular where a file (image in specific) could be attached to.
The posted data will raise a CreateSupportRequestCommand. Then the required aggregates will be loaded and changed.
I have three ideas to solve this, but I'm not very satisfied with them.
Way 1:
1. Post all data including the image (multipart) in a single request
2. Create a FileUploadCommand, which is returning the FileUploadId.
3. After that create a CreateSupportRequestCommand and pass the FileUploadId with the root data in the constructor.
Drawback: A single request will trigger two commands. In terms of CQRS one user interaction should be only one command.
Way 2:
1. Post the image to a seperate endpoint, create a temporary file and return the id or a file handle.
2. Post the formular with the attached tempfile id.
3. Invoke the CreateSupportRequestCommand with all root data including a file handle which points to the physical file.
4. Inside the command persist the tempfile into a FileUpload aggregate (by FileUploadRepository) then
5. Create the SupportRequest aggregate, assign the FileUploadId and persist.
Drawback: I handle 2 aggregates in the same command. Creating a support request is not responsible for uploading the file.
Way 3:
1. Post the image to a seperate endpoint, create a temporary file and return the id or a file handle.
2. Post the formular with the attached tempfile id.
3. Invoke the CreateSupportRequestCommand with all root data including a file handle which points to the physical file.
4. Only persist the root data to the SupportRequest aggregate. Raise a SupportRequestCreatedEvent and attach the file handle.
5. Inside the event process and assign the file handle.
Drawback: The SupportRequestCreatedEvent should not really care about a file handle.
Is there a better way to solve this?

I do not think handling File upload is a Domain Concern. The file metadata like FileContentId may be part of your domain but not the actual file upload. I would perform the file operation before the CommandHandler is executed. Probably in a middleware or perhaps before queing up the Command onto the message bus.
CreateSupportRequestCommandHandler would then only be invoking an operation like CreateSupportRequest on your aggrerate (say SupportRequest). Within that CreateSupportRequest method you will have all your business rule pretaining to the operation. SupportRequest then eventually would be saved in your repository.

Related

Is there a place where a set of code is run every time I visit a route and the output of the code is available to the module at the route?

I have a web application that hosts several tools. E.g. docx-to-pdf, pdf-to-docx, etc... each is a vue module file within the application.
When the user goes to the docx-to-pdf tool, uploads the file using a dropzone, the server's file manager will generate a uuid (I call it a module session id) and use this as the directory name to place the uploaded file and return the uuid to the browser. Then when the user clicks on 'convert', the uuid is sent with the 'convert' command and the server will perform the conversion and allows the user to download the converted file.
This works fine until I have a tool called combine-pdf and have 2 dropzones on the page. When I'm uploading file1 in dropzone1 and file2 in dropzone2 at the same time, each goes into its own directory because the server's file manager thinks they're the first file to be uploaded. Unless I complete file1's upload first before I start file2, otherwise when I try click on 'combine', the server will only have one of the two uuids and will try to combine but only find one file there.
The most logical solution I can think of would be to generate the uuid in Vue, and when I upload files to the server, it'll validate that it's a proper uuid and use this throughout the session in this module. I can put this is Vue's created hook. This is fine but I find that as me or my teammates add modules, we keep repeating this same code in every module which seems repetitive.
Is there a place where I can generate this uuid and eventually pass it to the module's data so it's write once but every module gets a new uuid?
I thought of having a parent module for all these tool modules and in this parent module I would perform this uuid generation in its created hook but this is only loaded once and not every time I visit a module.
You could move the the fileUpload function to the dropzone parent so that each dropzone component emits the file to the parent. The parent can then upload both files as an array to the server, and return an array of uuids to the client.

Retrieving all the data at once instead of calling each reference separately

Working the first time with FHIR, and I can't figure out how I retrieve all data saved as a bundle at once.
So I save a Bundle: Composition with 3 references. Everything is successful. When I call the data (GET) then I get my Composition, but the section just shows the references, so I call each on of the separate to get all the data.
Is there a better method? My method is prone to fail.
If you send a transaction or batch to the 'root' endpoint, that will cause the individual resources to be created but the batch won't be persisted. However, if you post a document bundle to the Bundle endpoint, the Bundle should be stored and retrievable as a Bundle. All that said, in FHIR, it's more typical to store individual resources and retrieve individual resources (though you can use _include, _revinclude and operations like $everything to retrieve more than one at the same time). Retrieving multiple resources shouldn't be more error-prone.
Did your Bundle save as a Bundle (POSTed to Bundle endpoint), or were the resources inside it saved separately (Bundle POSTed to root endpoint)? If it was the latter, you could check if the server supports the $document operation. If you invoke that on the Composition, the server will send you a Bundle, containing the Composition plus the referenced resources.

How to use one scenario output to another scenario without using properties files

I am working on API testing project. My requirement is to use response of one API as a response of another. I need different Feature files for each API. The challenge was to use output of one API as input to another which in my case is output of one feature file as input of another.
Also i don't want to call one feature file in another. So to achieve this currently we are using Runner class to initiate the test and using Properties file to store the responses. In the same run we are reading these properties file which act as input to another API(Feature file).
Is there any other better way to do this since we are not willing to use properties file in the framework.
Thanks
I think you are over-complicating your tests. My advice is combine the 2 calls into one scenario. Else there is no way unless you call a second feature file.

RESTful - when should I use POST and GET?

This is my WCF service, where user can find message for him.
Simple:
[OperationContract]
[WebGet(UriTemplate = "/GetMessages/{UserGLKNumber}/{UserPassword}/{SessionToken}")]
Messages GetMessages(string SessionToken, string UserPassword, string UserGLKNumber);
I have concerns about that line: {UserGLKNumber}/{UserPassword}/{SessionToken}
I have to authenticate user, before he get that messages. But with GET method, I cannot send objects, like in POST.
Is it consistent with REST pattern?
Please, clear up my doubts.
There are already posts & question about this, I am summarizing all of them
POST verb is used when are you creating a new resource (a file in your case) and repeated operations would create multiple resources on the server. This verb would make sense if uploading a file with the same name multiple times creates multiple files on the server.
PUT verb is used when you are updating an existing resource or creating a new resource with a predefined id. Multiple operations would recreate or update the same resource on the server. This verb would make sense if uploading a file with the same name for the second, third... time would overwrite the previously uploaded file.
POST everytime you are modifying some state on the server like database update, delete. GET for readonly fetching like database select.
GET: Get a collection of entries (as a feed document) or a single entry (as an entry document).
POST: Create a new entry from an entry document.
PUT: Update an existing entry with an entry document.
DELETE: Remove an entry.
Source:Difference between PUT and POST using WCF REST
Another Useful reads are:
What's the difference between a POST and a PUT HTTP REQUEST?
http://www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide
http://msdn.microsoft.com/en-us/magazine/dd315413.aspx
http://social.msdn.microsoft.com/Forums/vstudio/en-US/643e0d8b-80bb-45eb-8a84-318ac8de4497/difference-between-the-rest-verbs-put-and-post?forum=wcf
In terms of Restful services...
Post :
1. Its a secure to use in application rather than get.
2. Its not configure proxy server.
3. Big length of data restricted by web server.
4. Its not cached on browser.
5. Its take input as xml
Get :
1. Its a not secure to use in application rather than get.
2. Its configure proxy server.
3. Its use url encoding technique.
4. Its cached on browser.
5. Its a default if you are not declaring anyone.
6 Its take input as a string an returned a formatted output.

Ext js forms, models and file uploads

I would like to clarify how do ext 4 models correlate to form panels.
Suppose I have a model, e.g. "User", which has a REST proxy attached.
When I want to modify user parameters, i use form's
loadRecord( Ext.data.Model record ) : Ext.form.Basic
method, to set form's field values.
After modification, I call "updateRecord" method, to send changes from form to loaded model, and then use model's "save" method, to send changes to server. This works quite well, and seems to fit Ext MVC concepts.
Question
But, the question is: how should I conform to MVC, in case I need to upload file, while modifying user's data (e.g. avatar). According to what I learned from docs, I should switch to using form's "submit" method to send updated data so server, including the file.
In this case, I see several drawbacks:
The original model, loaded to the form, will not be updated.
If I update the model (using "updateRecord", or other way), the model will stay in dirty state, however, changes have already been sent to server.
The same proxy configuration should be applied to form, as to model, so that I would not need to change server side.
Is this a correct way of implementing file-upload through ext forms?
Is there any way to do this using model.save method, to be more MVC-stylish?
I don't think you can combine two thing together. File upload will always be something different than submitting the rest of the data. What you can do however:
Have a button to select and upload file to the server. But don't save file into the same place where you save your user (for example you can have separate file storage and save just file name into the user record)
When sending user record update to the server send new file name. This way your avatar update and other data update will be in the same transaction.