Asynchronous Single Page Applications without a Line of HTML or Javascript. Or why D is just awesome Robert ”burner” Schadek May 5, 2016 DConf
Javascript and HTML are awesome • No explicit types • Variables may be undefined • Repetition repetition repetition • No templates • No compile time function execution • No compile time 1
Goals • Retain type-information of data from DB to Client’s Browser 3
Goals • Retain type-information of data from DB to Client’s Browser • Keeping things DRY 3
Goals • Retain type-information of data from DB to Client’s Browser • Keeping things DRY • Performance 3
Goals • Retain type-information of data from DB to Client’s Browser • Keeping things DRY • Performance • Get things done 3
Vibe.d and Diet
Vibe.d • Powerful asynchronous I/O and web toolkit for D • Uses Fibers and Threads 4
Vibe.d • Powerful asynchronous I/O and web toolkit for D • Uses Fibers and Threads • n → m mapping • yield() • async IO 4
Vibe.d • Powerful asynchronous I/O and web toolkit for D • Uses Fibers and Threads • n → m mapping • yield() • async IO • async DB connectivity for MongoDB, Redis, MySQL • You don’t need to care about async • Web interface generator • REST interface generator 4
REST Interface Generator i n t e r f a c e MyAPI { // GET /weather −> responds {” text ”: ” . . . ” , ” → temperature ”: . . . } Weather getWeather () ; } 5
REST Interface Generator i n t e r f a c e MyAPI { // GET /weather −> responds {” text ”: ” . . . ” , ” → temperature ”: . . . } Weather getWeather () ; } c l a s s MyAPIImplementation : MyAPI { auto weather = [ ”sunny” , ” rainy ” , ” cats and dogs ” → , ”snow” ] ; Weather getWeather () { return Weather ( weather [ uniform (0 , weather . length ) ] , uniform ( −10 ,30) ) ; } } 5
REST Interface Generator auto router = new URLRouter ; router . get ( ”/” , staticTemplate ! ” index . dt” ) ; router . get ( ”/main . html” , staticTemplate ! ”main . dt” ) ; router . r e g i s t e r R e s t I n t e r f a c e !MyAPI(new → MyAPIImplementation , r e s t s e t t i n g s ) ; 6
REST Interface Generator auto router = new URLRouter ; router . get ( ”/” , staticTemplate ! ” index . dt” ) ; router . get ( ”/main . html” , staticTemplate ! ”main . dt” ) ; router . r e g i s t e r R e s t I n t e r f a c e !MyAPI(new → MyAPIImplementation , r e s t s e t t i n g s ) ; struct Weather { s t r i n g text ; double temperature ; } 6
AngularJS Typescript i n t e r f a c e Weather { text : string , temperature : number } 7
AngularJS Typescript i n t e r f a c e Weather { text : string , temperature : number } i n t e r f a c e MainScope extends ng . IScope { weather : Weather } 7
AngularJS Typescript i n t e r f a c e Weather { text : string , temperature : number } i n t e r f a c e MainScope extends ng . IScope { weather : Weather } c l a s s MainCtrl { public s t a t i c $ i n j e c t = [ ’ $scope ’ , ’ $http ’ ] ; constructor ( private $scope : MainScope , private $http : ng . IHttpService ) { t h i s . weather () ; } 7
AngularJS Typescript weather () : void { var s = ’ /weather ’ ; t h i s . $http . get ( s ) . success (( data : Weather ) => { t h i s . $scope . weather = data ; }) ; } 8
Diet doctype html html (ng−app=”myapp”) head t i t l e DConf 2016 Weather − j a v a s c r i p t ( ” . / angular . j s ”) ; − j a v a s c r i p t ( ” . / angular−route . j s ”) ; − j a v a s c r i p t ( ” . / myapp . j s ”) ; body div (ng−view ) 9
Diet doctype html html (ng−app=”myapp”) head t i t l e DConf 2016 Weather − j a v a s c r i p t ( ” . / angular . j s ”) ; − j a v a s c r i p t ( ” . / angular−route . j s ”) ; − j a v a s c r i p t ( ” . / myapp . j s ”) ; body div (ng−view ) − void j a v a s c r i p t ( s t r i n g name) s c r i p t ( src=”#{name}”) 9
Diet . container p {{ weather . text }} p {{ weather . temperature }} button ( type=”submit ” ,ng−c l i c k =” c t r l . weather () ; ” ) → Get Weather 10
Live Demo
Dataflow from the Server to the Frontend and back again
Dataflow from the Server to the Frontend and back again struct Weather { s t r i n g text ; double temperature ; } Dlang 11
Dataflow from the Server to the Frontend and back again struct Weather { s t r i n g text ; double temperature ; } Dlang i n t e r f a c e Weather { text : string , tempereture : number } Typescript 11
dstructtotypescript dstructtotypescript -i weather.d -p weather.ts -s → Weather 12
dstructtotypescript dstructtotypescript -i weather.d -p weather.ts -s → Weather struct Weather { string text ; double temperature ; }
dstructtotypescript dstructtotypescript -i weather.d -p weather.ts -s → Weather struct Weather { string text ; double temperature ; } import std . format ; foreach ( i t ; __traits (allMembers , Weather) )
dstructtotypescript dstructtotypescript -i weather.d -p weather.ts -s → Weather struct Weather { string text ; double temperature ; } import std . format ; foreach ( i t ; __traits (allMembers , Weather) ) interface Weather { text : string , temperature : number } 12
Everything is wrong
13
Everything is wrong • All we solved was a tiny specific problem • What about server to database • What if we would use Dart instead of Typescript • How do we communicate the overall architecture • How do we keep the architecture in sync with the code • How do we communicate with non-developer • ... 14
Everything is wrong • All we solved was a tiny specific problem • What about server to database • What if we would use Dart instead of Typescript • How do we communicate the overall architecture • How do we keep the architecture in sync with the code • How do we communicate with non-developer • ... • How do we deal with change? 14
Everything is still wrong • Waterfall Model 15
Everything is still wrong • Waterfall Model ← no change, never 15
Everything is still wrong • Waterfall Model ← no change, never • Hacking 15
Everything is still wrong • Waterfall Model ← no change, never • Hacking ← no plan to speak of, just change 15
Everything is still wrong • Waterfall Model ← no change, never • Agile Methods • Hacking ← no plan to speak of, just change 15
Everything is still wrong • Waterfall Model ← no change, never • Agile Methods ← just hacking, with fancy names • Hacking ← no plan to speak of, just change 15
Everything is still wrong • Waterfall Model ← no change, never • UML • Agile Methods ← just hacking, with fancy names • Hacking ← no plan to speak of, just change 15
Everything is still wrong • Waterfall Model ← no change, never • UML ← just kill me already • Agile Methods ← just hacking, with fancy names • Hacking ← no plan to speak of, just change 15
Everything is still wrong • Waterfall Model ← no change, never • UML ← just kill me already • Agile Methods ← just hacking, with fancy names • Hacking ← no plan to speak of, just change 15
Everything is still wrong • Waterfall Model ← no change, never • UML ← just kill me already • Agile Methods ← just hacking, with fancy names • Hacking ← no plan to speak of, just change 15
What do we want • Speak about the system at different levels of detail with different people • Quickly introduce people to the system • Keep data classes (Model) synchronized across • Frontend • Server • Database • Write only one model for everything, to keep stuff in sync • Have description line based, because git • Generate everything possible from the model 16
Introducing the C4 Architecture
Structurizr • Implements C4 Architecture Model • Java library to build the model 21
Structurizr • Implements C4 Architecture Model • Java library to build the model • Its code, its fits into git 21
Structurizr • Implements C4 Architecture Model • Java library to build the model • Its code, its fits into git • Structurizr generates code 21
Structurizr • Implements C4 Architecture Model • Java library to build the model • Its code, its fits into git • Structurizr generates code • Only Java and .net 21
How hard can it be
How do we approach the development • We’re not gonne create a new language 23
How do we approach the development • We’re not gonne create a new language, at first 23
How do we approach the development • We’re not gonne create a new language, at first, most likely 23
How do we approach the development • We’re not gonne create a new language, at first, most likely • The model (ast) is pretty simple 23
How do we approach the development • We’re not gonne create a new language, at first, most likely • The model (ast) is pretty simple • The world • The world has • Actors, software/hardware systems • A software systems has • Containers (everything with a unique pid) • A container has • Components (think module) and classes • A component has • Components and classes • Classes have members • Connections between the above • UML Association, Aggregation, Composition, Dependency, . . . • Additional informations, names, descriptions 23
Using Degenerator 1/2 auto world = new TheWorld( ”TheWorld” ) ; Actor users = world . getOrNewActor ( ”The Users ” ) ; users . d e s c r i p t i o n = ” This i s a way to long → de s c r i p t i o n fo r something ” ~ ” that should be obvious . ” ; auto system = world . getOrNewSoftwareSystem ( ” → AwesomeSoftware” ) ; 24
Using Degenerator 1/2 auto world = new TheWorld( ”TheWorld” ) ; Actor users = world . getOrNewActor ( ”The Users ” ) ; users . d e s c r i p t i o n = ” This i s a way to long → de s c r i p t i o n fo r something ” ~ ” that should be obvious . ” ; auto system = world . getOrNewSoftwareSystem ( ” → AwesomeSoftware” ) ; Container frontend = system . getOrNewContainer ( ” → Frontend” ) ; frontend . technology = ”Angular” ; auto frontendUserCtrl = frontend . getOrNewComponent( → ” frontUserCtrl ” ) ; 24
Using Degenerator 2/4 auto database = system . getOrNewContainer ( ”Database” → ) ; database . technology = ”MySQL” ; world . getOrNew ! Dependency ( ” serverDatabase ” , server , database ) . d e s c r i p t i o n = ”CRUD” ; 25
Using Degenerator 2/4 auto database = system . getOrNewContainer ( ”Database” → ) ; database . technology = ”MySQL” ; world . getOrNew ! Dependency ( ” serverDatabase ” , server , database ) . d e s c r i p t i o n = ”CRUD” ; Class user = getOrNewClass ( ”User” , frontendUserCtrl , serverUserCtrl , database ) ; 25
Using Degenerator 3/4 Class user = getOrNewClass ( ”User” , frontendUserCtrl , serverUserCtrl , database ) ; 26
Using Degenerator 3/4 Class user = getOrNewClass ( ”User” , frontendUserCtrl , serverUserCtrl , database ) ; MemberVariable userId = user . getOrNew ! → MemberVariable ( ” id ” ) ; userId . type = in teger ; userId . addLandSpecificAttribute ( ”MySQL” , ”PRIMARY → KEY” ) ; userId . addLandSpecificAttribute ( ”MySQL” , ”AUTO → INCREMENT” ) ; 26
Using Degenerator 4/4 Class address = getOrNewClass ( ” Address ” , frontendUserCtrl , serverUserCtrl , database ) ; 27
Using Degenerator 4/4 Class address = getOrNewClass ( ” Address ” , frontendUserCtrl , serverUserCtrl , database ) ; Aggregation userAddress = world . getOrNew ! → Aggregation ( ” addressUser ” , address , user ) ; 27
Types in Degenerator • Types 28
Types in Degenerator • Types e.g. strings are not always strings 28
Types in Degenerator • Types e.g. strings are not always strings • D string • MySQL text • C++ std::string 28
Types in Degenerator • Types e.g. strings are not always strings • D string • MySQL text • C++ std::string struct Type { s t r i n g name ; s t r i n g [ s t r i n g ] typeMapping ; } auto pwdHash = Type( ” PasswordString ” ) ; 28
Types in Degenerator • Types e.g. strings are not always strings • D string • MySQL text • C++ std::string struct Type { s t r i n g name ; s t r i n g [ s t r i n g ] typeMapping ; } auto pwdHash = Type( ” PasswordString ” ) ; pwdHash . typeMappings [ ”D” ] = ” s t r i n g ” ; pwdHash . typeMappings [ ”MySQL” ] = ”VARCHAR(128) ” ; 28
Generating Graphvic gv = new Graphvic ( world , ”GraphvizOutput” ) ; gv . generate () ; MySQL mysql = new MySQL( world , ”MySQL” ) ; mysql . generate ( database ) ; 29
The World 30
The World and Containers 31
Awesome Software System 32
Generating the Database CREATE TABLE Statements CREATE TABLE Address { id LONG PRIMARY KEY }; CREATE TABLE Address_User { User_id LONG FOREIGN KEY(User_id) → REFERENCES User ( id ) ON → UPDATE CASCADE ON → DELETE CASCADE, Address_id LONG FOREIGN KEY(Address_id) → REFERENCES Address ( id ) → ON UPDATE CASCADE ON → DELETE CASCADE } CREATE TABLE User { id LONG PRIMARY KEY AUTO → INCREMENT, lastname TEXT, firstname TEXT }; CREATE TABLE PostelCode { id LONG PRIMARY KEY AUTO → INCREMENT, code LONG, Address_id LONG FOREIGN KEY(Address_id ) → REFERENCES Address ( id ) → ON UPDATE CASCADE ON → DELETE CASCADE }; 33
What can we generate • Diagrams describing the project at different levels of detail • Database schema • phpmyadmin clones • Database access code • Data objects (D struct/class, Typescript interface/class, . . . • Server skeletons • Frontend skeletons 34
What can we generate • Diagrams describing the project at different levels of detail • Database schema • phpmyadmin clones • Database access code • Data objects (D struct/class, Typescript interface/class, . . . • Server skeletons • Frontend skeletons • Graphviz mostly done, MySQL is getting there, Vibe.d and Angular2 next 34
The End • vibe.d https://vibed.org • typescript https://www.typescriptlang.org/ • dstructtotypescript https://github.com/burner/dstructtotypescript • C4 Architecture (Simon Brown) http://www.codingthearchitecture.com • Structurizr https://structurizr.com/ • Degenerator https://github.com/burner/Degenerator 36

Asynchronous single page applications without a line of HTML or Javascript, or why D is just awesome

  • 1.
    Asynchronous Single PageApplications without a Line of HTML or Javascript. Or why D is just awesome Robert ”burner” Schadek May 5, 2016 DConf
  • 2.
    Javascript and HTMLare awesome • No explicit types • Variables may be undefined • Repetition repetition repetition • No templates • No compile time function execution • No compile time 1
  • 4.
    Goals • Retain type-informationof data from DB to Client’s Browser 3
  • 5.
    Goals • Retain type-informationof data from DB to Client’s Browser • Keeping things DRY 3
  • 6.
    Goals • Retain type-informationof data from DB to Client’s Browser • Keeping things DRY • Performance 3
  • 7.
    Goals • Retain type-informationof data from DB to Client’s Browser • Keeping things DRY • Performance • Get things done 3
  • 8.
  • 9.
    Vibe.d • Powerful asynchronousI/O and web toolkit for D • Uses Fibers and Threads 4
  • 10.
    Vibe.d • Powerful asynchronousI/O and web toolkit for D • Uses Fibers and Threads • n → m mapping • yield() • async IO 4
  • 11.
    Vibe.d • Powerful asynchronousI/O and web toolkit for D • Uses Fibers and Threads • n → m mapping • yield() • async IO • async DB connectivity for MongoDB, Redis, MySQL • You don’t need to care about async • Web interface generator • REST interface generator 4
  • 12.
    REST Interface Generator in t e r f a c e MyAPI { // GET /weather −> responds {” text ”: ” . . . ” , ” → temperature ”: . . . } Weather getWeather () ; } 5
  • 13.
    REST Interface Generator in t e r f a c e MyAPI { // GET /weather −> responds {” text ”: ” . . . ” , ” → temperature ”: . . . } Weather getWeather () ; } c l a s s MyAPIImplementation : MyAPI { auto weather = [ ”sunny” , ” rainy ” , ” cats and dogs ” → , ”snow” ] ; Weather getWeather () { return Weather ( weather [ uniform (0 , weather . length ) ] , uniform ( −10 ,30) ) ; } } 5
  • 14.
    REST Interface Generator autorouter = new URLRouter ; router . get ( ”/” , staticTemplate ! ” index . dt” ) ; router . get ( ”/main . html” , staticTemplate ! ”main . dt” ) ; router . r e g i s t e r R e s t I n t e r f a c e !MyAPI(new → MyAPIImplementation , r e s t s e t t i n g s ) ; 6
  • 15.
    REST Interface Generator autorouter = new URLRouter ; router . get ( ”/” , staticTemplate ! ” index . dt” ) ; router . get ( ”/main . html” , staticTemplate ! ”main . dt” ) ; router . r e g i s t e r R e s t I n t e r f a c e !MyAPI(new → MyAPIImplementation , r e s t s e t t i n g s ) ; struct Weather { s t r i n g text ; double temperature ; } 6
  • 16.
    AngularJS Typescript i nt e r f a c e Weather { text : string , temperature : number } 7
  • 17.
    AngularJS Typescript i nt e r f a c e Weather { text : string , temperature : number } i n t e r f a c e MainScope extends ng . IScope { weather : Weather } 7
  • 18.
    AngularJS Typescript i nt e r f a c e Weather { text : string , temperature : number } i n t e r f a c e MainScope extends ng . IScope { weather : Weather } c l a s s MainCtrl { public s t a t i c $ i n j e c t = [ ’ $scope ’ , ’ $http ’ ] ; constructor ( private $scope : MainScope , private $http : ng . IHttpService ) { t h i s . weather () ; } 7
  • 19.
    AngularJS Typescript weather (): void { var s = ’ /weather ’ ; t h i s . $http . get ( s ) . success (( data : Weather ) => { t h i s . $scope . weather = data ; }) ; } 8
  • 20.
    Diet doctype html html (ng−app=”myapp”) head ti t l e DConf 2016 Weather − j a v a s c r i p t ( ” . / angular . j s ”) ; − j a v a s c r i p t ( ” . / angular−route . j s ”) ; − j a v a s c r i p t ( ” . / myapp . j s ”) ; body div (ng−view ) 9
  • 21.
    Diet doctype html html (ng−app=”myapp”) head ti t l e DConf 2016 Weather − j a v a s c r i p t ( ” . / angular . j s ”) ; − j a v a s c r i p t ( ” . / angular−route . j s ”) ; − j a v a s c r i p t ( ” . / myapp . j s ”) ; body div (ng−view ) − void j a v a s c r i p t ( s t r i n g name) s c r i p t ( src=”#{name}”) 9
  • 22.
    Diet . container p {{weather . text }} p {{ weather . temperature }} button ( type=”submit ” ,ng−c l i c k =” c t r l . weather () ; ” ) → Get Weather 10
  • 23.
  • 24.
    Dataflow from theServer to the Frontend and back again
  • 25.
    Dataflow from theServer to the Frontend and back again struct Weather { s t r i n g text ; double temperature ; } Dlang 11
  • 26.
    Dataflow from theServer to the Frontend and back again struct Weather { s t r i n g text ; double temperature ; } Dlang i n t e r f a c e Weather { text : string , tempereture : number } Typescript 11
  • 27.
  • 28.
    dstructtotypescript dstructtotypescript -i weather.d-p weather.ts -s → Weather struct Weather { string text ; double temperature ; }
  • 29.
    dstructtotypescript dstructtotypescript -i weather.d-p weather.ts -s → Weather struct Weather { string text ; double temperature ; } import std . format ; foreach ( i t ; __traits (allMembers , Weather) )
  • 30.
    dstructtotypescript dstructtotypescript -i weather.d-p weather.ts -s → Weather struct Weather { string text ; double temperature ; } import std . format ; foreach ( i t ; __traits (allMembers , Weather) ) interface Weather { text : string , temperature : number } 12
  • 31.
  • 32.
  • 33.
    Everything is wrong •All we solved was a tiny specific problem • What about server to database • What if we would use Dart instead of Typescript • How do we communicate the overall architecture • How do we keep the architecture in sync with the code • How do we communicate with non-developer • ... 14
  • 34.
    Everything is wrong •All we solved was a tiny specific problem • What about server to database • What if we would use Dart instead of Typescript • How do we communicate the overall architecture • How do we keep the architecture in sync with the code • How do we communicate with non-developer • ... • How do we deal with change? 14
  • 35.
    Everything is stillwrong • Waterfall Model 15
  • 36.
    Everything is stillwrong • Waterfall Model ← no change, never 15
  • 37.
    Everything is stillwrong • Waterfall Model ← no change, never • Hacking 15
  • 38.
    Everything is stillwrong • Waterfall Model ← no change, never • Hacking ← no plan to speak of, just change 15
  • 39.
    Everything is stillwrong • Waterfall Model ← no change, never • Agile Methods • Hacking ← no plan to speak of, just change 15
  • 40.
    Everything is stillwrong • Waterfall Model ← no change, never • Agile Methods ← just hacking, with fancy names • Hacking ← no plan to speak of, just change 15
  • 41.
    Everything is stillwrong • Waterfall Model ← no change, never • UML • Agile Methods ← just hacking, with fancy names • Hacking ← no plan to speak of, just change 15
  • 42.
    Everything is stillwrong • Waterfall Model ← no change, never • UML ← just kill me already • Agile Methods ← just hacking, with fancy names • Hacking ← no plan to speak of, just change 15
  • 43.
    Everything is stillwrong • Waterfall Model ← no change, never • UML ← just kill me already • Agile Methods ← just hacking, with fancy names • Hacking ← no plan to speak of, just change 15
  • 44.
    Everything is stillwrong • Waterfall Model ← no change, never • UML ← just kill me already • Agile Methods ← just hacking, with fancy names • Hacking ← no plan to speak of, just change 15
  • 45.
    What do wewant • Speak about the system at different levels of detail with different people • Quickly introduce people to the system • Keep data classes (Model) synchronized across • Frontend • Server • Database • Write only one model for everything, to keep stuff in sync • Have description line based, because git • Generate everything possible from the model 16
  • 46.
    Introducing the C4Architecture
  • 51.
    Structurizr • Implements C4Architecture Model • Java library to build the model 21
  • 52.
    Structurizr • Implements C4Architecture Model • Java library to build the model • Its code, its fits into git 21
  • 53.
    Structurizr • Implements C4Architecture Model • Java library to build the model • Its code, its fits into git • Structurizr generates code 21
  • 54.
    Structurizr • Implements C4Architecture Model • Java library to build the model • Its code, its fits into git • Structurizr generates code • Only Java and .net 21
  • 56.
  • 57.
    How do weapproach the development • We’re not gonne create a new language 23
  • 58.
    How do weapproach the development • We’re not gonne create a new language, at first 23
  • 59.
    How do weapproach the development • We’re not gonne create a new language, at first, most likely 23
  • 60.
    How do weapproach the development • We’re not gonne create a new language, at first, most likely • The model (ast) is pretty simple 23
  • 61.
    How do weapproach the development • We’re not gonne create a new language, at first, most likely • The model (ast) is pretty simple • The world • The world has • Actors, software/hardware systems • A software systems has • Containers (everything with a unique pid) • A container has • Components (think module) and classes • A component has • Components and classes • Classes have members • Connections between the above • UML Association, Aggregation, Composition, Dependency, . . . • Additional informations, names, descriptions 23
  • 62.
    Using Degenerator 1/2 autoworld = new TheWorld( ”TheWorld” ) ; Actor users = world . getOrNewActor ( ”The Users ” ) ; users . d e s c r i p t i o n = ” This i s a way to long → de s c r i p t i o n fo r something ” ~ ” that should be obvious . ” ; auto system = world . getOrNewSoftwareSystem ( ” → AwesomeSoftware” ) ; 24
  • 63.
    Using Degenerator 1/2 autoworld = new TheWorld( ”TheWorld” ) ; Actor users = world . getOrNewActor ( ”The Users ” ) ; users . d e s c r i p t i o n = ” This i s a way to long → de s c r i p t i o n fo r something ” ~ ” that should be obvious . ” ; auto system = world . getOrNewSoftwareSystem ( ” → AwesomeSoftware” ) ; Container frontend = system . getOrNewContainer ( ” → Frontend” ) ; frontend . technology = ”Angular” ; auto frontendUserCtrl = frontend . getOrNewComponent( → ” frontUserCtrl ” ) ; 24
  • 64.
    Using Degenerator 2/4 autodatabase = system . getOrNewContainer ( ”Database” → ) ; database . technology = ”MySQL” ; world . getOrNew ! Dependency ( ” serverDatabase ” , server , database ) . d e s c r i p t i o n = ”CRUD” ; 25
  • 65.
    Using Degenerator 2/4 autodatabase = system . getOrNewContainer ( ”Database” → ) ; database . technology = ”MySQL” ; world . getOrNew ! Dependency ( ” serverDatabase ” , server , database ) . d e s c r i p t i o n = ”CRUD” ; Class user = getOrNewClass ( ”User” , frontendUserCtrl , serverUserCtrl , database ) ; 25
  • 66.
    Using Degenerator 3/4 Classuser = getOrNewClass ( ”User” , frontendUserCtrl , serverUserCtrl , database ) ; 26
  • 67.
    Using Degenerator 3/4 Classuser = getOrNewClass ( ”User” , frontendUserCtrl , serverUserCtrl , database ) ; MemberVariable userId = user . getOrNew ! → MemberVariable ( ” id ” ) ; userId . type = in teger ; userId . addLandSpecificAttribute ( ”MySQL” , ”PRIMARY → KEY” ) ; userId . addLandSpecificAttribute ( ”MySQL” , ”AUTO → INCREMENT” ) ; 26
  • 68.
    Using Degenerator 4/4 Classaddress = getOrNewClass ( ” Address ” , frontendUserCtrl , serverUserCtrl , database ) ; 27
  • 69.
    Using Degenerator 4/4 Classaddress = getOrNewClass ( ” Address ” , frontendUserCtrl , serverUserCtrl , database ) ; Aggregation userAddress = world . getOrNew ! → Aggregation ( ” addressUser ” , address , user ) ; 27
  • 70.
  • 71.
    Types in Degenerator •Types e.g. strings are not always strings 28
  • 72.
    Types in Degenerator •Types e.g. strings are not always strings • D string • MySQL text • C++ std::string 28
  • 73.
    Types in Degenerator •Types e.g. strings are not always strings • D string • MySQL text • C++ std::string struct Type { s t r i n g name ; s t r i n g [ s t r i n g ] typeMapping ; } auto pwdHash = Type( ” PasswordString ” ) ; 28
  • 74.
    Types in Degenerator •Types e.g. strings are not always strings • D string • MySQL text • C++ std::string struct Type { s t r i n g name ; s t r i n g [ s t r i n g ] typeMapping ; } auto pwdHash = Type( ” PasswordString ” ) ; pwdHash . typeMappings [ ”D” ] = ” s t r i n g ” ; pwdHash . typeMappings [ ”MySQL” ] = ”VARCHAR(128) ” ; 28
  • 75.
    Generating Graphvic gv =new Graphvic ( world , ”GraphvizOutput” ) ; gv . generate () ; MySQL mysql = new MySQL( world , ”MySQL” ) ; mysql . generate ( database ) ; 29
  • 76.
  • 77.
    The World andContainers 31
  • 78.
  • 79.
    Generating the DatabaseCREATE TABLE Statements CREATE TABLE Address { id LONG PRIMARY KEY }; CREATE TABLE Address_User { User_id LONG FOREIGN KEY(User_id) → REFERENCES User ( id ) ON → UPDATE CASCADE ON → DELETE CASCADE, Address_id LONG FOREIGN KEY(Address_id) → REFERENCES Address ( id ) → ON UPDATE CASCADE ON → DELETE CASCADE } CREATE TABLE User { id LONG PRIMARY KEY AUTO → INCREMENT, lastname TEXT, firstname TEXT }; CREATE TABLE PostelCode { id LONG PRIMARY KEY AUTO → INCREMENT, code LONG, Address_id LONG FOREIGN KEY(Address_id ) → REFERENCES Address ( id ) → ON UPDATE CASCADE ON → DELETE CASCADE }; 33
  • 80.
    What can wegenerate • Diagrams describing the project at different levels of detail • Database schema • phpmyadmin clones • Database access code • Data objects (D struct/class, Typescript interface/class, . . . • Server skeletons • Frontend skeletons 34
  • 81.
    What can wegenerate • Diagrams describing the project at different levels of detail • Database schema • phpmyadmin clones • Database access code • Data objects (D struct/class, Typescript interface/class, . . . • Server skeletons • Frontend skeletons • Graphviz mostly done, MySQL is getting there, Vibe.d and Angular2 next 34
  • 83.
    The End • vibe.dhttps://vibed.org • typescript https://www.typescriptlang.org/ • dstructtotypescript https://github.com/burner/dstructtotypescript • C4 Architecture (Simon Brown) http://www.codingthearchitecture.com • Structurizr https://structurizr.com/ • Degenerator https://github.com/burner/Degenerator 36