SlideShare ist ein Scribd-Unternehmen logo
1 von 46
Downloaden Sie, um offline zu lesen
Jhipster Beyond CRUD
API First for Enterprise
2 7 / 0 6 / 2 0 1 9 - I N T E S Y S
This material has been prepared by personnel of Intesys S.r.l. and is provided on a confidential basis.
All the materials, animations, graphics and concepts may not be used, reproduced, redistributed or transmitted, in whole or in part, without prior written permission from the owner. Any unauthorized use is strictly prohibited.
W H O A R E W E ?
Who we are
Paolo Quaglia
senior project manager
and software architect - @p_quail
Enrico Costanzi
senior software developer - @enricocostanzi
W H O A R E W E ?
Italian 100 employees company
Enterprise industry: Banks, insurance companies,
manufacturing
Our Development Pattern: Design to Deliver
W H O A R E W E ?
• We started with Jhipster in 2017
• 3rd Jhipster Bronze Sponsor
• ~10 developers on average working with Jhipster
• 5 projects running in production
• 3 big project in Development phase
• 2 Jhipster modules published
• More modules/blueprints – work in progress
• Some contributions to the main generator
Intesys & Jhipster
How we started
I N T E S Y S & J H I P S T E R
2017
I N T E S Y S & J H I P S T E R
2017 • Angular Monolith (Single Node)
• Jhipster 4.10.1
• 12 entities
• ~200 users
• No swagger endpoints
• 3 Roles
• No native queries
• Local Cache
• 2 dev teams involved
I N T E S Y S & J H I P S T E R
2019 • React Monolith (multiple nodes)
• Jhipster 5.8.2
• 120 entities (2 JDL files)
• ~4000 users
• 100 OpenAPI endpoints
• 7 roles
• Many native queries
• Distributed cache
• 5 dev teams involved
API Driven Enterprise
A P I D R I V E N E N T E R P R I S E
Enterprise Systems
(SAP, AS400,
TIBCO, API
Gateways)
Legacy databases
A G E N D A
• Why Beyond CRUD?
• Code First Jhipster
• API First Jhipster
• Modules Demo
• Testcontainers & Jhipster
Agenda
Why Beyond CRUD?
B E Y O N D C R U D
UserJWTController
AccountResource
UserResource
Entity1Resource Entity1Service Entity1Repository
Entity1ResourceExt Entity1ServiceExt Entity1RepoExt
CustomController1
UserService UserRepository
CustomService1
CustomController2 CustomService2
UserResourceExt UserServiceExt
How do I make life easy for API
consumers?
B E Y O N D C R U D
• Interoperability
• Productivity
• User Experience (UX)
• Developer Experience (DX)
We need
Code First Jhipster
C O D E F I R S T J H I P S T E R
UserJWTController
AccountResource
UserResource
Entity1Resource
Entity1ResourceExt
CustomController1
CustomController2
UserResourceExt
Swagger UI & Springfox
/v2/api-docs
Some Customizations
C O D E F I R S T J H I P S T E R
Split your Swagger specs
/v2/api-docs?group=auth
/v2/api-docs?group=admin
/v2/api-docs
UserJWTController
AccountResource
UserResource
Entity1Resource
Entity1ResourceExt
CustomController1
CustomController2
UserResourceExt
C O D E F I R S T J H I P S T E R
Split your Swagger specs
/v2/api-docs?group=auth
/v2/api-docs?group=admin
/v2/api-docs
UserJWTController
AccountResource
UserResource
Entity1Resource
Entity1ResourceExt
CustomController1
CustomController2
UserResourceExt
@Bean
public Docket authDocket() {
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.groupName("auth")
.forCodeGeneration(true)
.directModelSubstitute(java.nio.ByteBuffer.class, String.class)
.directModelSubstitute(URI.class, String.class)
.directModelSubstitute(StatusType.class, Integer.class)
.genericModelSubstitutes(ResponseEntity.class)
.additionalModels(typeResolver.resolve(Problem.class))
.select()
.paths(Predicates.or(
regex("/api/account.*"), regex("/api/authenticate.*"),
regex("/api/activate.*"), regex("/api/register.*"))
)
.build();
return docket;
}
C O D E F I R S T J H I P S T E R
Export your Swagger specs
UserJWTController
AccountResource
UserResource
Entity1Resource
Entity1ResourceExt
CustomController1
CustomController2
UserResourceExt
account-spec.json
default-spec.json
account-spec.json
C O D E F I R S T J H I P S T E R
Export your Swagger specs
UserJWTController
AccountResource
UserResource
Entity1Resource
Entity1ResourceExt
CustomController1
CustomController2
UserResourceExt
account-spec.json
default-spec.json
account-spec.json
@SpringBootTest(classes = JhipetstoreApp.class)
@ActiveProfiles(value = {JHipsterConstants.SPRING_PROFILE_SWAGGER})
public class OpenApiSpecGeneratorIT {
@Autowired DocumentationCache documentationCache;
@Autowired ServiceModelToSwagger2Mapper mapper;
@Autowired JsonSerializer jsonSerializer;
@Test
void createOpenApiJsonSpec() throws IOException {
for (Map.Entry<String, Documentation> documentationEntry : documentationCache.all().entrySet()) {
String groupName = documentationEntry.getKey();
Documentation documentation = documentationEntry.getValue();
Swagger swagger = mapper.mapDocumentation(documentation);
Json spec = jsonSerializer.toJson(swagger);
File specsDir = new File("target/swagger-specs");
if (!specsDir.exists()) specsDir.mkdirs();
IOUtils.write(spec.value().getBytes(), new FileOutputStream("target/swagger-specs/”
+ groupName + «-spec.json"));
}
}
}
C O D E F I R S T - C O N T R A C T D R I V E N C O M M U N I C A T I O N
UserJWTController
AccountResource
UserResource
Entity1Resource Entity1Service Entity1Repository
Entity1ResourceExt Entity1ServiceExt Entity1RepoExt
CustomController1
UserService UserRepository
CustomService1
CustomController2 CustomService2
UserResourceExt UserServiceExt
B E Y O N D C R U D
Code First
• API Consumers must wait for specs to be
exposed or exported
• Only Swagger v2 support (OpenAPI 3
generation is WIP)
• Springfox scanning is slow with lots of
controllers
• Security rules must be coded in dockets
API First Jhipster
A P I F I R S T J H I P S T E R
API First
• Design
• API Design before writing code
• Interoperability
• Helps detecting breaking changes
• Developer Experience
• Decoupling client/server development
• Developers contribute to API definition
• Approval process during API design
• User Experience
• API design with UX/UI in mind
27
A P I F I R S T J H I P S T E R
Server side code generation from swagger / openapi specifications
ReadPetsApi
ReadPetApiDelegate
API First Jhipster
src/main/resources/swagger/api.yml
ReadPetsApiDelegateImpl
ReadPetsApiController
A P I F I R S T
modelNameSuffix: avoid DTOS
with the same class name:
• PetDTO (Jhipster)
• PetApiDto (OpenAPI DTO)
useTags: Groups the OpenAPI
endpoints by tag (not by path
prefix)
OpenAPI Generator Configuration
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>${openapi-generator-maven-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>…/resources/swagger/api.yml</inputSpec>
<generatorName>spring</generatorName>
…
<modelNameSuffix>ApiDTO</modelNameSuffix>
<configOptions>
<delegatePattern>true</delegatePattern>
<title>jhipetstore</title>
<useTags>true</useTags>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
C O D E F I R S T A N D A P I F I R S T
What changed?
UserJWTController
AccountResource
UserResource
Entity1Resource
Entity1ResourceExt
CustomController1
CustomController2
UserResourceExt
OpenAPIController1
OpenAPIController2
UserJWTController
AccountResource
UserResource
Entity1Resource
Entity1ResourceExt
UserResourceExt
C O D E F I R S T A N D A P I F I R S T
UserJWTController
AccountResource
UserResource
Entity1Resource Entity1Service Entity1Repository
Entity1ResourceExt Entity1ServiceExt Entity1RepoExt
UserService UserRepository
CustomAPIService1
UserResourceExt UserServiceExt
OpenAPIController1
OpenAPIController2 CustomAPIService2
JDL
Code First
API First
C O D E F I R S T A N D A P I F I R S T
Jhipster Frontend
OpenAPIController1
OpenAPIController2
UserJWTController
AccountResource
UserResource
Entity1Resource
Entity1ResourceExt
UserResourceExt
JDL APIs:
• Jhipster CRUD
• Jhipster Administration
• Customizations
API First Endpoints
(generated client SDK):
• Custom Pages
• Design First
C O D E F I R S T A N D A P I F I R S T
External Apps – API + Code First
OpenAPIController1
OpenAPIController2
UserJWTController
AccountResource
UserResource
Entity1Resource
Entity1ResourceExt
UserResourceExt
External Backend Applications
Mobile Apps
Custom Single Page Applications
C O D E F I R S T A N D A P I F I R S T
External Apps – API First only
OpenAPIController1
OpenAPIController2
UserJWTController
AccountResource
UserResource
Entity1Resource
Entity1ResourceExt
UserResourceExt
External Backend Applications
Mobile Apps
Custom Single Page Applications
A P I F I R S T
• Code duplication
• Jhipster DTOs ~= OpenAPI DTOs
• Basic CRUD Operations have to be rewritten in the spec
• Metamodel Filtering and pagination (coded in the spec)
• Authentication (duplicated endpoints in some cases)
API First Limitations
Demo
D E M O
Customizing Using Modules
OpenAPIController1
OpenAPIController2
OpenAPIController1
OpenAPIController2
Generated by OpenAPI Generator
Generated by
Springfox
Designed specs
Designed specs
• api.yml served statically (not generated by Springfox)
by a dedicated endpoint
• Replaces Swagger UI 2 with Swagger UI 3 (iframe)
• API version tag published in consul or Jhipster registry
D E M O
• Jhipster submodule to generate client code from swagger/openapi
specifications
• Integration of generator-jhipster-swagger-cli in the main generator
• Wraps the official npm module openapi-generator-cli
• Supports backend client generation (Feign clients)
• Future steps: generate client code for Angular / React
Jhipster OpenAPI Client (Preview)
$ jhipster openapi-client
Testcontainers & Jhipster
T E S T C O N T A I N E R S
Testcontainers
“Testcontainers is a Java library that
supports JUnit tests, providing
lightweight, throwaway instances of
common databases, Selenium web
browsers, or anything else that can run
in a Docker container”
Jhipster Integration Tests
• Native SQL Queries & Functions
• Liquibase changelogs
T E S T C O N T A I N E R S
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>1.11.3</version>
<scope>test</scope>
</dependency>
The easy way
jdbc:tc:postgresql:11.3://localhost:5432/jhipetstore
org.testcontainers.jdbc.ContainerDatabaseDriver
1. add dependency
2. change test properties
3. ./mvnw verify
4. DONE! ☺
T E S T C O N T A I N E R S
The custom way
jdbc:tc:postgresql:11.3://localhost:5432/jhipetstore
org.testcontainers.jdbc.ContainerDatabaseDriver
@TestConfiguration
@Profile("testcontainers")
public class IntegrationTestsConfiguration {
@Bean
public DataSource dataSource() {
dbContainer =
new MSSQLServerContainer("my-docker-account/mssql-server-custom:latest")
.withPassword("yourStrong(!)Password");
dbContainer.start(); //starts the container
String jdbcUrl = dbContainer.getJdbcUrl();
logger.info("Database started, creating datasource for url: '{}'", jdbcUrl);
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setUsername(dbContainer.getUsername());
dataSource.setPassword(dbContainer.getPassword());
dataSource.setDriverClassName(dbContainer.getDriverClassName());
dataSource.setAutoCommit(false);
return dataSource;
}
generator-jhipster-testcontainers
T E S T C O N T A I N E R S
The custom way
jdbc:tc:postgresql:11.3://localhost:5432/jhipetstore
org.testcontainers.jdbc.ContainerDatabaseDriver
@TestConfiguration
@Profile("testcontainers")
public class IntegrationTestsConfiguration {
@Bean
public DataSource dataSource() {
dbContainer =
new MSSQLServerContainer("my-docker-account/mssql-server-custom:latest")
.withPassword("yourStrong(!)Password");
dbContainer.start(); //starts the container
String jdbcUrl = dbContainer.getJdbcUrl();
logger.info("Database started, creating datasource for url: '{}'", jdbcUrl);
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setUsername(dbContainer.getUsername());
dataSource.setPassword(dbContainer.getPassword());
dataSource.setDriverClassName(dbContainer.getDriverClassName());
dataSource.setAutoCommit(false);
return dataSource;
}
generator-jhipster-testcontainers
$ yo jhipster-testcontainers
$ ./mvnw verify -Dspring.profiles.active=testcontainers
Recap
A P I F I R S T
• CRUD stack is the foundation of your APP
• How CRUD and OpenAPI layers coexist
• Go API First only for mission critical APIs
• Use Testcontainers
• Share your modules ☺
Recap
A P I F I R S T
• Jhipster Conf 2018
• Connect your JHipster apps to APIs with Swagger and gRPC by Christophe Bornet
(https://www.youtube.com/watch?v=XWa-53-mDwY)
• Custom and Generated Code Side by Side by Antonio Goncalves
(https://www.youtube.com/watch?v=9WVpwIUEty0)
• generator-jhipster-apiutils module
• https://www.npmjs.com/package/generator-jhipster-apiutils
• Testcontainers & Jhipster
• https://www.youtube.com/watch?time_continue=3&v=L_i61qTg510
• https://atomfrede.gitlab.io/2019/05/jhipster-with-testcontainers/
• https://www.npmjs.com/package/generator-jhipster-testcontainers
• https://github.com/danielgtaylor/apisprout
• Demo Code Samples:
• https://github.com/intesys/jhipsterconf2019-petstore-demo
• https://github.com/intesys/jhipsterconf2019-petstore-client
References
Intesys S.r.l.
Via Roveggia, 122/A - 37136 Verona VR
T. +39 045 503 663
F. +39 045 503 604
@ info@intesys.it
intesys.it
Enrico Costanzi
S e n i o r s o f t w a r e d e v e l o p e r
enrico.costanzi@intesys.it
@enricocostanzi
Paolo Quaglia
S e n i o r P r o j e c t M a n a g e r a n d A r c h i t e c t
paolo.quaglia@intesys.it
@p_quail

Weitere ähnliche Inhalte

Was ist angesagt?

Counterclockwise past present future
Counterclockwise  past present futureCounterclockwise  past present future
Counterclockwise past present future
lolopetit
 
blueMarine Sailing with NetBeans Platform
blueMarine Sailing with NetBeans PlatformblueMarine Sailing with NetBeans Platform
blueMarine Sailing with NetBeans Platform
Fabrizio Giudici
 

Was ist angesagt? (20)

In defense of GWT-RPC By Colin Alworth
In defense of GWT-RPC By Colin AlworthIn defense of GWT-RPC By Colin Alworth
In defense of GWT-RPC By Colin Alworth
 
GitBucket: Open source self-hosting Git server built by Scala
GitBucket: Open source self-hosting Git server built by ScalaGitBucket: Open source self-hosting Git server built by Scala
GitBucket: Open source self-hosting Git server built by Scala
 
React native: building native iOS apps with javascript
React native: building native iOS apps with javascriptReact native: building native iOS apps with javascript
React native: building native iOS apps with javascript
 
JHipster, modern web application development made easy
JHipster, modern web application development made easyJHipster, modern web application development made easy
JHipster, modern web application development made easy
 
Javantura v4 - Angular2 - Ionic2 - from birth to stable versions - Hrvoje Pek...
Javantura v4 - Angular2 - Ionic2 - from birth to stable versions - Hrvoje Pek...Javantura v4 - Angular2 - Ionic2 - from birth to stable versions - Hrvoje Pek...
Javantura v4 - Angular2 - Ionic2 - from birth to stable versions - Hrvoje Pek...
 
How to keep maintainability of long life Scala applications
How to keep maintainability of long life Scala applicationsHow to keep maintainability of long life Scala applications
How to keep maintainability of long life Scala applications
 
Intro to React Native
Intro to React NativeIntro to React Native
Intro to React Native
 
Counterclockwise past present future
Counterclockwise  past present futureCounterclockwise  past present future
Counterclockwise past present future
 
Gradle build automation tool
Gradle   build automation toolGradle   build automation tool
Gradle build automation tool
 
Qt 5 - C++ and Widgets
Qt 5 - C++ and WidgetsQt 5 - C++ and Widgets
Qt 5 - C++ and Widgets
 
Android Made Simple
Android Made SimpleAndroid Made Simple
Android Made Simple
 
Javantura v4 - Support SpringBoot application development lifecycle using Ora...
Javantura v4 - Support SpringBoot application development lifecycle using Ora...Javantura v4 - Support SpringBoot application development lifecycle using Ora...
Javantura v4 - Support SpringBoot application development lifecycle using Ora...
 
Case Study: Using Qt to Develop Advanced GUIs & Advanced Visualization Software
Case Study: Using Qt to Develop Advanced GUIs & Advanced Visualization SoftwareCase Study: Using Qt to Develop Advanced GUIs & Advanced Visualization Software
Case Study: Using Qt to Develop Advanced GUIs & Advanced Visualization Software
 
Exploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & BeyondExploring the power of Gradle in android studio - Basics & Beyond
Exploring the power of Gradle in android studio - Basics & Beyond
 
Javantura v4 - What’s NOT new in modular Java - Milen Dyankov
Javantura v4 - What’s NOT new in modular Java - Milen DyankovJavantura v4 - What’s NOT new in modular Java - Milen Dyankov
Javantura v4 - What’s NOT new in modular Java - Milen Dyankov
 
blueMarine Sailing with NetBeans Platform
blueMarine Sailing with NetBeans PlatformblueMarine Sailing with NetBeans Platform
blueMarine Sailing with NetBeans Platform
 
Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6
 
Rapid and Reliable Developing with HTML5 & GWT
Rapid and Reliable Developing with HTML5 & GWTRapid and Reliable Developing with HTML5 & GWT
Rapid and Reliable Developing with HTML5 & GWT
 
How to Make Your Qt App Look Native
How to Make Your Qt App Look NativeHow to Make Your Qt App Look Native
How to Make Your Qt App Look Native
 
GWT Contributor Workshop
GWT Contributor WorkshopGWT Contributor Workshop
GWT Contributor Workshop
 

Ähnlich wie JHipster Beyond CRUD - JHipster Conf' 2019

OpenERP Technical Memento
OpenERP Technical MementoOpenERP Technical Memento
OpenERP Technical Memento
Odoo
 

Ähnlich wie JHipster Beyond CRUD - JHipster Conf' 2019 (20)

Operator SDK for K8s using Go
Operator SDK for K8s using GoOperator SDK for K8s using Go
Operator SDK for K8s using Go
 
PhpStorm: Symfony2 Plugin
PhpStorm: Symfony2 PluginPhpStorm: Symfony2 Plugin
PhpStorm: Symfony2 Plugin
 
Build Great Networked APIs with Swift, OpenAPI, and gRPC
Build Great Networked APIs with Swift, OpenAPI, and gRPCBuild Great Networked APIs with Swift, OpenAPI, and gRPC
Build Great Networked APIs with Swift, OpenAPI, and gRPC
 
OpenERP Technical Memento
OpenERP Technical MementoOpenERP Technical Memento
OpenERP Technical Memento
 
How to Contribute to Apache Usergrid
How to Contribute to Apache UsergridHow to Contribute to Apache Usergrid
How to Contribute to Apache Usergrid
 
NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...
NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...
NDC Sydney 2019 - Microservices for building an IDE – The innards of JetBrain...
 
FIWARE Wednesday Webinars - How to Debug IoT Agents
FIWARE Wednesday Webinars - How to Debug IoT AgentsFIWARE Wednesday Webinars - How to Debug IoT Agents
FIWARE Wednesday Webinars - How to Debug IoT Agents
 
Developing On the IntelliJ Platform
Developing On the IntelliJ PlatformDeveloping On the IntelliJ Platform
Developing On the IntelliJ Platform
 
2022 APIsecure_Securing APIs with Open Standards
2022 APIsecure_Securing APIs with Open Standards2022 APIsecure_Securing APIs with Open Standards
2022 APIsecure_Securing APIs with Open Standards
 
Modern web application development with java ee 7
Modern web application development with java ee 7Modern web application development with java ee 7
Modern web application development with java ee 7
 
Building scalable applications with angular js
Building scalable applications with angular jsBuilding scalable applications with angular js
Building scalable applications with angular js
 
Enabling IoT Devices’ Hardware and Software Interoperability, IPSO Alliance (...
Enabling IoT Devices’ Hardware and Software Interoperability, IPSO Alliance (...Enabling IoT Devices’ Hardware and Software Interoperability, IPSO Alliance (...
Enabling IoT Devices’ Hardware and Software Interoperability, IPSO Alliance (...
 
Microsoft power point automation-opensourcetestingtools_matrix-1
Microsoft power point   automation-opensourcetestingtools_matrix-1Microsoft power point   automation-opensourcetestingtools_matrix-1
Microsoft power point automation-opensourcetestingtools_matrix-1
 
Microsoft power point automation-opensourcetestingtools_matrix-1
Microsoft power point   automation-opensourcetestingtools_matrix-1Microsoft power point   automation-opensourcetestingtools_matrix-1
Microsoft power point automation-opensourcetestingtools_matrix-1
 
OpenAPI and gRPC Side by-Side
OpenAPI and gRPC Side by-SideOpenAPI and gRPC Side by-Side
OpenAPI and gRPC Side by-Side
 
LF_APIStrat17_OpenAPI and gRPC Side-by-Side
LF_APIStrat17_OpenAPI and gRPC Side-by-SideLF_APIStrat17_OpenAPI and gRPC Side-by-Side
LF_APIStrat17_OpenAPI and gRPC Side-by-Side
 
PyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsPyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web Applications
 
N api-node summit-2017-final
N api-node summit-2017-finalN api-node summit-2017-final
N api-node summit-2017-final
 
N-API NodeSummit-2017
N-API NodeSummit-2017N-API NodeSummit-2017
N-API NodeSummit-2017
 
Tutorial: Writing Sencha Touch Mobile Apps using ]project-open[
Tutorial: Writing Sencha Touch Mobile Apps using ]project-open[Tutorial: Writing Sencha Touch Mobile Apps using ]project-open[
Tutorial: Writing Sencha Touch Mobile Apps using ]project-open[
 

Mehr von Intesys

Mehr von Intesys (8)

Experience API: il caso del CMS Headless Liferay di Rafael Lluis
Experience API: il caso del CMS Headless Liferay di Rafael LluisExperience API: il caso del CMS Headless Liferay di Rafael Lluis
Experience API: il caso del CMS Headless Liferay di Rafael Lluis
 
API Design: il must-have per governare un’Architettura Headless
API Design: il must-have per governare un’Architettura HeadlessAPI Design: il must-have per governare un’Architettura Headless
API Design: il must-have per governare un’Architettura Headless
 
Abilitare la digital transformation con una API architecture
Abilitare la digital transformation con una API architectureAbilitare la digital transformation con una API architecture
Abilitare la digital transformation con una API architecture
 
Ottimizzare i processi di vendita con un configuratore basato su Single Page ...
Ottimizzare i processi di vendita con un configuratore basato su Single Page ...Ottimizzare i processi di vendita con un configuratore basato su Single Page ...
Ottimizzare i processi di vendita con un configuratore basato su Single Page ...
 
La struttura di un'Architettura IT orientata alle API
La struttura di un'Architettura IT orientata alle API La struttura di un'Architettura IT orientata alle API
La struttura di un'Architettura IT orientata alle API
 
Quando la trasformazione digitale passa attraverso una API Architecture.
Quando la trasformazione digitale passa attraverso una API Architecture. Quando la trasformazione digitale passa attraverso una API Architecture.
Quando la trasformazione digitale passa attraverso una API Architecture.
 
Digital Strategy Integrata nel B2B - Intesys Global Marketing Summit
Digital Strategy Integrata nel B2B - Intesys Global Marketing SummitDigital Strategy Integrata nel B2B - Intesys Global Marketing Summit
Digital Strategy Integrata nel B2B - Intesys Global Marketing Summit
 
Enterprise Mobility: approccio strategico ai progetti mobile
Enterprise Mobility: approccio strategico ai progetti mobileEnterprise Mobility: approccio strategico ai progetti mobile
Enterprise Mobility: approccio strategico ai progetti mobile
 

Kürzlich hochgeladen

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Kürzlich hochgeladen (20)

Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 

JHipster Beyond CRUD - JHipster Conf' 2019

  • 1. Jhipster Beyond CRUD API First for Enterprise 2 7 / 0 6 / 2 0 1 9 - I N T E S Y S This material has been prepared by personnel of Intesys S.r.l. and is provided on a confidential basis. All the materials, animations, graphics and concepts may not be used, reproduced, redistributed or transmitted, in whole or in part, without prior written permission from the owner. Any unauthorized use is strictly prohibited.
  • 2. W H O A R E W E ? Who we are Paolo Quaglia senior project manager and software architect - @p_quail Enrico Costanzi senior software developer - @enricocostanzi
  • 3. W H O A R E W E ? Italian 100 employees company Enterprise industry: Banks, insurance companies, manufacturing Our Development Pattern: Design to Deliver
  • 4. W H O A R E W E ? • We started with Jhipster in 2017 • 3rd Jhipster Bronze Sponsor • ~10 developers on average working with Jhipster • 5 projects running in production • 3 big project in Development phase • 2 Jhipster modules published • More modules/blueprints – work in progress • Some contributions to the main generator Intesys & Jhipster
  • 6. I N T E S Y S & J H I P S T E R 2017
  • 7. I N T E S Y S & J H I P S T E R 2017 • Angular Monolith (Single Node) • Jhipster 4.10.1 • 12 entities • ~200 users • No swagger endpoints • 3 Roles • No native queries • Local Cache • 2 dev teams involved
  • 8. I N T E S Y S & J H I P S T E R 2019 • React Monolith (multiple nodes) • Jhipster 5.8.2 • 120 entities (2 JDL files) • ~4000 users • 100 OpenAPI endpoints • 7 roles • Many native queries • Distributed cache • 5 dev teams involved
  • 10. A P I D R I V E N E N T E R P R I S E Enterprise Systems (SAP, AS400, TIBCO, API Gateways) Legacy databases
  • 11. A G E N D A • Why Beyond CRUD? • Code First Jhipster • API First Jhipster • Modules Demo • Testcontainers & Jhipster Agenda
  • 13. B E Y O N D C R U D UserJWTController AccountResource UserResource Entity1Resource Entity1Service Entity1Repository Entity1ResourceExt Entity1ServiceExt Entity1RepoExt CustomController1 UserService UserRepository CustomService1 CustomController2 CustomService2 UserResourceExt UserServiceExt
  • 14. How do I make life easy for API consumers?
  • 15. B E Y O N D C R U D • Interoperability • Productivity • User Experience (UX) • Developer Experience (DX) We need
  • 17. C O D E F I R S T J H I P S T E R UserJWTController AccountResource UserResource Entity1Resource Entity1ResourceExt CustomController1 CustomController2 UserResourceExt Swagger UI & Springfox /v2/api-docs
  • 19. C O D E F I R S T J H I P S T E R Split your Swagger specs /v2/api-docs?group=auth /v2/api-docs?group=admin /v2/api-docs UserJWTController AccountResource UserResource Entity1Resource Entity1ResourceExt CustomController1 CustomController2 UserResourceExt
  • 20. C O D E F I R S T J H I P S T E R Split your Swagger specs /v2/api-docs?group=auth /v2/api-docs?group=admin /v2/api-docs UserJWTController AccountResource UserResource Entity1Resource Entity1ResourceExt CustomController1 CustomController2 UserResourceExt @Bean public Docket authDocket() { Docket docket = new Docket(DocumentationType.SWAGGER_2) .groupName("auth") .forCodeGeneration(true) .directModelSubstitute(java.nio.ByteBuffer.class, String.class) .directModelSubstitute(URI.class, String.class) .directModelSubstitute(StatusType.class, Integer.class) .genericModelSubstitutes(ResponseEntity.class) .additionalModels(typeResolver.resolve(Problem.class)) .select() .paths(Predicates.or( regex("/api/account.*"), regex("/api/authenticate.*"), regex("/api/activate.*"), regex("/api/register.*")) ) .build(); return docket; }
  • 21. C O D E F I R S T J H I P S T E R Export your Swagger specs UserJWTController AccountResource UserResource Entity1Resource Entity1ResourceExt CustomController1 CustomController2 UserResourceExt account-spec.json default-spec.json account-spec.json
  • 22. C O D E F I R S T J H I P S T E R Export your Swagger specs UserJWTController AccountResource UserResource Entity1Resource Entity1ResourceExt CustomController1 CustomController2 UserResourceExt account-spec.json default-spec.json account-spec.json @SpringBootTest(classes = JhipetstoreApp.class) @ActiveProfiles(value = {JHipsterConstants.SPRING_PROFILE_SWAGGER}) public class OpenApiSpecGeneratorIT { @Autowired DocumentationCache documentationCache; @Autowired ServiceModelToSwagger2Mapper mapper; @Autowired JsonSerializer jsonSerializer; @Test void createOpenApiJsonSpec() throws IOException { for (Map.Entry<String, Documentation> documentationEntry : documentationCache.all().entrySet()) { String groupName = documentationEntry.getKey(); Documentation documentation = documentationEntry.getValue(); Swagger swagger = mapper.mapDocumentation(documentation); Json spec = jsonSerializer.toJson(swagger); File specsDir = new File("target/swagger-specs"); if (!specsDir.exists()) specsDir.mkdirs(); IOUtils.write(spec.value().getBytes(), new FileOutputStream("target/swagger-specs/” + groupName + «-spec.json")); } } }
  • 23. C O D E F I R S T - C O N T R A C T D R I V E N C O M M U N I C A T I O N UserJWTController AccountResource UserResource Entity1Resource Entity1Service Entity1Repository Entity1ResourceExt Entity1ServiceExt Entity1RepoExt CustomController1 UserService UserRepository CustomService1 CustomController2 CustomService2 UserResourceExt UserServiceExt
  • 24. B E Y O N D C R U D Code First • API Consumers must wait for specs to be exposed or exported • Only Swagger v2 support (OpenAPI 3 generation is WIP) • Springfox scanning is slow with lots of controllers • Security rules must be coded in dockets
  • 26. A P I F I R S T J H I P S T E R API First • Design • API Design before writing code • Interoperability • Helps detecting breaking changes • Developer Experience • Decoupling client/server development • Developers contribute to API definition • Approval process during API design • User Experience • API design with UX/UI in mind
  • 27. 27 A P I F I R S T J H I P S T E R Server side code generation from swagger / openapi specifications ReadPetsApi ReadPetApiDelegate API First Jhipster src/main/resources/swagger/api.yml ReadPetsApiDelegateImpl ReadPetsApiController
  • 28. A P I F I R S T modelNameSuffix: avoid DTOS with the same class name: • PetDTO (Jhipster) • PetApiDto (OpenAPI DTO) useTags: Groups the OpenAPI endpoints by tag (not by path prefix) OpenAPI Generator Configuration <groupId>org.openapitools</groupId> <artifactId>openapi-generator-maven-plugin</artifactId> <version>${openapi-generator-maven-plugin.version}</version> <executions> <execution> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>…/resources/swagger/api.yml</inputSpec> <generatorName>spring</generatorName> … <modelNameSuffix>ApiDTO</modelNameSuffix> <configOptions> <delegatePattern>true</delegatePattern> <title>jhipetstore</title> <useTags>true</useTags> </configOptions> </configuration> </execution> </executions> </plugin>
  • 29. C O D E F I R S T A N D A P I F I R S T What changed? UserJWTController AccountResource UserResource Entity1Resource Entity1ResourceExt CustomController1 CustomController2 UserResourceExt OpenAPIController1 OpenAPIController2 UserJWTController AccountResource UserResource Entity1Resource Entity1ResourceExt UserResourceExt
  • 30. C O D E F I R S T A N D A P I F I R S T UserJWTController AccountResource UserResource Entity1Resource Entity1Service Entity1Repository Entity1ResourceExt Entity1ServiceExt Entity1RepoExt UserService UserRepository CustomAPIService1 UserResourceExt UserServiceExt OpenAPIController1 OpenAPIController2 CustomAPIService2 JDL Code First API First
  • 31. C O D E F I R S T A N D A P I F I R S T Jhipster Frontend OpenAPIController1 OpenAPIController2 UserJWTController AccountResource UserResource Entity1Resource Entity1ResourceExt UserResourceExt JDL APIs: • Jhipster CRUD • Jhipster Administration • Customizations API First Endpoints (generated client SDK): • Custom Pages • Design First
  • 32. C O D E F I R S T A N D A P I F I R S T External Apps – API + Code First OpenAPIController1 OpenAPIController2 UserJWTController AccountResource UserResource Entity1Resource Entity1ResourceExt UserResourceExt External Backend Applications Mobile Apps Custom Single Page Applications
  • 33. C O D E F I R S T A N D A P I F I R S T External Apps – API First only OpenAPIController1 OpenAPIController2 UserJWTController AccountResource UserResource Entity1Resource Entity1ResourceExt UserResourceExt External Backend Applications Mobile Apps Custom Single Page Applications
  • 34. A P I F I R S T • Code duplication • Jhipster DTOs ~= OpenAPI DTOs • Basic CRUD Operations have to be rewritten in the spec • Metamodel Filtering and pagination (coded in the spec) • Authentication (duplicated endpoints in some cases) API First Limitations
  • 35. Demo
  • 36. D E M O Customizing Using Modules OpenAPIController1 OpenAPIController2 OpenAPIController1 OpenAPIController2 Generated by OpenAPI Generator Generated by Springfox Designed specs Designed specs • api.yml served statically (not generated by Springfox) by a dedicated endpoint • Replaces Swagger UI 2 with Swagger UI 3 (iframe) • API version tag published in consul or Jhipster registry
  • 37. D E M O • Jhipster submodule to generate client code from swagger/openapi specifications • Integration of generator-jhipster-swagger-cli in the main generator • Wraps the official npm module openapi-generator-cli • Supports backend client generation (Feign clients) • Future steps: generate client code for Angular / React Jhipster OpenAPI Client (Preview) $ jhipster openapi-client
  • 39. T E S T C O N T A I N E R S Testcontainers “Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container” Jhipster Integration Tests • Native SQL Queries & Functions • Liquibase changelogs
  • 40. T E S T C O N T A I N E R S <dependency> <groupId>org.testcontainers</groupId> <artifactId>postgresql</artifactId> <version>1.11.3</version> <scope>test</scope> </dependency> The easy way jdbc:tc:postgresql:11.3://localhost:5432/jhipetstore org.testcontainers.jdbc.ContainerDatabaseDriver 1. add dependency 2. change test properties 3. ./mvnw verify 4. DONE! ☺
  • 41. T E S T C O N T A I N E R S The custom way jdbc:tc:postgresql:11.3://localhost:5432/jhipetstore org.testcontainers.jdbc.ContainerDatabaseDriver @TestConfiguration @Profile("testcontainers") public class IntegrationTestsConfiguration { @Bean public DataSource dataSource() { dbContainer = new MSSQLServerContainer("my-docker-account/mssql-server-custom:latest") .withPassword("yourStrong(!)Password"); dbContainer.start(); //starts the container String jdbcUrl = dbContainer.getJdbcUrl(); logger.info("Database started, creating datasource for url: '{}'", jdbcUrl); HikariDataSource dataSource = new HikariDataSource(); dataSource.setJdbcUrl(jdbcUrl); dataSource.setUsername(dbContainer.getUsername()); dataSource.setPassword(dbContainer.getPassword()); dataSource.setDriverClassName(dbContainer.getDriverClassName()); dataSource.setAutoCommit(false); return dataSource; } generator-jhipster-testcontainers
  • 42. T E S T C O N T A I N E R S The custom way jdbc:tc:postgresql:11.3://localhost:5432/jhipetstore org.testcontainers.jdbc.ContainerDatabaseDriver @TestConfiguration @Profile("testcontainers") public class IntegrationTestsConfiguration { @Bean public DataSource dataSource() { dbContainer = new MSSQLServerContainer("my-docker-account/mssql-server-custom:latest") .withPassword("yourStrong(!)Password"); dbContainer.start(); //starts the container String jdbcUrl = dbContainer.getJdbcUrl(); logger.info("Database started, creating datasource for url: '{}'", jdbcUrl); HikariDataSource dataSource = new HikariDataSource(); dataSource.setJdbcUrl(jdbcUrl); dataSource.setUsername(dbContainer.getUsername()); dataSource.setPassword(dbContainer.getPassword()); dataSource.setDriverClassName(dbContainer.getDriverClassName()); dataSource.setAutoCommit(false); return dataSource; } generator-jhipster-testcontainers $ yo jhipster-testcontainers $ ./mvnw verify -Dspring.profiles.active=testcontainers
  • 43. Recap
  • 44. A P I F I R S T • CRUD stack is the foundation of your APP • How CRUD and OpenAPI layers coexist • Go API First only for mission critical APIs • Use Testcontainers • Share your modules ☺ Recap
  • 45. A P I F I R S T • Jhipster Conf 2018 • Connect your JHipster apps to APIs with Swagger and gRPC by Christophe Bornet (https://www.youtube.com/watch?v=XWa-53-mDwY) • Custom and Generated Code Side by Side by Antonio Goncalves (https://www.youtube.com/watch?v=9WVpwIUEty0) • generator-jhipster-apiutils module • https://www.npmjs.com/package/generator-jhipster-apiutils • Testcontainers & Jhipster • https://www.youtube.com/watch?time_continue=3&v=L_i61qTg510 • https://atomfrede.gitlab.io/2019/05/jhipster-with-testcontainers/ • https://www.npmjs.com/package/generator-jhipster-testcontainers • https://github.com/danielgtaylor/apisprout • Demo Code Samples: • https://github.com/intesys/jhipsterconf2019-petstore-demo • https://github.com/intesys/jhipsterconf2019-petstore-client References
  • 46. Intesys S.r.l. Via Roveggia, 122/A - 37136 Verona VR T. +39 045 503 663 F. +39 045 503 604 @ info@intesys.it intesys.it Enrico Costanzi S e n i o r s o f t w a r e d e v e l o p e r enrico.costanzi@intesys.it @enricocostanzi Paolo Quaglia S e n i o r P r o j e c t M a n a g e r a n d A r c h i t e c t paolo.quaglia@intesys.it @p_quail