SlideShare a Scribd company logo
Dynamic OpenAPIs with
Spring Cloud Gateway
Iván López
@ilopmar
@ilopmar
Iván López
Who am I?
● Iván López (@ilopmar)
● JVM Developer
● Staff Software Engineer at VMware
● @MadridGUG Coordinator
● Speaker: GeeCon, Codemotion, Devoxx, SpringOne,
RigaDevDays, CommitConf, Spring IO,...
🇪🇸🇮🇹🇬🇧🇦🇹🇨🇦🇧🇪🇨🇿🇺🇦🇩🇰🇸🇪🇺🇸🇷🇺🇪🇪🇱🇻🇭🇷🇵🇱🇹🇷🇷🇴🇧🇬
OpenAPI
@ilopmar
Iván López
OpenAPI Specification
● Old Swagger Specification
● API description format for REST APIs
● Endpoints, operations, parameters, authentication,...
● Programming language agnostic
● YAML or JSON
@ilopmar
Iván López
Swagger
● Set of opensource tools build around OpenApi Spec
● Swagger Editor
● Swagger UI
● Swagger Codegen
● Swagger Core, Parser,...
@ilopmar
Iván López
Why use OpenAPI?
● Standard widely used
● Huge userbase
● Stable implementation
● Swagger Codegen to generate server stub and
client libraries!
● Integrations with many languages, libraries and
frameworks
Spring Cloud
Gateway
@ilopmar
Iván López
What is an API Gateway?
● API proxy between an API Client and API Server
● Single entry point for the backend API and services
● Cross-cuttings concerns: security, rate-limiting,
monitoring, logging, metrics,...
@ilopmar
Iván López
Spring Cloud Gateway
● API Gateway for the Spring Ecosystem
● Built on top Spring Boot, WebFlux and Reactor
● Dynamic routing
● Route matching: Path, Method, Header, Host,...
● Filters
● Rate Limiting, Circuit Breaker
● Path Rewriting
@ilopmar
Iván López
Spring Cloud Gateway Basics
● Route, Predicate and Filter
● Route Predicates: Cookie, Header, Host, Method,
Path,...
● Gateway Factories: Add/Remove
Request/Response Header/Parameter, Rewrite
path
● Global and custom filters
● YAML configuration & Programmatic API
@ilopmar
Iván López
Spring Cloud Gateway examples
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Foo, some-value
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/?(?<segment>.*), /${segment}
The problem
“I just want to expose
the OpenAPI of my
application”
@ilopmar
Iván López
Current status
● Spring Cloud Gateway in front of all different services
● All services expose OpenAPI
● API First?
– Code -> OpenAPI
– OpenAPI -> Code
● Internal endpoints vs Public endpoints
● Manual configuration in SCG
@ilopmar
Iván López
Requirements
● Expose product Public OpenAPI in Gateway
● Aggregate endpoints from different services
● Public endpoints defined on every service
● Optionally rewrite some endpoints
● Expose only public schemas and not all of them
● Rewrite and group tags
● Update Public OpenAPI and routing must be dynamic
@ilopmar
Iván López
My approach
● I did a 1 week spike
● We use SCG OSS
● The feature is available in SCG Commercial: Only
Tanzu Application Service and Kubernetes
● We deploy on K8S but wanted to keep everything
agnostic: local development, on-premise,...
● Libraries to read/write OpenAPI specifications
● SCG Programmatic API
Solution
@ilopmar
Iván López
Every service defines...
● Which endpoint is made public
paths:
/pipelines:
post:
x-vmw-public: true
summary: Create a new pipeline definition
description: Given a pipeline, it creates an execution
graph and prepares it to be run
@ilopmar
Iván López
Every service defines...
● How an endpoint is rewritten
paths:
/reports:
get:
x-vmw-public: true
x-vmw-rewrite: /vulnerabilities/reports
summary: Get all reports, optionally filtered by artifact version
description: It returns a collection of report metadata...
@ilopmar
Iván López
Every service defines...
● How tags are rewritten
tags:
- name: products
description: Using these endpoints you can manage the products...
x-vmw-rewrite: inventory
- name: artifacts
description: Using these endpoints you can manage the artifacts...
x-vmw-rewrite: inventory
- name: artifact-versions
description: Using these endpoints you can manage the artifact versions...
x-vmw-rewrite: inventory
- name: inventory
description: Using these endpoints you can see the products, artifacts and
artifact versions and their relationships in your organization inventory
@ilopmar
Iván López
Every service defines...
● How tags are rewritten
tags:
- name: products
description: Using these endpoints you can manage the products...
x-vmw-rewrite: inventory
- name: artifacts
description: Using these endpoints you can manage the artifacts...
x-vmw-rewrite: inventory
- name: artifact-versions
description: Using these endpoints you can manage the artifact versions...
x-vmw-rewrite: inventory
- name: inventory
description: Using these endpoints you can see the products, artifacts and
artifact versions and their relationships in your organization inventory
@ilopmar
Iván López
OpenAPI creation
● Gateway polls services every 5 minutes
● Filter, transform and combine all the OpenAPI specs
● Creates Public OpenAPI specification on the fly
@ilopmar
Iván López
Expose OpenAPI
@GetMapping(value = "/v1/api.yml", produces = APPLICATION_X_YAML)
public ResponseEntity<String> v1() {
return openApiService.generateOpenApi()
.map(ResponseEntity::ok)
.orElseGet(() -> ResponseEntity.notFound().build());
}
@ilopmar
Iván López
Spring Cloud Gateway routes
@Bean
@RefreshScope
public RouteLocator routeLocator(RouteLocatorBuilder routeLocatorBuilder, RouteService routeService) {
RouteLocatorBuilder.Builder routeLocator = routeLocatorBuilder.routes();
List<GatewayRoute> gatewayRoutes = routeService.findGatewayRoutes();
for (GatewayRoute gatewayRoute : gatewayRoutes) {
routeLocator.route(gatewayRoute.routeId(), r -> r
.order(gatewayRoute.order())
.path(gatewayRoute.gatewayPath())
.and().method(gatewayRoute.openApiRoute().method())
.filters(gatewayFilterSpec -> gatewayFilterSpec.rewritePath(gatewayRoute.regexp(),
gatewayRoute.rewritePath())
)
.uri(gatewayRoute.openApiRoute().uri()));
}
return routeLocator.build();
}
● Routes refreshed dynamically
@ilopmar
Iván López
● Routes refreshed dynamically
Spring Cloud Gateway routes
@Bean
@RefreshScope
public RouteLocator routeLocator(RouteLocatorBuilder routeLocatorBuilder, RouteService routeService) {
RouteLocatorBuilder.Builder routeLocator = routeLocatorBuilder.routes();
List<GatewayRoute> gatewayRoutes = routeService.findGatewayRoutes();
for (GatewayRoute gatewayRoute : gatewayRoutes) {
routeLocator.route(gatewayRoute.routeId(), r -> r
.order(gatewayRoute.order())
.path(gatewayRoute.gatewayPath())
.and().method(gatewayRoute.openApiRoute().method())
.filters(gatewayFilterSpec -> gatewayFilterSpec.rewritePath(gatewayRoute.regexp(),
gatewayRoute.rewritePath())
)
.uri(gatewayRoute.openApiRoute().uri()));
}
return routeLocator.build();
}
@ilopmar
Iván López
Gateway Routes
public List<GatewayRoute> findGatewayRoutes() {
return openApiService.findOpenApiRoutes()
.stream()
.map(RouteConverter::convertOpenApiRouteToGatewayRoute)
.filter(Optional::isPresent)
.map(Optional::get)
.toList();
}
@ilopmar
Iván López
Example: Route conversion (I)
OpenApiRoute[
originalPath=/v1/reports
newPath=/v1/vulnerabilities/reports
method=GET
uri=https://vulnerability-service.xxxxxxxxxxxxx
]
GatewayRoute[
routeId=GET__/v1/vulnerabilities/reports
gatewayPath=/v1/vulnerabilities/reports
regexp=/v1/vulnerabilities/reports
rewritePath=/v1/reports
order=0
]
@ilopmar
Iván López
Example: Route conversion (II)
OpenApiRoute[
originalPath=/v1/target-platforms/{target_platform_id}
newPath=/v1/tp/{target_platform_id}
method=GET
uri=https://provisioning-service.xxxxxxxxxxxxx
]
GatewayRoute[
routeId=GET__/v1/tp/{target_platform_id}
gatewateyPath=/v1/tp/?*
regexp=/v1/tp/(?<id1>.*)
rewritePath=/v1/target-platforms/${id1}
order=10
]
@ilopmar
Iván López
Spring Cloud Gateway routes
@Bean
@RefreshScope
public RouteLocator routeLocator(RouteLocatorBuilder routeLocatorBuilder, RouteService routeService) {
RouteLocatorBuilder.Builder routeLocator = routeLocatorBuilder.routes();
List<GatewayRoute> openApiRoutes = routeService.findOpenApiRoutes();
for (GatewayRoute gatewayRoute : openApiRoutes) {
routeLocator.route(gatewayRoute.routeId(), r -> r
.order(gatewayRoute.order())
.path(gatewayRoute.gatewayPath())
.and().method(gatewayRoute.openApiRoute().method())
.filters(gatewayFilterSpec -> gatewayFilterSpec.rewritePath(gatewayRoute.regexp(),
gatewayRoute.rewritePath())
)
.uri(gatewayRoute.openApiRoute().uri()));
}
return routeLocator.build();
}
● Routes refreshed dynamically
@ilopmar
Iván López
Example: Gateway Routes (I)
OpenApiRoute[
originalPath=/v1/reports
newPath=/v1/vulnerabilities/reports
method=GET
uri=https://vulnerability-service...
]
GatewayRoute[
routeId=GET__/v1/vulnerabilities/reports
gatewateyPath=/v1/vulnerabilities/reports
regexp=/v1/vulnerabilities/reports
rewritePath=/v1/reports
order=0
]
routeLocator.route("GET__/v1/vulnerabilities/reports", r -> r
.order(0)
.path("/v1/vulnerabilities/reports")
.and().method("GET")
.filters(s -> s.rewritePath("/v1/vulnerabilities/reports", "/v1/reports"))
.uri("https://vulnerability-service.xxxxxxxxxxxxxxxxxx"));
@ilopmar
Iván López
Example: Gateway Routes (II)
OpenApiRoute[
originalPath=/v1/target-platforms/{target_platform_id}
newPath=/v1/tp/{target_platform_id}
method=GET
uri=https://provisioning-service...
]
GatewayRoute[
routeId=GET__/v1/tp/{target_platform_id}
gatewateyPath=/v1/tp/?*
regexp=/v1/tp/(?<id1>.*)
rewritePath=/v1/target-platforms/${id1}
order=10
]
routeLocator.route("GET__/v1/tp/{target_platform_id}", r -> r
.order(10)
.path("/v1/tp/?*")
.and().method("GET")
.filters(s -> s.rewritePath("/v1/tp/(?<id1>.*)", "/v1/target-platforms/${id1}"))
.uri("https://provisioning-service.xxxxxxxxxxxxxxx"));
Demo
@ilopmar
Iván López
Summary
Solved the problem
in one week
+1 year in Production
without problems
Reuse existing
OSS libraries
Platform agnostic Spring Cloud Gateway
is awesome
Public and Dynamic
OpenAPI
Thank you!
Questions?
Iván López
@ilopmar
lopez.ivan@gmail.com
https:/
/github.com/ilopmar
https:/
/bit.ly/springio-dynamic-apis

More Related Content

What's hot

Distributed Locking in Kubernetes
Distributed Locking in KubernetesDistributed Locking in Kubernetes
Distributed Locking in Kubernetes
Rafał Leszko
 
Intro to React
Intro to ReactIntro to React
Intro to React
Justin Reock
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
Ignacio Martín
 
Spring Security 5
Spring Security 5Spring Security 5
Spring Security 5
Jesus Perez Franco
 
Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooks
Maulik Shah
 
初探 OpenTelemetry - 蒐集遙測數據的新標準
初探 OpenTelemetry - 蒐集遙測數據的新標準初探 OpenTelemetry - 蒐集遙測數據的新標準
初探 OpenTelemetry - 蒐集遙測數據的新標準
Marcus Tung
 
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Matt Raible
 
Ansible presentation
Ansible presentationAnsible presentation
Ansible presentation
Suresh Kumar
 
Karate - Web-Service API Testing Made Simple
Karate - Web-Service API Testing Made SimpleKarate - Web-Service API Testing Made Simple
Karate - Web-Service API Testing Made Simple
VodqaBLR
 
Designing a complete ci cd pipeline using argo events, workflow and cd products
Designing a complete ci cd pipeline using argo events, workflow and cd productsDesigning a complete ci cd pipeline using argo events, workflow and cd products
Designing a complete ci cd pipeline using argo events, workflow and cd products
Julian Mazzitelli
 
Introduction to Ansible
Introduction to AnsibleIntroduction to Ansible
Introduction to Ansible
Knoldus Inc.
 
Scalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsScalability, Availability & Stability Patterns
Scalability, Availability & Stability Patterns
Jonas Bonér
 
톰캣 운영 노하우
톰캣 운영 노하우톰캣 운영 노하우
톰캣 운영 노하우
jieunsys
 
Springboot Microservices
Springboot MicroservicesSpringboot Microservices
Springboot Microservices
NexThoughts Technologies
 
Battle of the frameworks : Quarkus vs SpringBoot
Battle of the frameworks : Quarkus vs SpringBootBattle of the frameworks : Quarkus vs SpringBoot
Battle of the frameworks : Quarkus vs SpringBoot
Christos Sotiriou
 
[오픈소스컨설팅] 쿠버네티스와 쿠버네티스 on 오픈스택 비교 및 구축 방법
[오픈소스컨설팅] 쿠버네티스와 쿠버네티스 on 오픈스택 비교  및 구축 방법[오픈소스컨설팅] 쿠버네티스와 쿠버네티스 on 오픈스택 비교  및 구축 방법
[오픈소스컨설팅] 쿠버네티스와 쿠버네티스 on 오픈스택 비교 및 구축 방법
Open Source Consulting
 
Jenkins presentation
Jenkins presentationJenkins presentation
Jenkins presentation
Valentin Buryakov
 
Introduction to react native
Introduction to react nativeIntroduction to react native
Introduction to react native
Dani Akash
 
Spring Framework Petclinic sample application
Spring Framework Petclinic sample applicationSpring Framework Petclinic sample application
Spring Framework Petclinic sample application
Antoine Rey
 
12 factor app an introduction
12 factor app an introduction12 factor app an introduction
12 factor app an introduction
Krishna-Kumar
 

What's hot (20)

Distributed Locking in Kubernetes
Distributed Locking in KubernetesDistributed Locking in Kubernetes
Distributed Locking in Kubernetes
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
 
Spring Security 5
Spring Security 5Spring Security 5
Spring Security 5
 
Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooks
 
初探 OpenTelemetry - 蒐集遙測數據的新標準
初探 OpenTelemetry - 蒐集遙測數據的新標準初探 OpenTelemetry - 蒐集遙測數據的新標準
初探 OpenTelemetry - 蒐集遙測數據的新標準
 
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020
 
Ansible presentation
Ansible presentationAnsible presentation
Ansible presentation
 
Karate - Web-Service API Testing Made Simple
Karate - Web-Service API Testing Made SimpleKarate - Web-Service API Testing Made Simple
Karate - Web-Service API Testing Made Simple
 
Designing a complete ci cd pipeline using argo events, workflow and cd products
Designing a complete ci cd pipeline using argo events, workflow and cd productsDesigning a complete ci cd pipeline using argo events, workflow and cd products
Designing a complete ci cd pipeline using argo events, workflow and cd products
 
Introduction to Ansible
Introduction to AnsibleIntroduction to Ansible
Introduction to Ansible
 
Scalability, Availability & Stability Patterns
Scalability, Availability & Stability PatternsScalability, Availability & Stability Patterns
Scalability, Availability & Stability Patterns
 
톰캣 운영 노하우
톰캣 운영 노하우톰캣 운영 노하우
톰캣 운영 노하우
 
Springboot Microservices
Springboot MicroservicesSpringboot Microservices
Springboot Microservices
 
Battle of the frameworks : Quarkus vs SpringBoot
Battle of the frameworks : Quarkus vs SpringBootBattle of the frameworks : Quarkus vs SpringBoot
Battle of the frameworks : Quarkus vs SpringBoot
 
[오픈소스컨설팅] 쿠버네티스와 쿠버네티스 on 오픈스택 비교 및 구축 방법
[오픈소스컨설팅] 쿠버네티스와 쿠버네티스 on 오픈스택 비교  및 구축 방법[오픈소스컨설팅] 쿠버네티스와 쿠버네티스 on 오픈스택 비교  및 구축 방법
[오픈소스컨설팅] 쿠버네티스와 쿠버네티스 on 오픈스택 비교 및 구축 방법
 
Jenkins presentation
Jenkins presentationJenkins presentation
Jenkins presentation
 
Introduction to react native
Introduction to react nativeIntroduction to react native
Introduction to react native
 
Spring Framework Petclinic sample application
Spring Framework Petclinic sample applicationSpring Framework Petclinic sample application
Spring Framework Petclinic sample application
 
12 factor app an introduction
12 factor app an introduction12 factor app an introduction
12 factor app an introduction
 

Similar to Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud Gateway

OpenAPI and gRPC Side by-Side
OpenAPI and gRPC Side by-SideOpenAPI and gRPC Side by-Side
OpenAPI and gRPC Side by-Side
Tim Burks
 
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
LF_APIStrat
 
LCU14 310- Cisco ODP v2
LCU14 310- Cisco ODP v2LCU14 310- Cisco ODP v2
LCU14 310- Cisco ODP v2
Linaro
 
OpenAPI Extensions for OSLC
OpenAPI Extensions for OSLCOpenAPI Extensions for OSLC
OpenAPI Extensions for OSLC
LuisArmandoRamrezAgu
 
How to build a tool for operating Flink on Kubernetes
How to build a tool for operating Flink on KubernetesHow to build a tool for operating Flink on Kubernetes
How to build a tool for operating Flink on Kubernetes
AndreaMedeghini
 
Using JHipster 4 for generating Angular/Spring Boot apps
Using JHipster 4 for generating Angular/Spring Boot appsUsing JHipster 4 for generating Angular/Spring Boot apps
Using JHipster 4 for generating Angular/Spring Boot apps
Yakov Fain
 
apidays LIVE Australia 2020 - Have your cake and eat it too: GraphQL? REST? W...
apidays LIVE Australia 2020 - Have your cake and eat it too: GraphQL? REST? W...apidays LIVE Australia 2020 - Have your cake and eat it too: GraphQL? REST? W...
apidays LIVE Australia 2020 - Have your cake and eat it too: GraphQL? REST? W...
apidays
 
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
Tim Burks
 
Introduction to Jhipster
Introduction to JhipsterIntroduction to Jhipster
Introduction to Jhipster
Knoldus Inc.
 
Enforcing API Design Rules for High Quality Code Generation
Enforcing API Design Rules for High Quality Code GenerationEnforcing API Design Rules for High Quality Code Generation
Enforcing API Design Rules for High Quality Code Generation
Tim Burks
 
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays
 
BKK16-106 ODP Project Update
BKK16-106 ODP Project UpdateBKK16-106 ODP Project Update
BKK16-106 ODP Project Update
Linaro
 
SFO15-102:ODP Project Update
SFO15-102:ODP Project UpdateSFO15-102:ODP Project Update
SFO15-102:ODP Project Update
Linaro
 
Odo improving the developer experience on OpenShift - hack &amp; sangria
Odo   improving the developer experience on OpenShift - hack &amp; sangriaOdo   improving the developer experience on OpenShift - hack &amp; sangria
Odo improving the developer experience on OpenShift - hack &amp; sangria
Jorge Morales
 
Java2 days 5_agile_steps_to_cloud-ready_apps
Java2 days 5_agile_steps_to_cloud-ready_appsJava2 days 5_agile_steps_to_cloud-ready_apps
Java2 days 5_agile_steps_to_cloud-ready_apps
Payara
 
How we scale up our architecture and organization at Dailymotion
How we scale up our architecture and organization at DailymotionHow we scale up our architecture and organization at Dailymotion
How we scale up our architecture and organization at Dailymotion
Stanislas Chollet
 
Hyperion EPM APIs - Added value from HFM, Workspace, FDM, Smartview, and Shar...
Hyperion EPM APIs - Added value from HFM, Workspace, FDM, Smartview, and Shar...Hyperion EPM APIs - Added value from HFM, Workspace, FDM, Smartview, and Shar...
Hyperion EPM APIs - Added value from HFM, Workspace, FDM, Smartview, and Shar...
Charles Beyer
 
Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...
Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...
Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...
Flink Forward
 
Nodejs
NodejsNodejs
Using JHipster for generating Angular/Spring Boot apps
Using JHipster for generating Angular/Spring Boot appsUsing JHipster for generating Angular/Spring Boot apps
Using JHipster for generating Angular/Spring Boot apps
Yakov Fain
 

Similar to Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud Gateway (20)

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
 
LCU14 310- Cisco ODP v2
LCU14 310- Cisco ODP v2LCU14 310- Cisco ODP v2
LCU14 310- Cisco ODP v2
 
OpenAPI Extensions for OSLC
OpenAPI Extensions for OSLCOpenAPI Extensions for OSLC
OpenAPI Extensions for OSLC
 
How to build a tool for operating Flink on Kubernetes
How to build a tool for operating Flink on KubernetesHow to build a tool for operating Flink on Kubernetes
How to build a tool for operating Flink on Kubernetes
 
Using JHipster 4 for generating Angular/Spring Boot apps
Using JHipster 4 for generating Angular/Spring Boot appsUsing JHipster 4 for generating Angular/Spring Boot apps
Using JHipster 4 for generating Angular/Spring Boot apps
 
apidays LIVE Australia 2020 - Have your cake and eat it too: GraphQL? REST? W...
apidays LIVE Australia 2020 - Have your cake and eat it too: GraphQL? REST? W...apidays LIVE Australia 2020 - Have your cake and eat it too: GraphQL? REST? W...
apidays LIVE Australia 2020 - Have your cake and eat it too: GraphQL? REST? W...
 
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
 
Introduction to Jhipster
Introduction to JhipsterIntroduction to Jhipster
Introduction to Jhipster
 
Enforcing API Design Rules for High Quality Code Generation
Enforcing API Design Rules for High Quality Code GenerationEnforcing API Design Rules for High Quality Code Generation
Enforcing API Design Rules for High Quality Code Generation
 
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
 
BKK16-106 ODP Project Update
BKK16-106 ODP Project UpdateBKK16-106 ODP Project Update
BKK16-106 ODP Project Update
 
SFO15-102:ODP Project Update
SFO15-102:ODP Project UpdateSFO15-102:ODP Project Update
SFO15-102:ODP Project Update
 
Odo improving the developer experience on OpenShift - hack &amp; sangria
Odo   improving the developer experience on OpenShift - hack &amp; sangriaOdo   improving the developer experience on OpenShift - hack &amp; sangria
Odo improving the developer experience on OpenShift - hack &amp; sangria
 
Java2 days 5_agile_steps_to_cloud-ready_apps
Java2 days 5_agile_steps_to_cloud-ready_appsJava2 days 5_agile_steps_to_cloud-ready_apps
Java2 days 5_agile_steps_to_cloud-ready_apps
 
How we scale up our architecture and organization at Dailymotion
How we scale up our architecture and organization at DailymotionHow we scale up our architecture and organization at Dailymotion
How we scale up our architecture and organization at Dailymotion
 
Hyperion EPM APIs - Added value from HFM, Workspace, FDM, Smartview, and Shar...
Hyperion EPM APIs - Added value from HFM, Workspace, FDM, Smartview, and Shar...Hyperion EPM APIs - Added value from HFM, Workspace, FDM, Smartview, and Shar...
Hyperion EPM APIs - Added value from HFM, Workspace, FDM, Smartview, and Shar...
 
Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...
Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...
Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...
 
Nodejs
NodejsNodejs
Nodejs
 
Using JHipster for generating Angular/Spring Boot apps
Using JHipster for generating Angular/Spring Boot appsUsing JHipster for generating Angular/Spring Boot apps
Using JHipster for generating Angular/Spring Boot apps
 

More from Iván López Martín

SalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 TestcontainersSalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 Testcontainers
Iván López Martín
 
CommitConf 2024 - Spring Boot <3 Testcontainers
CommitConf 2024 - Spring Boot <3 TestcontainersCommitConf 2024 - Spring Boot <3 Testcontainers
CommitConf 2024 - Spring Boot <3 Testcontainers
Iván López Martín
 
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdfVoxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
Iván López Martín
 
VMware - Testcontainers y Spring Boot
VMware - Testcontainers y Spring BootVMware - Testcontainers y Spring Boot
VMware - Testcontainers y Spring Boot
Iván López Martín
 
Codemotion Madrid 2023 - Testcontainers y Spring Boot
Codemotion Madrid 2023 - Testcontainers y Spring BootCodemotion Madrid 2023 - Testcontainers y Spring Boot
Codemotion Madrid 2023 - Testcontainers y Spring Boot
Iván López Martín
 
CommitConf 2023 - Spring Framework 6 y Spring Boot 3
CommitConf 2023 - Spring Framework 6 y Spring Boot 3CommitConf 2023 - Spring Framework 6 y Spring Boot 3
CommitConf 2023 - Spring Framework 6 y Spring Boot 3
Iván López Martín
 
Construyendo un API REST con Spring Boot y GraalVM
Construyendo un API REST con Spring Boot y GraalVMConstruyendo un API REST con Spring Boot y GraalVM
Construyendo un API REST con Spring Boot y GraalVM
Iván López Martín
 
jLove 2020 - Micronaut and graalvm: The power of AoT
jLove 2020 - Micronaut and graalvm: The power of AoTjLove 2020 - Micronaut and graalvm: The power of AoT
jLove 2020 - Micronaut and graalvm: The power of AoT
Iván López Martín
 
Codemotion Madrid 2020 - Serverless con Micronaut
Codemotion Madrid 2020 - Serverless con MicronautCodemotion Madrid 2020 - Serverless con Micronaut
Codemotion Madrid 2020 - Serverless con Micronaut
Iván López Martín
 
JConf Perú 2020 - ¡Micronaut en acción!
JConf Perú 2020 - ¡Micronaut en acción!JConf Perú 2020 - ¡Micronaut en acción!
JConf Perú 2020 - ¡Micronaut en acción!
Iván López Martín
 
JConf Perú 2020 - Micronaut + GraalVM = <3
JConf Perú 2020 - Micronaut + GraalVM = <3JConf Perú 2020 - Micronaut + GraalVM = <3
JConf Perú 2020 - Micronaut + GraalVM = <3
Iván López Martín
 
JConf México 2020 - Micronaut + GraalVM = <3
JConf México 2020 - Micronaut + GraalVM = <3JConf México 2020 - Micronaut + GraalVM = <3
JConf México 2020 - Micronaut + GraalVM = <3
Iván López Martín
 
Developing Micronaut Applications With IntelliJ IDEA
Developing Micronaut Applications With IntelliJ IDEADeveloping Micronaut Applications With IntelliJ IDEA
Developing Micronaut Applications With IntelliJ IDEA
Iván López Martín
 
CommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
CommitConf 2019 - Micronaut y GraalVm: La combinación perfectaCommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
CommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
Iván López Martín
 
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
Iván López Martín
 
Greach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut ConfigurationsGreach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut Configurations
Iván López Martín
 
VoxxedDays Bucharest 2019 - Alexa, nice to meet you
VoxxedDays Bucharest 2019 - Alexa, nice to meet youVoxxedDays Bucharest 2019 - Alexa, nice to meet you
VoxxedDays Bucharest 2019 - Alexa, nice to meet you
Iván López Martín
 
JavaDay Lviv 2019 - Micronaut in action!
JavaDay Lviv 2019 - Micronaut in action!JavaDay Lviv 2019 - Micronaut in action!
JavaDay Lviv 2019 - Micronaut in action!
Iván López Martín
 
CrossDvlup Madrid 2019 - Alexa, encantado de conocerte
CrossDvlup Madrid 2019 - Alexa, encantado de conocerteCrossDvlup Madrid 2019 - Alexa, encantado de conocerte
CrossDvlup Madrid 2019 - Alexa, encantado de conocerte
Iván López Martín
 
Madrid-GUG - ¡Micronaut en acción!
Madrid-GUG - ¡Micronaut en acción!Madrid-GUG - ¡Micronaut en acción!
Madrid-GUG - ¡Micronaut en acción!
Iván López Martín
 

More from Iván López Martín (20)

SalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 TestcontainersSalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 Testcontainers
 
CommitConf 2024 - Spring Boot <3 Testcontainers
CommitConf 2024 - Spring Boot <3 TestcontainersCommitConf 2024 - Spring Boot <3 Testcontainers
CommitConf 2024 - Spring Boot <3 Testcontainers
 
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdfVoxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
 
VMware - Testcontainers y Spring Boot
VMware - Testcontainers y Spring BootVMware - Testcontainers y Spring Boot
VMware - Testcontainers y Spring Boot
 
Codemotion Madrid 2023 - Testcontainers y Spring Boot
Codemotion Madrid 2023 - Testcontainers y Spring BootCodemotion Madrid 2023 - Testcontainers y Spring Boot
Codemotion Madrid 2023 - Testcontainers y Spring Boot
 
CommitConf 2023 - Spring Framework 6 y Spring Boot 3
CommitConf 2023 - Spring Framework 6 y Spring Boot 3CommitConf 2023 - Spring Framework 6 y Spring Boot 3
CommitConf 2023 - Spring Framework 6 y Spring Boot 3
 
Construyendo un API REST con Spring Boot y GraalVM
Construyendo un API REST con Spring Boot y GraalVMConstruyendo un API REST con Spring Boot y GraalVM
Construyendo un API REST con Spring Boot y GraalVM
 
jLove 2020 - Micronaut and graalvm: The power of AoT
jLove 2020 - Micronaut and graalvm: The power of AoTjLove 2020 - Micronaut and graalvm: The power of AoT
jLove 2020 - Micronaut and graalvm: The power of AoT
 
Codemotion Madrid 2020 - Serverless con Micronaut
Codemotion Madrid 2020 - Serverless con MicronautCodemotion Madrid 2020 - Serverless con Micronaut
Codemotion Madrid 2020 - Serverless con Micronaut
 
JConf Perú 2020 - ¡Micronaut en acción!
JConf Perú 2020 - ¡Micronaut en acción!JConf Perú 2020 - ¡Micronaut en acción!
JConf Perú 2020 - ¡Micronaut en acción!
 
JConf Perú 2020 - Micronaut + GraalVM = <3
JConf Perú 2020 - Micronaut + GraalVM = <3JConf Perú 2020 - Micronaut + GraalVM = <3
JConf Perú 2020 - Micronaut + GraalVM = <3
 
JConf México 2020 - Micronaut + GraalVM = <3
JConf México 2020 - Micronaut + GraalVM = <3JConf México 2020 - Micronaut + GraalVM = <3
JConf México 2020 - Micronaut + GraalVM = <3
 
Developing Micronaut Applications With IntelliJ IDEA
Developing Micronaut Applications With IntelliJ IDEADeveloping Micronaut Applications With IntelliJ IDEA
Developing Micronaut Applications With IntelliJ IDEA
 
CommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
CommitConf 2019 - Micronaut y GraalVm: La combinación perfectaCommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
CommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
 
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
 
Greach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut ConfigurationsGreach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut Configurations
 
VoxxedDays Bucharest 2019 - Alexa, nice to meet you
VoxxedDays Bucharest 2019 - Alexa, nice to meet youVoxxedDays Bucharest 2019 - Alexa, nice to meet you
VoxxedDays Bucharest 2019 - Alexa, nice to meet you
 
JavaDay Lviv 2019 - Micronaut in action!
JavaDay Lviv 2019 - Micronaut in action!JavaDay Lviv 2019 - Micronaut in action!
JavaDay Lviv 2019 - Micronaut in action!
 
CrossDvlup Madrid 2019 - Alexa, encantado de conocerte
CrossDvlup Madrid 2019 - Alexa, encantado de conocerteCrossDvlup Madrid 2019 - Alexa, encantado de conocerte
CrossDvlup Madrid 2019 - Alexa, encantado de conocerte
 
Madrid-GUG - ¡Micronaut en acción!
Madrid-GUG - ¡Micronaut en acción!Madrid-GUG - ¡Micronaut en acción!
Madrid-GUG - ¡Micronaut en acción!
 

Recently uploaded

Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
Bhaskar Mitra
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 

Recently uploaded (20)

Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 

Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud Gateway

  • 1. Dynamic OpenAPIs with Spring Cloud Gateway Iván López @ilopmar
  • 2. @ilopmar Iván López Who am I? ● Iván López (@ilopmar) ● JVM Developer ● Staff Software Engineer at VMware ● @MadridGUG Coordinator ● Speaker: GeeCon, Codemotion, Devoxx, SpringOne, RigaDevDays, CommitConf, Spring IO,... 🇪🇸🇮🇹🇬🇧🇦🇹🇨🇦🇧🇪🇨🇿🇺🇦🇩🇰🇸🇪🇺🇸🇷🇺🇪🇪🇱🇻🇭🇷🇵🇱🇹🇷🇷🇴🇧🇬
  • 4. @ilopmar Iván López OpenAPI Specification ● Old Swagger Specification ● API description format for REST APIs ● Endpoints, operations, parameters, authentication,... ● Programming language agnostic ● YAML or JSON
  • 5. @ilopmar Iván López Swagger ● Set of opensource tools build around OpenApi Spec ● Swagger Editor ● Swagger UI ● Swagger Codegen ● Swagger Core, Parser,...
  • 6. @ilopmar Iván López Why use OpenAPI? ● Standard widely used ● Huge userbase ● Stable implementation ● Swagger Codegen to generate server stub and client libraries! ● Integrations with many languages, libraries and frameworks
  • 8. @ilopmar Iván López What is an API Gateway? ● API proxy between an API Client and API Server ● Single entry point for the backend API and services ● Cross-cuttings concerns: security, rate-limiting, monitoring, logging, metrics,...
  • 9. @ilopmar Iván López Spring Cloud Gateway ● API Gateway for the Spring Ecosystem ● Built on top Spring Boot, WebFlux and Reactor ● Dynamic routing ● Route matching: Path, Method, Header, Host,... ● Filters ● Rate Limiting, Circuit Breaker ● Path Rewriting
  • 10. @ilopmar Iván López Spring Cloud Gateway Basics ● Route, Predicate and Filter ● Route Predicates: Cookie, Header, Host, Method, Path,... ● Gateway Factories: Add/Remove Request/Response Header/Parameter, Rewrite path ● Global and custom filters ● YAML configuration & Programmatic API
  • 11. @ilopmar Iván López Spring Cloud Gateway examples spring: cloud: gateway: routes: - id: method_route uri: https://example.org predicates: - Method=GET,POST spring: cloud: gateway: routes: - id: add_request_header_route uri: https://example.org filters: - AddRequestHeader=X-Foo, some-value spring: cloud: gateway: routes: - id: rewritepath_route uri: https://example.org predicates: - Path=/foo/** filters: - RewritePath=/foo/?(?<segment>.*), /${segment}
  • 13. “I just want to expose the OpenAPI of my application”
  • 14. @ilopmar Iván López Current status ● Spring Cloud Gateway in front of all different services ● All services expose OpenAPI ● API First? – Code -> OpenAPI – OpenAPI -> Code ● Internal endpoints vs Public endpoints ● Manual configuration in SCG
  • 15. @ilopmar Iván López Requirements ● Expose product Public OpenAPI in Gateway ● Aggregate endpoints from different services ● Public endpoints defined on every service ● Optionally rewrite some endpoints ● Expose only public schemas and not all of them ● Rewrite and group tags ● Update Public OpenAPI and routing must be dynamic
  • 16. @ilopmar Iván López My approach ● I did a 1 week spike ● We use SCG OSS ● The feature is available in SCG Commercial: Only Tanzu Application Service and Kubernetes ● We deploy on K8S but wanted to keep everything agnostic: local development, on-premise,... ● Libraries to read/write OpenAPI specifications ● SCG Programmatic API
  • 18. @ilopmar Iván López Every service defines... ● Which endpoint is made public paths: /pipelines: post: x-vmw-public: true summary: Create a new pipeline definition description: Given a pipeline, it creates an execution graph and prepares it to be run
  • 19. @ilopmar Iván López Every service defines... ● How an endpoint is rewritten paths: /reports: get: x-vmw-public: true x-vmw-rewrite: /vulnerabilities/reports summary: Get all reports, optionally filtered by artifact version description: It returns a collection of report metadata...
  • 20. @ilopmar Iván López Every service defines... ● How tags are rewritten tags: - name: products description: Using these endpoints you can manage the products... x-vmw-rewrite: inventory - name: artifacts description: Using these endpoints you can manage the artifacts... x-vmw-rewrite: inventory - name: artifact-versions description: Using these endpoints you can manage the artifact versions... x-vmw-rewrite: inventory - name: inventory description: Using these endpoints you can see the products, artifacts and artifact versions and their relationships in your organization inventory
  • 21. @ilopmar Iván López Every service defines... ● How tags are rewritten tags: - name: products description: Using these endpoints you can manage the products... x-vmw-rewrite: inventory - name: artifacts description: Using these endpoints you can manage the artifacts... x-vmw-rewrite: inventory - name: artifact-versions description: Using these endpoints you can manage the artifact versions... x-vmw-rewrite: inventory - name: inventory description: Using these endpoints you can see the products, artifacts and artifact versions and their relationships in your organization inventory
  • 22. @ilopmar Iván López OpenAPI creation ● Gateway polls services every 5 minutes ● Filter, transform and combine all the OpenAPI specs ● Creates Public OpenAPI specification on the fly
  • 23. @ilopmar Iván López Expose OpenAPI @GetMapping(value = "/v1/api.yml", produces = APPLICATION_X_YAML) public ResponseEntity<String> v1() { return openApiService.generateOpenApi() .map(ResponseEntity::ok) .orElseGet(() -> ResponseEntity.notFound().build()); }
  • 24. @ilopmar Iván López Spring Cloud Gateway routes @Bean @RefreshScope public RouteLocator routeLocator(RouteLocatorBuilder routeLocatorBuilder, RouteService routeService) { RouteLocatorBuilder.Builder routeLocator = routeLocatorBuilder.routes(); List<GatewayRoute> gatewayRoutes = routeService.findGatewayRoutes(); for (GatewayRoute gatewayRoute : gatewayRoutes) { routeLocator.route(gatewayRoute.routeId(), r -> r .order(gatewayRoute.order()) .path(gatewayRoute.gatewayPath()) .and().method(gatewayRoute.openApiRoute().method()) .filters(gatewayFilterSpec -> gatewayFilterSpec.rewritePath(gatewayRoute.regexp(), gatewayRoute.rewritePath()) ) .uri(gatewayRoute.openApiRoute().uri())); } return routeLocator.build(); } ● Routes refreshed dynamically
  • 25. @ilopmar Iván López ● Routes refreshed dynamically Spring Cloud Gateway routes @Bean @RefreshScope public RouteLocator routeLocator(RouteLocatorBuilder routeLocatorBuilder, RouteService routeService) { RouteLocatorBuilder.Builder routeLocator = routeLocatorBuilder.routes(); List<GatewayRoute> gatewayRoutes = routeService.findGatewayRoutes(); for (GatewayRoute gatewayRoute : gatewayRoutes) { routeLocator.route(gatewayRoute.routeId(), r -> r .order(gatewayRoute.order()) .path(gatewayRoute.gatewayPath()) .and().method(gatewayRoute.openApiRoute().method()) .filters(gatewayFilterSpec -> gatewayFilterSpec.rewritePath(gatewayRoute.regexp(), gatewayRoute.rewritePath()) ) .uri(gatewayRoute.openApiRoute().uri())); } return routeLocator.build(); }
  • 26. @ilopmar Iván López Gateway Routes public List<GatewayRoute> findGatewayRoutes() { return openApiService.findOpenApiRoutes() .stream() .map(RouteConverter::convertOpenApiRouteToGatewayRoute) .filter(Optional::isPresent) .map(Optional::get) .toList(); }
  • 27. @ilopmar Iván López Example: Route conversion (I) OpenApiRoute[ originalPath=/v1/reports newPath=/v1/vulnerabilities/reports method=GET uri=https://vulnerability-service.xxxxxxxxxxxxx ] GatewayRoute[ routeId=GET__/v1/vulnerabilities/reports gatewayPath=/v1/vulnerabilities/reports regexp=/v1/vulnerabilities/reports rewritePath=/v1/reports order=0 ]
  • 28. @ilopmar Iván López Example: Route conversion (II) OpenApiRoute[ originalPath=/v1/target-platforms/{target_platform_id} newPath=/v1/tp/{target_platform_id} method=GET uri=https://provisioning-service.xxxxxxxxxxxxx ] GatewayRoute[ routeId=GET__/v1/tp/{target_platform_id} gatewateyPath=/v1/tp/?* regexp=/v1/tp/(?<id1>.*) rewritePath=/v1/target-platforms/${id1} order=10 ]
  • 29. @ilopmar Iván López Spring Cloud Gateway routes @Bean @RefreshScope public RouteLocator routeLocator(RouteLocatorBuilder routeLocatorBuilder, RouteService routeService) { RouteLocatorBuilder.Builder routeLocator = routeLocatorBuilder.routes(); List<GatewayRoute> openApiRoutes = routeService.findOpenApiRoutes(); for (GatewayRoute gatewayRoute : openApiRoutes) { routeLocator.route(gatewayRoute.routeId(), r -> r .order(gatewayRoute.order()) .path(gatewayRoute.gatewayPath()) .and().method(gatewayRoute.openApiRoute().method()) .filters(gatewayFilterSpec -> gatewayFilterSpec.rewritePath(gatewayRoute.regexp(), gatewayRoute.rewritePath()) ) .uri(gatewayRoute.openApiRoute().uri())); } return routeLocator.build(); } ● Routes refreshed dynamically
  • 30. @ilopmar Iván López Example: Gateway Routes (I) OpenApiRoute[ originalPath=/v1/reports newPath=/v1/vulnerabilities/reports method=GET uri=https://vulnerability-service... ] GatewayRoute[ routeId=GET__/v1/vulnerabilities/reports gatewateyPath=/v1/vulnerabilities/reports regexp=/v1/vulnerabilities/reports rewritePath=/v1/reports order=0 ] routeLocator.route("GET__/v1/vulnerabilities/reports", r -> r .order(0) .path("/v1/vulnerabilities/reports") .and().method("GET") .filters(s -> s.rewritePath("/v1/vulnerabilities/reports", "/v1/reports")) .uri("https://vulnerability-service.xxxxxxxxxxxxxxxxxx"));
  • 31. @ilopmar Iván López Example: Gateway Routes (II) OpenApiRoute[ originalPath=/v1/target-platforms/{target_platform_id} newPath=/v1/tp/{target_platform_id} method=GET uri=https://provisioning-service... ] GatewayRoute[ routeId=GET__/v1/tp/{target_platform_id} gatewateyPath=/v1/tp/?* regexp=/v1/tp/(?<id1>.*) rewritePath=/v1/target-platforms/${id1} order=10 ] routeLocator.route("GET__/v1/tp/{target_platform_id}", r -> r .order(10) .path("/v1/tp/?*") .and().method("GET") .filters(s -> s.rewritePath("/v1/tp/(?<id1>.*)", "/v1/target-platforms/${id1}")) .uri("https://provisioning-service.xxxxxxxxxxxxxxx"));
  • 32. Demo
  • 33. @ilopmar Iván López Summary Solved the problem in one week +1 year in Production without problems Reuse existing OSS libraries Platform agnostic Spring Cloud Gateway is awesome Public and Dynamic OpenAPI