Closed sunilk-m closed 1 year ago
Hi @sunilk-m, thanks for reporting!
I'm not sure if we should go for such a generic solution since the tactic DDD syntax is based on Sculptor and already supports many of your needs (let me know if I'm wrong).
It is possible to define the database table name as follows:
Entity Customer {
aggregateRoot
databaseTable = "Customer" // see here
String firstname
String lastname
}
... its also possible to define the column name on attribute level:
Entity Customer {
aggregateRoot
databaseTable = "Customer" // see here
String firstname databaseColumn = "firstname"
String lastname databaseColumn = "lastname"
}
As you can see here the attribute rule supports other keywords such as required, nullable, notChangeable, etc. The only thing that is not available is unique.
Maybe we could just add a corresponding unique keyword? Would that be sufficient or do you have other requirements that are missing @sunilk-m? I get the idea of the generic solution that would allow adding any arbitrary additional attributes but I want to challenge if its really needed. What do you think @socadk?
Hi Stefan Thanks for your reply. I will add one more scenario that I am currently working on. I have a read model which needs to be persisted into a graph database and I am currently on evaluating arangodb. In this case I have 2 types of entities i.e vertices & edges where vertices are nodes in the graph and edges connect the nodes. So in context mapper if I have to create such a model, I need some way of marking some entities as vertices and others as edges. The workaround I have today is to use the databaseTable attribute and hint to provide this additional meta information. For example if I have to model airports and the connecting flights information using graphs I will do something like this. Entity Airport { aggregateRoot
databaseTable = "type=VERTEX, name=AIRPORT"
String name .... } Entity Flight { databaseTable = "type=EDGE, name=FLIGHTS" -Airport from hint="FROM" -Airport to hint ="TO" }
My primary use case for using context mapper is to capture the domain model and also use that model to drive generation of code so that right patterns and best practices can be enforced. In order to generate code I will need some additional meta information and that's the reason I was proposing a generic solution. The solution I proposed is widely used in case of code generation using UML and I have myself used it a lot of times in the past.
So my answer to the question " already supports many of your needs (let me know if I'm wrong)." is - it supports through workarounds but it would be great if a uniform approach is available supported by the tool :).
Regards Sunil
On Fri, Jan 15, 2021 at 2:25 AM Stefan Kapferer notifications@github.com wrote:
Hi @sunilk-m https://github.com/sunilk-m, thanks for reporting!
I'm not sure if we should go for such a generic solution since the tactic DDD syntax is based on Sculptor http://sculptorgenerator.org/ and already supports many of your needs (let me know if I'm wrong).
It is possible to define the database table name as follows:
Entity Customer { aggregateRoot
databaseTable = "Customer" // see here
String firstname String lastname }
... its also possible to define the column name on attribute level:
Entity Customer { aggregateRoot
databaseTable = "Customer" // see here
String firstname databaseColumn = "firstname" String lastname databaseColumn = "lastname" }
As you can see here https://github.com/ContextMapper/context-mapper-dsl/blob/d4ae1ba982702ac48773de968d9558a9eb22fbec/org.contextmapper.dsl/src/org/contextmapper/tactic/dsl/TacticDDDLanguage.xtext#L365 the attribute rule supports other keywords such as required, nullable, notChangeable, etc. The only thing that is not available is unique.
Maybe we could just add a corresponding unique keyword? Would that be sufficient or do you have other requirements that are missing @sunilk-m https://github.com/sunilk-m? I get the idea of the generic solution that would allow adding any arbitrary additional attributes but I want to challenge if its really needed. What do you think @socadk https://github.com/socadk?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ContextMapper/context-mapper-dsl/issues/278#issuecomment-760470185, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANHNC3L6M4MCKAJZSMQM7UDSZ5K3PANCNFSM4V5N5IZQ .
Hi, while I can see the need for such generic solution/uniform approach, I agree with @stefan-ka 's reasoning above.
Sculptor also has the docstrings (doc=STRING)?
that can carry such information (note: its originally indented usage is different, see here).
I do like the proposal for a new unique
keyword, though.
@sunilk-m
FYI: the unique
keyword is now supported (with release 6.4.0).
I implemented the suggestion of @socadk to use the doc statements. This CML:
BoundedContext CustomerManagementContext {
Aggregate Customers {
Entity Customer {
aggregateRoot
"lives at" - @Address address
* void anotherMethod("uses" @Name name);
"needs something" * @ReturnTypeEntity yetAnotherMethod();
}
Entity Address {
String name
}
ValueObject Name {
String first
String last
}
Entity ReturnTypeEntity {
int i
}
}
}
@startuml
skinparam componentStyle uml2
package "'Customers' Aggregate" <<Rectangle>> {
class Customer <<(A,#fffab8) Aggregate Root>> {
Address address
void anotherMethod(Name name)
ReturnTypeEntity yetAnotherMethod()
}
class Address <<(E,DarkSeaGreen) Entity>> {
String name
}
class Name <<(V,DarkSeaGreen) Value Object>> {
String first
String last
}
class ReturnTypeEntity <<(E,DarkSeaGreen) Entity>> {
int i
}
}
Customer --> Address : lives at
Customer --> Name : uses
Customer --> ReturnTypeEntity : needs something
@enduml
I.e.
This is exactly what I need (i.e. the ability to annotate relations between entities in a way that is readable for non-technical domain experts).
The syntax is a bit peculiar like this, but it works. What do you think? Should I prepare a pull request?
Sorry, reading back I see that @sunilk-m's usecase was rather different. I have no interest in code generation, I am solely using context-mapper as a modeling tool. As such I found it useful to make the generated diagram more naturally readable. How to proceed?
Hi @StevenVanDijk
Thank you very much for your work! I like the idea... Would be nice to have a PR so we can also play around with it a bit. Could you create one?
What do you think @socadk?
Here is the PR: https://github.com/ContextMapper/context-mapper-dsl/pull/319
@StevenVanDijk, we released v6.7.0 today which includes your contribution ;) https://contextmapper.org/news/2022/12/02/v6.7.0-released/ Thanks again for this! Therefore, I'll close this issue now. Best regards, Stefan
Annotation provide the ability to extend the language without having to modify the grammer and can be very valuable for generating code from the model by providing the appropriate guidance to the generator. It should be possible to add annotation to any element in the model. The example below describes in more detail. From the model we can provide the annotation as shown below. The @Table/@Document can be used on Entity and if JPA classes are generated then it can be used to drive the generator to generate the appropriate annotation on the JPA class. Similarly the @Unique annotation can be used to mark an attribute as unique. The corresponding attribute in the generated JPA class will be marked as unique. To define a combination of unique attribute we can use @Unique annotation with the same name.
BoundedContext VendorManagement { .... Aggregate Vendor { @Table/@Document(name="vendors") Entity Vendor { String id key @Unique(name= "") String name String description } } ... }
The corresponding generated JPA class might look like this in case of table @Entity public class Vendor { ... @Id private String id; @Column(unique=true) private String name; private String description; ... }
The corresponding generated JPA class might look like this in case of Document (eg Arangodb) @Document("vendors") public class Vendor { ... @Id private String id; private String name; private String description; ... } These are basic examples, in case of graph db storage we can also define entities as nodes and edges to define the vertices and edges by using appropriate stereotypes.
In order to support annotations, context mapper grammer will have to be enhanced to define annotations on each of the modeling elements. The supported annotation should be defined separately in a different file which can be reused across teams and can also be used to validate the usage. The annotation can be defined using the following format <name>
This information can be used for validations also.
An option should also be provided to hide the annotation by default and can be displayed only if user is interested in viewing those details
Alternative is to specify this externally as additional metadata information to guide the generator but this leads to duplication which can be avoided by providing support in the tool itself.