Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

When Enterprise Java Micro Profile meets Angular

4,626 views

Published on

Antonio is a Java developer and knows nothing about user interfaces. He uses his Mac to develop Java EE micro-services, runs them with WildFly Swarm, packages in the Docker and exposes beautiful REST APIs.

Sébastien is a TypeScript developer and knows nothing about Java. Employed at Microsoft, he uses his PC to develop beautiful user interfaces with TypeScript and Angular to invoke the services REST exposed by Antonio.

This university is intended for Java and Angular developers who want to learn how to use a Angular / TypeScript front-end with a Java / MicroProfile back-end. It is composed of two parts:

1) More theoretical: presentation of the Enterprise Micro Profile, WildFly Swarm, the TypeScript syntax and Angular.

2) More practical: development of an Angular application using several REST back-ends (JAX-RS, JSon: API, Swagger, Cors, Hateoas, ETag, JWT, Traeffik).

Published in: Software
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

When Enterprise Java Micro Profile meets Angular

  1. 1. #devoxxfr #ngjava @sebastienpertus @agoncal Enterprise Java MicroProfile TypeScript and Angular Sebastien Pertus Antonio Goncalves
  2. 2. #devoxxfr #ngjava @sebastienpertus @agoncal Agenda • Enterprise Java MicroProfile • TypeScript • Docker • Angular 2 • Break • Exposing & consuming REST APIs with Angular 2 • Tips and tricks: • APIs, Swagger, Cors, Hateoas, Etag, JWT, Scaling Ask questions
  3. 3. #devoxxfr #ngjava @sebastienpertus @agoncal Sebastien Pertus • Microsoft Technical Evangelist • OSS Lover • Full Stack developer • Node.JS & .Net Core advocate • SQL Server man • Develops on Windows (yeah yeah)
  4. 4. #devoxxfr #ngjava @sebastienpertus @agoncal Antonio Goncalves • Java Champion • Loves back-end • Hates front-end • Develops on Mac
  5. 5. #devoxxfr #ngjava @sebastienpertus @agoncal
  6. 6. #devoxxfr #ngjava @sebastienpertus @agoncal
  7. 7. #devoxxfr #ngjava @sebastienpertus @agoncal The Conference App
  8. 8. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time ! The Conference App https://github.com/agoncal/agoncal- application-conference
  9. 9. #devoxxfr #ngjava @sebastienpertus @agoncal Optimizing Enterprise Java for a Microservices Architecture
  10. 10. #devoxxfr #ngjava @sebastienpertus @agoncal Fundamental Shifts in Computing Cloud Microservices Reduce time to market Address unpredictable loads Pay as you go Containerization Deliver new features more quickly Smaller, more agile teams Deliver business features as discrete services Scale services independently
  11. 11. #devoxxfr #ngjava @sebastienpertus @agoncal • Began as a of independent discussions • Many “microservices” efforts exist in Java EE • WildFly Swarm • WebSphere Liberty • Payara • TomEE • New features to address microservices architectures • Java EE already being used for microservices… • ...but we can do better MicroProfile Background
  12. 12. #devoxxfr #ngjava @sebastienpertus @agoncal Release Schedule Sep 2016 MicroProfile 1.0 Q4 2016 2017 2017 Move to Foundation MicroProfile 1.1 MicroProfile 1.2 JAX-RS CDI JSON-P
  13. 13. #devoxxfr #ngjava @sebastienpertus @agoncal MicroProfile 1.1 Underway Security: JWT Token Exchange Health Check Configuration Fault Tolerance Second Quarter 2017!
  14. 14. #devoxxfr #ngjava @sebastienpertus @agoncal
  15. 15. #devoxxfr #ngjava @sebastienpertus @agoncal WildFly Swarm • Based on good old JBoss AS • « Rightsize your services » • Bundles several fractions • Java EE • Netflix OSS (Ribbon, Hystrix, RxJava) • Spring • Logstash • Swagger • ...
  16. 16. #devoxxfr #ngjava @sebastienpertus @agoncal Setting up Swarm and MicroProfile <profile> <id>swarm</id> <dependencies><dependency> <groupId>org.wildfly.swarm</groupId> <artifactId>microprofile</artifactId> </dependency></dependencies> <build> <plugins><plugin> <groupId>org.wildfly.swarm</groupId> <artifactId>wildfly-swarm-plugin</artifactId> </plugin></plugins> </build> </profile>
  17. 17. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time ! Skinny War Fat Jar
  18. 18. #devoxxfr #ngjava @sebastienpertus @agoncal TypeScript: JavaScript that Scales
  19. 19. #devoxxfr #ngjava @sebastienpertus @agoncal BRENDAN EICH ANDERS HEJLSBERG Do you know those guys ? Javascript creator CTO / CEO Mozilla Foundation Brave Software CEO C# creator Technical Fellow @ Microsoft TypeScript creator and lead team
  20. 20. #devoxxfr #ngjava @sebastienpertus @agoncal
  21. 21. #devoxxfr #ngjava @sebastienpertus @agoncal ES6 / EcmaScript 2015 / ES2015 ES6 is the most important update of JavaScript Brendan Eich : - “We want to go faster. “ - “Every year, a new spec that will be shipped in nighty versions of moderns browsers”
  22. 22. #devoxxfr #ngjava @sebastienpertus @agoncal Ecmascript evolution ES 8 ES 7 (ES 2016) ES 6 (ES 2015) ES 5 ES 3 Core features 1997 ~~ 1999 new functions strict mode, json 2009 class, promises, generators, arrow functions, new syntax and concepts … 2015 Exponential (**), array.includes, 2016
  23. 23. #devoxxfr #ngjava @sebastienpertus @agoncal Rise of the transpilers: Typescript 2.0
  24. 24. #devoxxfr #ngjava @sebastienpertus @agoncal TRANSPILER COMPILER Transpiler vs Compiler is a specific term for taking source code written in one language and transforming into another language that has a similar level of abstraction TypeScript (subclass of JavaScript) to JavaScript is the general term for taking source code written in one language and transforming into another C# to IL Java to ByteCode "CoffeeScript is to Ruby as TypeScript is to Java/C#/C++." - Luke Hoban Reference : Steve Fenton – 2012 - https://www.stevefenton.co.uk/2012/11/compiling-vs-transpiling
  25. 25. #devoxxfr #ngjava @sebastienpertus @agoncal A statically typed superset of JavaScript that compiles to plain JavaScript. Oh wait … that transpiles 
  26. 26. B R O W S E R H O S T O S
  27. 27. #devoxxfr #ngjava @sebastienpertus @agoncal Open Source
  28. 28. #devoxxfr #ngjava @sebastienpertus @agoncal
  29. 29. #devoxxfr #ngjava @sebastienpertus @agoncal The feature gap
  30. 30. #devoxxfr #ngjava @sebastienpertus @agoncal TypeScript IDE
  31. 31. #devoxxfr #ngjava @sebastienpertus @agoncal One year, four releases 1.5 1.6 1.7 1.8
  32. 32. #devoxxfr #ngjava @sebastienpertus @agoncal TypeScript 2.0 • Control flow based type analysis • Non-nullable types • Async/await downlevel support • Readonly properties • Private and protected Constructor • Type “never”
  33. 33. #devoxxfr #ngjava @sebastienpertus @agoncal TypeScript 2.1, 2.2 • New JS language service in Visual Studio • Better and more refactoring support • Extensions methods • Mixin classes • Better .jsx react native support
  34. 34. #devoxxfr #ngjava @sebastienpertus @agoncal Nullable types number string boolean
  35. 35. #devoxxfr #ngjava @sebastienpertus @agoncal Non-nullable types number string boolean
  36. 36. #devoxxfr #ngjava @sebastienpertus @agoncal Non-nullable types number string boolean undefined null
  37. 37. #devoxxfr #ngjava @sebastienpertus @agoncal Non-nullable types string undefined null string | null | undefined
  38. 38. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time ! Non Nullables Types Control Flow Async / await
  39. 39. #devoxxfr #ngjava @sebastienpertus @agoncal
  40. 40. #devoxxfr #ngjava @sebastienpertus @agoncal Docker • « Build, Ship, Run » • Containers, containers, containers • Docker to run containers • Docker-compose to compose several containers • WildFly containers • JRE container
  41. 41. #devoxxfr #ngjava @sebastienpertus @agoncal Dockerfile Skinny War FROM jboss/wildfly:10.1.0.Final EXPOSE 8080 # Setting the Wildfly Admin console (user/pwd admin/admin) RUN $JBOSS_HOME/bin/add-user.sh admin admin --silent CMD $JBOSS_HOME/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0 COPY venue.war $JBOSS_HOME/standalone/deployments/
  42. 42. #devoxxfr #ngjava @sebastienpertus @agoncal Dockerfile Far Jar FROM openjdk:8-jre-alpine EXPOSE 8080 COPY venue-swarm.jar /opt/venue-swarm.jar ENTRYPOINT ["java", "-jar", "/opt/venue-swarm.jar"]
  43. 43. #devoxxfr #ngjava @sebastienpertus @agoncal Dockerfile Angular Distribution FROM nginx EXPOSE 80 COPY ./dist /usr/share/nginx/html
  44. 44. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time ! Skinny War Image Fat Jar Image
  45. 45. #devoxxfr #ngjava @sebastienpertus @agoncal
  46. 46. #devoxxfr #ngjava @sebastienpertus @agoncal
  47. 47. #devoxxfr #ngjava @sebastienpertus @agoncal Angular : In a nutshell Modules Components Services
  48. 48. #devoxxfr #ngjava @sebastienpertus @agoncal Angular Component
  49. 49. #devoxxfr #ngjava @sebastienpertus @agoncal Angular Module
  50. 50. #devoxxfr #ngjava @sebastienpertus @agoncal Angular Dependency Injection
  51. 51. #devoxxfr #ngjava @sebastienpertus @agoncal Angular & Webpack
  52. 52. #devoxxfr #ngjava @sebastienpertus @agoncal ES7 THEN ES8 PROPOSAL ALREADY IMPLEMENTED IN TS Decorators Pattern that allow us to extend / modify the behavior of a class / function / propery As you can see …. It’s used A LOT in Angular 2
  53. 53. #devoxxfr #ngjava @sebastienpertus @agoncal Decorators class Person { public lastName: string; public firstName: string; constructor(ln: string, fn: string) { this.lastName = ln; this.firstName = fn; } @log(false) public getFullName(fnFirst: boolean = true) { if (fnFirst) return this.firstName + " " + this.lastName; else return this.lastName + " " + this.firstName; } }
  54. 54. #devoxxfr #ngjava @sebastienpertus @agoncal Decorators function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { var desc = { value: function (...args: any[]) { // get the params var params = args.map(arg => JSON.stringify(arg)).join(); // get the result var result = descriptor.value.apply(this, args); var resultString = JSON.stringify(result); console.log(`function ${propertyKey} invoked. Params: ${params}. Result: ${resultString}`); return result; } } return desc; }
  55. 55. #devoxxfr #ngjava @sebastienpertus @agoncal Angular CLI Angular Command Line Interface
  56. 56. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time ! Angular CLI - Component - Service
  57. 57. #devoxxfr #ngjava @sebastienpertus @agoncal Agenda • Enterprise Java MicroProfile • TypeScript • Docker • Angular 2 • Break • Exposing & consuming REST APIs with Angular 2 • Tips and tricks: • APIs, Swagger, Cors, Hateoas, Etag, JWT, Scaling Ask questions
  58. 58. #devoxxfr #ngjava @sebastienpertus @agoncal
  59. 59. #devoxxfr #ngjava @sebastienpertus @agoncal Exposing REST Endpoints
  60. 60. #devoxxfr #ngjava @sebastienpertus @agoncal Conference Micro Services
  61. 61. #devoxxfr #ngjava @sebastienpertus @agoncal Exposing « beautiful » APIs • JSon:API • OData • Jsend • HAL • CPHL • SIREN • Google’s JSon Style Guide • Do it your own
  62. 62. #devoxxfr #ngjava @sebastienpertus @agoncal « Kind of » JSon:API GET http://host/schedule/api/sessions GET http://host/schedule/api/sessions?page=2 GET http://host/schedule/api/sessions?sort=title GET http://host/schedule/api/sessions?sort=-title,date POST http://host/schedule/api/sessions GET http://host/schedule/api/sessions/abcd REMOVE http://host/schedule/api/sessions/abcd GET http://host/speaker/api/speakers/abcd GET http://host/speaker/api/speakers/abcd?expand=false
  63. 63. #devoxxfr #ngjava @sebastienpertus @agoncal
  64. 64. #devoxxfr #ngjava @sebastienpertus @agoncal Swagger • Simple yet powerful representation of your RESTful API • API documentation • What do you call? • What are the parameters? • What are the status code? • Contract written in JSon (or Yaml) • Donated to the Open API Initiative
  65. 65. #devoxxfr #ngjava @sebastienpertus @agoncal Swagger’s ecosystem
  66. 66. #devoxxfr #ngjava @sebastienpertus @agoncal Swagger APIs @Path("/speakers") @Api(description = "Speakers REST Endpoint") public class SpeakerEndpoint { @POST @ApiOperation(value = "Adds a new speaker to the conference") @ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid input")}) public Response add(@NotNull Speaker speaker) { ... } @GET @Path("/{id}") @ApiOperation(value = "Finds a speaker by ID") public Response retrieve(@PathParam("id") String id) { ... } }
  67. 67. #devoxxfr #ngjava @sebastienpertus @agoncal Swagger Maven Plugin <plugin> <groupId>com.github.kongchen</groupId> <artifactId>swagger-maven-plugin</artifactId> <configuration> <apiSources><apiSource> <locations>org.agoncal.conference.venue.rest</locations> <schemes>http,https</schemes> <host>localhost:8080</host> <basePath>/api</basePath> <info> <title>Room</title> <version>1.0.0</version> <description>Rooms of the venue</description> </info>
  68. 68. #devoxxfr #ngjava @sebastienpertus @agoncal
  69. 69. #devoxxfr #ngjava @sebastienpertus @agoncal Swagger TypeScript for Angular generation public add(room: models.Room): Observable<{}> { return this.http.request(path, requestOptions) .map((response: Response) => { … }); } public retrieve(id: string, extraHttpRequestParams?: any): Observable<models.Room> { return this.http.request(path, requestOptions) .map((response: Response) => { … }); }
  70. 70. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time ! Generate Angular from Swagger
  71. 71. #devoxxfr #ngjava @sebastienpertus @agoncal
  72. 72. #devoxxfr #ngjava @sebastienpertus @agoncal Proxy
  73. 73. #devoxxfr #ngjava @sebastienpertus @agoncal CORS • Cross-Origin Resource Sharing • Specification (https://www.w3.org/TR/cors/) • Access across domain-boundaries • JavaScript and web programming has grown • But the same-origin policy still remains • Prevents JavaScript from making requests across domain boundaries
  74. 74. #devoxxfr #ngjava @sebastienpertus @agoncal HTTP Header Access-Control-Allow-Origin Access-Control-Allow-Credentials Access-Control-Expose-Headers Access-Control-Max-Age Access-Control-Allow-Methods Access-Control-Allow-Headers Access-Control-Request-Method Access-Control-Request-Headers
  75. 75. #devoxxfr #ngjava @sebastienpertus @agoncal CORS @Provider public class CORSFilter implements ContainerResponseFilter { public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException { response.getHeaders().add("Access-Control-Allow-Origin", "*"); response.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization, Etag"); response.getHeaders().add("Access-Control-Allow-Credentials", "true"); response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); } }
  76. 76. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time !
  77. 77. #devoxxfr #ngjava @sebastienpertus @agoncal
  78. 78. #devoxxfr #ngjava @sebastienpertus @agoncal HateOAS • « Hypermedia as the engine of application state » • At its core is the concept of « hypermedia » • Or in other words: the idea of links • Client application goes from one state to the next by following a link • Runtime contract • Nothing in Java EE, maybe in MicroProfile • JAX-RS has a Link API
  79. 79. #devoxxfr #ngjava @sebastienpertus @agoncal Links links: { self: "http://host/schedule/api/sessions?page=1", first: "http://host/schedule/api/sessions?page=1", last: "http://host/schedule/api/sessions?page=14", next: "http://host/schedule/api/sessions?page=2", monday: "http://host/schedule/api/sessions/monday", tuesday: "http://host/schedule/api/sessions/tuesday" }, data: [ { links: { self: "http://host/schedule/api/sessions/uni_room9_tuesd" }, id: "uni_room9_tuesday_8_9h30_12h30", title: ”Java EE and Angular 2",
  80. 80. #devoxxfr #ngjava @sebastienpertus @agoncal http://www.iana.org/assignments/link-relations/link-relations.xml
  81. 81. #devoxxfr #ngjava @sebastienpertus @agoncal Links @XmlType(name = "links") public abstract class LinkableResource implements Identifiable { private Map<String, URI> links; public void addSelfLink(URI uri) { addLink(SELF, uri); } public void addCollectionLink(URI uri) { addLink(COLLECTION, uri); } }
  82. 82. #devoxxfr #ngjava @sebastienpertus @agoncal Links if (body.links) { this.links = {}; for (let key in body.links) { this.links[key] = body.links[key] !== undefined ? body.links[key] : null; } }
  83. 83. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time ! HateOAS
  84. 84. #devoxxfr #ngjava @sebastienpertus @agoncal
  85. 85. #devoxxfr #ngjava @sebastienpertus @agoncal Caching • HTTP has temporary storage (caching) • Reduce bandwidth usage • Reduce server load • Reduce perceived lag • ETags, or entity-tags: "conditional" requests. • Checksum • If-None-Match
  86. 86. #devoxxfr #ngjava @sebastienpertus @agoncal Etag Generation @GET @Path("/{id}") public Response retrieve(@PathParam("id") String id, @Context Request request) { Talk talk = talkRepository.findById(id); EntityTag etag = new EntityTag(talk.hashCode()); Response.ResponseBuilder preconditions = request.evaluatePreconditions(etag); if (preconditions == null) { preconditions = Response.ok(talk).tag(etag); } return preconditions.build(); }
  87. 87. #devoxxfr #ngjava @sebastienpertus @agoncal
  88. 88. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time ! ETag & caching
  89. 89. #devoxxfr #ngjava @sebastienpertus @agoncal
  90. 90. #devoxxfr #ngjava @sebastienpertus @agoncal JSon Web Token • Lightweigh token • Contains « some » data (claims) • Base64 • Encrypted • Passed in the HTTP Header • Sent at each request • Not in Java EE nor Microprofile (yet) • Many librairies
  91. 91. #devoxxfr #ngjava @sebastienpertus @agoncal A Token Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZ29uY2FsIiwiaXNzIjoi aHR0cDovL2NvbmZlcmVuY2UuZG9ja2VyLmxvY2FsaG9zd Do5MC9jb25mZXJlbmNlLWF0dGVuZGVlL2FwaS9hdHRlbm RlZXMvbG9naW4iLCJpYXQiOjE0Nzc0OTk3NTUsImV4cCI6 MTQ3NzUwMDY1NX0.aL0a_q5wC3cesBKhkXChg30zr3W WOsYhFhpJ0lQ479LtLjrPvTQiDH0N_YnFuARuEuy299S4u O0yXGmX0tSs-Q
  92. 92. #devoxxfr #ngjava @sebastienpertus @agoncal A Token Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZ29uY2FsIiwiaXNzIjoi aHR0cDovL2NvbmZlcmVuY2UuZG9ja2VyLmxvY2FsaG9zd Do5MC9jb25mZXJlbmNlLWF0dGVuZGVlL2FwaS9hdHRlbm RlZXMvbG9naW4iLCJpYXQiOjE0Nzc0OTk3NTUsImV4cCI6 MTQ3NzUwMDY1NX0.aL0a_q5wC3cesBKhkXChg30zr3W WOsYhFhpJ0lQ479LtLjrPvTQiDH0N_YnFuARuEuy299S4u O0yXGmX0tSs-Q
  93. 93. #devoxxfr #ngjava @sebastienpertus @agoncal A Token HEADER: { "alg": "HS512" } PAYLOAD:{ "sub": "agoncal", "iss": "http://host/attendee/api/login", "iat": 1477499755, "exp": 1477500655 } VERIFY SIGNATURE HMACSHA256(...)
  94. 94. #devoxxfr #ngjava @sebastienpertus @agoncal JWT Generation @Path("/attendees") public class AttendeeEndpoint { @POST @Path("/login") @Consumes(APPLICATION_FORM_URLENCODED) public Response auth(@FormParam("login") String login, @FormParam("password") String password) { // Authentication, security exception and so on... return Response.ok().header(AUTHORIZATION, "Bearer " + issueToken(login)).build(); } }
  95. 95. #devoxxfr #ngjava @sebastienpertus @agoncal Filter to Check the Token @JWTTokenNeeded @Provider @Priority(Priorities.AUTHENTICATION) public class JWTTokenNeededFilter implements ContainerRequestFilter{ public void filter(ContainerRequestContext ctx) { String auth = ctx.getHeaderString(HttpHeaders.AUTHORIZATION); if (auth == null || !authorizationHeader.startsWith("Bearer")) { throw new NotAuthorizedException("No Bearer"); } String token = auth.substring("Bearer".length()).trim(); Jwts.parser().setSigningKey(key).parseClaimsJws(token); } }
  96. 96. #devoxxfr #ngjava @sebastienpertus @agoncal Check the Token @Path("/ratings") public class RatingEndpoint { @JWTTokenNeeded @POST public Response rate(...) { } @GET public Response retrieve(...) { } }
  97. 97. #devoxxfr #ngjava @sebastienpertus @agoncal JWT Consumption return this.http .post(this.basePath, body, requestOptions) .map((response: Response) => { if (response.status !== 200) { return undefined; } this.jwt = response.headers.get('authorization'); if (!this.jwt) return undefined; return this.jwt; }) .catch((error: any) => { return undefined });
  98. 98. #devoxxfr #ngjava @sebastienpertus @agoncal @Injectable() export class AuthGuardService implements CanActivate { constructor(private authService: AuthService, private router: Router) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { let url: string = state.url; return this.checkLogin(url); } checkLogin(url: string): boolean { if (this.authService.isLoggedIn) { return true; } this.router.navigate(['/login'], { queryParams: { redirectTo: url } }); return false; } }
  99. 99. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time ! Passing a token around
  100. 100. #devoxxfr #ngjava @sebastienpertus @agoncal
  101. 101. #devoxxfr #ngjava @sebastienpertus @agoncal Scaling • Stateless architecture • No cookie • No HTTP session • No local cache • Stateless scales better than statefull • Clients can round robin • Dynamic proxy • Meet Traeffik
  102. 102. #devoxxfr #ngjava @sebastienpertus @agoncal
  103. 103. #devoxxfr #ngjava @sebastienpertus @agoncal Proxy
  104. 104. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time ! Traeffik
  105. 105. #devoxxfr #ngjava @sebastienpertus @agoncal
  106. 106. #devoxxfr #ngjava @sebastienpertus @agoncal Going in production with Angular • By default, Angular (in dev mode) is about … 4 mb ! • Angular cli and webpack will: • Uglify your JavaScript code • Create a standalone bundle file • Gzip compress • Apply a tree shaking to delete unused code (it’s not dead code, btw !) • Could use AOT compilation
  107. 107. #devoxxfr #ngjava @sebastienpertus @agoncal JIT vs AOT Compilation Source Code JIT Compilation Code Generation VM execution Source Code AOT Compilation Code Generation VM execution BUILD RUN
  108. 108. #devoxxfr #ngjava @sebastienpertus @agoncal With AOT, AN Angular project could be 60 – 70 % less code http://slides.com/wassimchegham/demystifying-ahead-of-time-compilation-in-angular-2-aot-jit#/32
  109. 109. #devoxxfr #ngjava @sebastienpertus @agoncal Demo Time ! Angular Production ready
  110. 110. #devoxxfr #ngjava @sebastienpertus @agoncal Conclusion • MicroProfile 1.1 will bring more MicroServices features • Configuration • Security: JWT Token Exchange • Health Check • Fault Tolerance • More to come
  111. 111. #devoxxfr #ngjava @sebastienpertus @agoncal
  112. 112. #devoxxfr #ngjava @sebastienpertus @agoncal Conclusion • Angular 4 • Native Script • TypeScript 2.x
  113. 113. #devoxxfr #ngjava @sebastienpertus @agoncal
  114. 114. #devoxxfr #ngjava @sebastienpertus @agoncal
  115. 115. #devoxxfr #ngjava @sebastienpertus @agoncal
  116. 116. #devoxxfr #ngjava @sebastienpertus @agoncal
  117. 117. #devoxxfr #ngjava @sebastienpertus @agoncal
  118. 118. #devoxxfr #ngjava @sebastienpertus @agoncal
  119. 119. #devoxxfr #ngjava @sebastienpertus @agoncal Enterprise Java MicroProfile TypeScript and Angular Sebastien Pertus Antonio Goncalves https://github.com/agoncal/agoncal-application-conference

×