jhipster / jhipster-core

JHipster Domain Language, used by JHipster UML and JDL-Studio to generate entities
Apache License 2.0
346 stars 116 forks source link

JDL Roadmap #277

Open deepu105 opened 5 years ago

deepu105 commented 5 years ago

To make JHipster more JDL centric and to truly achieve scaffolding as Code I envision the below. Detailed explanation of the vision is in this mailing list entry, this ticket only covers the JDL part

If everyone agrees, I would like to drive this for v6

Note: This is not addressing the side by side or code upgrade issues as I believe they need to solved through architecture of generated code and from the generator rather than through JDL, and I don't want to bring in that discussion here. It will be discussed in the mailing list entry

For a detailed discussion about the rationale behind some of the considerations check these older issues #141 and https://github.com/jhipster/generator-jhipster/issues/6275

Entities

current

@paginate(pagination)
@service(serviceImpl)
entity MyEntity {
    age Integer
    ...
}

enhanced

Entities can be defined at

  1. File level: This needs to be declared in application block to be included in case of JDL with apps, for legacy entity only files the usage remains as it is today
  2. Inside application blocks: in this case they are generated only for that application
  3. Abstract entities will not be generated, and when extending properties with same key, it will be overwritten if re-declared in the child.
// Implies entity is abstract and will only be generated when referred from an application
abstract entity MyBaseEntity {
    name String
    ...
}

@paginate(pagination)
@service(serviceImpl)
entity MyEntity extends MyBaseEntity {
    age Integer
    ...
}

Service

Services can be abstract or concrete, same rules as entity.

  1. File level: This needs to be declared in application block to be included in case of JDL with apps, for service only files the usage remains similar to that of entity only JDL and can be used in monolithic apps
  2. Inside application blocks: in this case they are generated only for that application
  3. Abstract services will not be generated, and when extending methods with same name, it will be overwritten if re-declared in the child.
  4. Service methods can be only done from JDL and there won't be support in generator CLI
// Implies service is abstract and will only be generated when referred from an application
abstract service AService {
    // only generates simple method skeletons
    Customer findByName(String name)
}

service BService extends AService {
    ...
    Product calculateTax(String name, Integer cost, ...)
}

Application

current

application {
    config {
        ...
    }
    entities A, B
}

enhanced

BASE_PORT 8080 // common constants

// doesn't generate anything, can only be used in concrete definitions like below
abstract config MyAppConfig {
    baseName foo
    ...
    serverPort BASE_PORT
}

application {
    config extends MyAppConfig
    entities A, B
    services BService
}

application {
    config extends MyAppConfig {
        baseName bar
        ...
        serverPort (BASE_PORT + 1)
    }
    entities C, D

    entity MyEntity {
        ...
    }
    relationship ManyToMany {
        C{d} to D{c}
    }

    services BService
    service MyOnlyService {
        Customer findByName(String name)
    }

    paginate * with infinite-scroll
    service * with serviceImpl
}

Deployments

Already WIP: #276. Deployments can be declared so that their configuration etc are generated. An application can declare multiple deployments

deployment {
  deploymentType docker-compose,
  appsFolders [foo, bar],
  directoryPath "../",
  serviceDiscoveryType eureka,
  dockerRepositoryName "test"
}

Other improvements

  1. JDL file import within another file, this will help to modularize JDL when it grows. Imports will be at the beginning of the file and only with relative path from the parent
    import commonConfig.jdl             // import common configuration
    import myMicroservice1JDLFile.jdl   // import microservice 1
    import myMicroservice2JDLFile.jdl   // import microservice 2 and so on
    import deployment/docker.jdl        // import docker deployments setup
  2. Basic arithmetic and string operations for constants
BASE_PORT 8080

serverPort (BASE_PORT + 1)

APP_NAME myApp

baseName (APP_NAME + "Service1")
colameo commented 5 years ago

what about having also a way to implement the generation gap pattern like this:

The idea behind is that developers could enhance the concrete class with their own code without losing the manually entered code when regenerating.

Of course, they would also be able to overload the generated code in the abstract class partially or completeley which gives developers the maximal flexibility. Obviousely, methods that for what every reason we would not allow to overload must be declared as private.

colameo commented 5 years ago

...and btw, this would also work with inheritance, because:

deepu105 commented 5 years ago

@colameo that's the idea but I wouldn't want to go too far, the extends in JDL will only extend the config of JDL and will not create extends in the output code. Instead of annotating entities as @incomplete it could be an application level property to enable the behavior as you would want to edit most of your entities anyway. The fine grain control can be a later feature. I would like to get an MVP first and then improve it

deepu105 commented 5 years ago

@colameo I have talked about that in the mailing list btw

CoderYellow commented 3 years ago

Any progress on Inheritance? It is a great feature.