The generator is target to generate controllers and services for nestjsx/crud and nestjs/swagger based on typeorm entities. You will only need to draw typeorm entities and their relationships, the rest will be handled by the tool automatically. Features:
- Support embedded entities (classes with stereotype
fields
). - Support all kinds of entity relationships (even trees).
- Support cross module references.
- Generate ready to use CRUD APIs and Swagger Docs.
The followings are entities borrowed from Salesforce CRM platform. As you can see, there are many-to-many, many-to-one and one-to-many relationships etc. The AddressFields
, SystemFields
classes are embedded entities with stereotype fields
. We will dive into details later on.
In order to support the above features, there are a few rules need to be followed. Some are self invented terms such as fields
stereotype for embedded entities. Although it sounds complex, it is easy to use with the following main steps in mind:
- Create an empty StarUML project
- Add node_modules package automatically
- Draw entity relationship class diagram manually
- Add crud services and controllers automatically
- Generate nestjs code automatically
As you can see only the 3rd step requires manual configuration. The library currently only runs positive test cases, and complex class/interface inheritances have not been tested. However for just entity relationship diagrams, the current implementaion is sufficient.
If the "Install From URL.." option does not work for you, by putting the github project url into the text field. Please directly download the soruce code and put the staruml-nestjs
folder under the following directory accordingly.
- MAC OS:
/Users/<user>/Library/Application Support/StarUML/extensions/user
- Windows:
C:\Users\<user>\AppData\Roaming\StarUML\extensions\user
- Linux:
~/.config/StarUML/extensions/user
For a quick start, please just download the sample Salesforce.mdj file directly. To generate your first NestJS module, please follow these steps:
- Double click to open Salesforce.mdj.
- Click Menu Item: Tools => NestJS => Generate Code...
- Select any module (the package with
<<Module>>
stereotype), such as app or sales. - Press OK and select a directory to output the generated source codes.
- The red cube represents a StarUML project, similarly to NodeJS/NestJS project root folder where package.json file resides.
- The Model (folder icon with a triangle in it) is equivalent to an
src
folder in NodeJS/NestJS world. - The green icon named
Main
is the class diagram.
- Click menu item: Tools => NestJS => Add Meta Class...
- Select the red cube StarUML project, and press OK.
- The
node_modules
package will be generated under the project. These are mainly used as stereotypes during entity and relationship creation.
Module is just a StarUML package with stereotype Module
. StarUML package is the fundamental element to organize classes. Each package with/without stereotype will be treated as a folder. And the package name will be directed used as the folder name. So we don't follow com.nestjs.package
java naming convention for the package names. During the generation, a name-of-something.module.ts
file with proper import and declaration will be created for you. Please follow the following steps to create a module:
- Right click on Model.
- Click Add => Package.
- Rename Package to
app
or any appropriate module name. - Assign
<<Module>>
stereotype by clicking the magnifying glass icon besides the stereotype field. - Type
Module
to search for the classModule
undernestjs/common
package. Select it and press OK button. - And make sure there is a yellow class icon besides the stereotype selected. If you type the
Module
string directly into the stereotype text field, the class icon won't appear.
Entities are just plain UML classes with stereotype Entity
. The generated entity file name will look like name-of-something.entity.ts
. Note: there will be corresponding model classes generated for every entity classes implicitly. The model class name will be the entity class name suffixed with Model
. The generated model file name will look like name-of-something.model.ts
.
- In order to add new Entity classes later, let's create a new package
entities
under the module we created above. This is for better organize the generated entity class files. - Right click the
entities
package created above. - Click Add => Class.
- Use
Entity
class as its stereotype. Please use the magnifying glass to search the class as we did for modules. And make sure the yellow class icon is present besides the stereotype selected. - Drag and drop the newly created class onto the diagram, so we can visually add columns later.
embedded entities are just plain UML classes with stereotype FieldSet
. The class name should be suffixed with FieldSet
as well. The generated class names will look like name-of-something.fieldset.ts
.
- Right click the
entities
package created above. - Click Add => Class, and rename it with
FieldSet
suffix. - Just type
FieldSet
in the stereotype text field. Caution: there is no corresponding meta class for FieldSet. - Drag and drop the newly created class onto the diagram, so we can visually add columns later.
All valid typeorm data types or FieldSet class types can be used as column data types, such as string
, number
, boolean
, or Date
etc. When referencing FieldSet
as data types, the correct class type can be automatically resolved after typing. As you can see the yellow class icon is present besides the type property. Please double check this if any data type reference is not imported for the entity after code generation. The FieldSet
class can resides in <<Module>>
package other than the current entity module, such as a shared module.
Please add the ?
mark after the name for optional columns. In the following example, industry is an optional column.
Check the isID
checkbox for typeorm PrimanyColumn
. And also check the isDerived
checkbox if it is a typeorm PrimanyGeneratedColumn
.
Note: All relationships are UML associations, and must be drawn in the direction from Child to Parent.
|---------| |---------|
| Parent | | Child |
|---------|-----------------|---------|
|---------| |---------|
- Just draw a plain association from child to parent class.
|---------| |---------|
| Parent | 0..*| Child |
|---------|-----------------|---------|
|---------| |---------|
- Just draw a plain association from child to parent class.
- And change the multiplicity at child end to a range above 1. For simplicity, let's just use
0..*
.
|---------| |---------|
| Parent |0..* 0..*| Child |
|---------|-----------------|---------|
|---------| |---------|
- Just draw a plain association from child to parent class.
- Change the multiplicity at both child and parent end to a range above 1. For simplicity, let's just use
0..*
.
|---------| |---------|
| Parent | 0..*| Child |
|---------|<----------------|---------|
|---------| |---------|
If you don't want the Parent class have an array field referencing its children, but Child class have a field referencing its parent instance, or vice versa. Please disable the navigable at the Child end. Since we always draw from Child to Parent, it is the end1.navigable checkbox that needs to be unchecked. By doing this, the association at parent end will turn into an arrow.
Self referencing is allowed, and must be one-to-many/many-to-one relationship. If typeorm tree structure is needed for the self referencing hierarchy relationship. Please assign the stereotype of the association to the Tree
class under typeorm
package.
By default materialized-path
strategy will be used to establish the tree structure. If other strategies are used, please specify it as the association name. For a complete tree establish strategy, please refer to typeorm Tree Entities document.
- Click menu item: Tools => NestJS => Add Crud Class...
- Select top or sub
<<module>>
package containing entities. - Press OK, the services and controllers will be generated under their corresponding folders.
- The services and controllers package in above screenshot are automatically created to organize the newly added classes. However, entities are not required to be under the entities folder, they can be anywhere within the
<Module>
package.
- Click Menu Item: Tools => NestJS => Generate Code...
- Select any module (the package with
<<Module>>
stereotype). - Press OK and select a directory to output the generated soruce codes.
In order to run the generated code, we have to put them into a NestJS project with additional npm packages installed. Please refer to official docs on how to nestjsx/crud and nestjs/swagger.
"@nestjs/swagger": "^3.1.0",
"@nestjsx/crud": "^4.2.0",
"@nestjsx/crud-typeorm": "^4.2.0",
"class-transformer": "^0.2.3",
"class-validator": "^0.10.2",
"swagger-ui-express": "^4.1.2",
Please don't forget to import the generated modules. And the main.ts
should look like the followings:
import { CrudConfigService } from '@nestjsx/crud';
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(
AppModule.forRoot(),
);
const options = new DocumentBuilder()
.setTitle('API Document')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('docs', app, document);
await app.listen(process.env.PORT || 3000);
}
bootstrap();
MIT