Validate existing entity in CQRS + EventSourcing. Microservice ASP.NET Core 5.0 - asp.net-core

I am currently building an app, and I would like to use micro services.
I use Mediatr for implementing a CQRS pattern and EventStore for event sourcing.
I have a problem with checking that an entity exists before creating an event of aggregate and appending it to the EventStore.
For example: I have LanguageAggregateRoot
public class LanguageAggregateRoot
{
public Guid Id {get;set}
public string Code { get; private set; }
public string Name { get; private set; }
public bool Enable { get; private set; }
public string Icon { get; private set; }
}
Field Code is unique and user can change code for language.
When I use Code field for stream id of eventstore, if the user sends a CreateLanguageCommand and ChangeCodeCommand, I need to check that the new code exists.
So I use Id field for stream id. But I don't understand how I can validate whether code field is unique?
As far as I've found out should not use query handling in command handling.
If i use client to check existed then send command to server. I think it doesn't look good. Because something/someone can request only command with out my client.
How can I do that?
Thanks for your support.

It should be fine to validate your request in your command itself.
you can use the below link for more details.
CQRS - is it allowed to call the read side from the write side?

Related

ASP.NET Core WebAPI 3.1 multiple parameters vs Complex object httpget

Not done API for a while and wanted to make sure what is the best practice to make a call when you need to pass multiple parameters in an HttpGet
Option 1
[HttpGet("getpet", Name = nameof(GetPet))]
[ProducesResponseType(typeof(PetResponse), (int)HttpStatusCode.OK)]
public async Task<ActionResult<<PetResponse>> GetById(
[FromQuery]int id,
[FromQuery]bool dogsOnly)
Option 2
use a Complex Object.
[HttpGet("getpet", Name = nameof(GetPet))]
[ProducesResponseType(typeof(PetResponse), (int)HttpStatusCode.OK)]
public async Task<ActionResult<<PetResponse>> GetById([FromQuery]PetRequest request)
public class PetRequest
{
public int Id { get; set; }
public bool DogsOnly { get; set; }
}
Any suggestions or limitation of any of the approach eg test in postman?
Any suggestions or limitation of any of the approach eg test in
postman?
The two option use the same way to test on Postman.
If your query strings would not change,the two options are all acceptable.But if you need to change the query string afterwards and the same query strings appear many times in your application,creating a PetRequest model is much better.

What is the recommended way to do partial updates with PATCH in ServiceStack?

I am building a RESTful API using the ServiceStack framework. A lot of the resources that I need to update are quite big, with up to 40 attributes per class, so I would like to do partial updates instead of replacing the entire resource. Often the client will only need to update one or two attributes out of the 40, so I would like to just send a JSON body consisting of the few attributes.
Since all combinations of attributes are possible, it is not feasible to make an "Update" class per class as suggested here: https://github.com/ServiceStack/ServiceStack/wiki/New-Api#patch-request-example
In the Microsoft ASP.NET WebAPI OData package there is a Delta class that takes a subset of a class and updates the resource based on this subset (http://www.strathweb.com/2013/01/easy-asp-net-web-api-resource-updates-with-delta/). This is the functionality I would like to have, as I will be having quite a few classes so a generic method would be best.
Basically, if I have a class
public class MyClass {
public int a { get; set; }
public int b { get; set; }
...
public int z { get; set; }
}
I would like to update a resource of MyClass with a PATCH request with body
{"a":42,"c":42}
Is there a standard or recommended way to accomplish this with ServiceStack?
Declare any scalar values in your DTO as nullable. This will allow you to determine which fields were actually sent in the request:
public class MyClass {
public int? a { get; set; }
public int? b { get; set; }
public int? c { get; set; }
// etc.
// object-type properties are already nullable of course
public string MyString { get; set; }
}
Now if a client sends a partial request, like so:
{ "a": 1, "b": 0 }
You'll be able to determine which properties were actually sent when inspecting your DTO:
myClass.a == 1
myClass.b == 0
myClass.c == null
myClass.MyString == null
etc.
Set up a PATCH route for your DTO and implement a Patch method in your service:
public object Patch(MyClass request)
{
var existing = GetMyClassObjectFromDatabase();
existing.PopulateWithNonDefaultValues(request);
SaveToDatabase(existing);
...
}
PopulateWithNonDefaultValues is key here. It will copy values from your request object onto the database entity, but will only copy properties that are not the default values. Thus, if a value is null, it won't copy it, because the client didn't send a value for it. Notice that it will copy an integer value of zero though, because we made it a nullable int, and the default value for a nullable int is considered by this method to be null, not zero. Declaring your DTO properties as nullable shouldn't cause much of a hassle in the rest of your code.
Note that this approach works easily with JSON. If you need to support XML requests/responses, you may need need to do some additional work with DataContract/DataMember attributes to insure that nulls are handled correctly.
While esker's response is fine I would like to add that it might not be enough for nullable fields - since you don't know if the deserializer or the user have created that null field.
One approach would be to peek at the raw request.
A different approach is to ask the user to provide additional request (querystring) parameter to clearly specify which fields to patch.
Something like: patch_fields=name,description,field3
The bonus of that approach is that the end user has more control over the patching and is not overriding a value by mistake (because he used the original entity and forgot to clear some fields)

WCF DataContract Versioning

Alright here goes nothing. After reading Best Practices on Service Versioning and Data Contract Versioning (http://msdn.microsoft.com/en-us/library/ms733832.aspx) I mostly understand how its all done. I am planning to use Agile Versioning for Data Contracts but cant figure out what the difference or better practice is between Creating a WorkRequestV2 to add new properties or just adding the new properties to WorkRequestV1. Now I tried doing both ways and it worked but when I do create WorkRequestV2 I have to modify ServiceContractor to use WorkRequestV2 why do this rather than just adding properties to WorkRequestV1? What is the difference?
The Example I looked at was here (http://msdn.microsoft.com/en-us/library/ms731138.aspx)
CarV1 and CarV2 why not add HorsePower to CarV1 and not have to create a whole new Contract.
[DataContract(Name = "WorkRequest")]
public class WorkRequestV1 : IExtensibleDataObject {
[DataMember(Name = "workrequest",Order=1,IsRequired=true)]
public int workrequest { get; set; }
[DataMember(Name = "CQ")]
public string CrewHeadquarter { get; set; }
[DataMember(Name = "JobCode")]
public string JobCode { get; set; }
[DataMember(Name = "JobType")]
public string JobType { get; set; }
[DataMember(Name = "Latitude")]
public string Latitude { get; set; }
[DataMember(Name = "Longitute")]
public string Longitute { get; set; }
private ExtensionDataObject theData;
public ExtensionDataObject ExtensionData {
get {
return theData;
}
set {
theData = value;
}
}
}
Have another read of the Data Contract versioning (your second link)
Here is a quote from that page:
Breaking vs. Nonbreaking Changes
Changes to a data contract can be
breaking or nonbreaking. When a data contract is changed in a
nonbreaking way, an application using the older version of the
contract can communicate with an application using the newer version,
and an application using the newer version of the contract can
communicate with an application using the older version. On the other
hand, a breaking change prevents communication in one or both
directions.
For your case, adding some additional properties is a non-breaking change. You can quite safely add the properties to the existing data contract rather than create a new one, as long as you don't have strict schema validation (such as the new properties don't have 'required' marked on them)
Old clients communicating with new services still continue to work, values of the new properties will remain the default value. New clients communicating with old services will also work, as the new properties will be ignored.
But as you can see, you will run into the problem of how can you ensure new clients communicate with new services, and old clients with old services? If this isn't an issue, then you don't have a problem. Otherwise you may need to introduce a new data contract.
Further reading:
MSDN Service Versioning
IBM Best practice for Web service versioning
Oracle Web services versioning
What are your WebService Versioning best practices?

WCF - Exposing parameterized constructor

I have a WCF DataContract called RecipientDto defined as:
[DataContract]
public class RecipientDto
{
[DataMember]
public string Name
{
get;
private set;
}
[DataMember]
public string EmailAddress
{
get;
private set;
}
public RecipientDto(string name, string emailAddress)
{
Name = name;
EmailAddress = emailAddress;
//Initialize other property here
}
}
I want to have constructor of RecipientDto being exposed to the client as it involve some basic initialization of other properties (not shown here).
Please guide how can I achieve this.
Thank you!
You cannot achieve that unless you share assembly with your DTOs between client and server. Metadata (WSDL + XSD) can describe only data transferred by DTO. They cannot describe any logic defined in DTO on service side.
What you could do is the create a second source file for the RecipientDto class, that contains a second declaration of the class with the "partial" keyword. Add your constructor to it and include that file in your client project using Visual Studio's "Add Link" functionality available on the "Add existing item" dialog. If you only need that constructor on the client then just define that second source file directly in the client project.

Send custom data as object using WCF

In my latest project, I wish to send custom data as an object using WCF. Reason for this is that I won't have to update each client when a new data class is introduced.
However, when I try to send this data, it never arrives at the client side.
To give a short example:
A custom class:
[DataContract]
public class MyData
{
[DataMember]
public string Name { get ;set; }
[DataMember]
public id Value { get; set; }
public MyData(string name, id value)
{
this.Name = name;
this.Value = value;
}
}
When I want to send this to the client, I use:
object obj = new MyData("test",1);
service.SendDataToClient(obj);
The client never receives this event from the service when I send it as object. However, when I send it as MyData instead of object, it works as it should. How can I send this as object?
If you want to send custom data the easy way is using XElement instead of object. Another approach is defining all possible transfered types by ServicKnownTypeAttribute or creating generic resolver (in such case you must share contract assembly between client and service). Check this great article.