SlideShare una empresa de Scribd logo
1 de 34
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

Quarkus - a next-generation Kubernetes Native Java framework
Quarkus - a next-generation Kubernetes Native Java frameworkQuarkus - a next-generation Kubernetes Native Java framework
Quarkus - a next-generation Kubernetes Native Java framework
SVDevOps
 

La actualidad más candente (20)

Introduction to kubernetes
Introduction to kubernetesIntroduction to kubernetes
Introduction to kubernetes
 
Red Hat OpenShift Container Platform Overview
Red Hat OpenShift Container Platform OverviewRed Hat OpenShift Container Platform Overview
Red Hat OpenShift Container Platform Overview
 
Docker Networking Deep Dive
Docker Networking Deep DiveDocker Networking Deep Dive
Docker Networking Deep Dive
 
Spring Security 5
Spring Security 5Spring Security 5
Spring Security 5
 
Microservices Design Patterns | Edureka
Microservices Design Patterns | EdurekaMicroservices Design Patterns | Edureka
Microservices Design Patterns | Edureka
 
Introduction to Kubernetes with demo
Introduction to Kubernetes with demoIntroduction to Kubernetes with demo
Introduction to Kubernetes with demo
 
Jenkins tutorial
Jenkins tutorialJenkins tutorial
Jenkins tutorial
 
Micro Frontends
Micro FrontendsMicro Frontends
Micro Frontends
 
Jenkins tutorial for beginners
Jenkins tutorial for beginnersJenkins tutorial for beginners
Jenkins tutorial for beginners
 
An Introduction To Jenkins
An Introduction To JenkinsAn Introduction To Jenkins
An Introduction To Jenkins
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UK
 
Quarkus - a next-generation Kubernetes Native Java framework
Quarkus - a next-generation Kubernetes Native Java frameworkQuarkus - a next-generation Kubernetes Native Java framework
Quarkus - a next-generation Kubernetes Native Java framework
 
Gradle - the Enterprise Automation Tool
Gradle  - the Enterprise Automation ToolGradle  - the Enterprise Automation Tool
Gradle - the Enterprise Automation Tool
 
Nginx Reverse Proxy with Kafka.pptx
Nginx Reverse Proxy with Kafka.pptxNginx Reverse Proxy with Kafka.pptx
Nginx Reverse Proxy with Kafka.pptx
 
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
 
소프트웨어 아키텍처
소프트웨어 아키텍처소프트웨어 아키텍처
소프트웨어 아키텍처
 
Api first design 개발의 선순환
Api first design 개발의 선순환Api first design 개발의 선순환
Api first design 개발의 선순환
 
Introduction to Spring Cloud
Introduction to Spring Cloud           Introduction to Spring Cloud
Introduction to Spring Cloud
 
Docker Swarm for Beginner
Docker Swarm for BeginnerDocker Swarm for Beginner
Docker Swarm for Beginner
 

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

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
 

Similar a 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
 

Más de Iván López Martín

Más de 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!
 

Último

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Último (20)

Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 

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