For a project I'd like to set up a small microservice scenario using Spring Boot with an API gateway exposing REST and GraphQL to the clients, a Eureka service registry and three services. I want all services behind the API gateway to talk gRPC because of performance reasons, but at the same time still expose an additional REST API. Is there a clean way to implement both types of interfaces on top of the same business logic? And how would the gateway proxy the clients' HTTP requests to gRPC ones?
You can look into LogNet grpc-spring-boot-starter to see how to integrate gRPC into Spring Boot, it also has a section about Eureka.
As per Eureka example, make sure you don't create new connection over gRPC for each call.
Depending on the implementation of the API gateway, it should also talk to Eureka, and access downstream services by logical names via gRPC.
As per second part, simply implement your business logic in Spring Services, and forward calls to them from the transport related abstractions (Controllers and gRPC services).
Optionally, you can go even further, and define all messages in Protobuf only. And then register Spring's Protobuf Converter for HTTP.
Related
Small architecture and design question please.
Question:
Should Kubernetes Ingress lives together with Spring Cloud Gateway? If not, which one should be preferred?
First, with a Spring Webflux / Spring Cloud Gateway project, I managed to have working route-based forwarding. Meaning, all my clients only need to know this one and only Spring Cloud Gateway endpoint, and the Spring Cloud Gateway will forward to serviceA if the URL contains serviceA, to serviceB if serviceB, etc, straightforward.
I added some more “software level features” such as dynamic configuration (to change the routes at runtime), circuit breaker, rate limit, bulkhead, and few others features, very cool, but really, I ended up using the route forwarding as a main feature.
Then couple of weeks back, I spent time studying Kubernetes, and more precisely Kubernetes Ingress.
I managed to learn Kubernetes Ingress is a very cool and strong thing. I managed to perform at least the route based forwarding.
Meaning, clients needs to only know this one and only Ingress endpoint, and the Ingress will forward to underlying services within the Kubernetes cluster. Where as of now, it forwards everything to Spring Cloud Gateway, which will forward to everything else. I tried, and it could have forwarded to the real business services in the first place).
And this is the moment where I am having doubts.
Did I just duplicate work? (I mean in terms on functionally, I had fun learning both).
Should I consider an architecture where the Spring Cloud Gateway (only him) is really doing the gating?
Should I consider an architecture where both the Ingress and the Software Gateway have full importance, configuring features in both? (Accept the duplicated work?)
Should I remove the Spring Cloud Gateway entirely?
Thank you
In my opinion, Kubernetes must lives together with Spring Cloud Gateway.
Reverse proxies has capabilities like central logging, security, caching, routing, traffic management features etc, but there are also things they cannot do. API Gateways come into play at this point. They have all the features of reverse proxies, plus they have extra capabilities that they can't. For this reason, API Gateways are called enhanced reverse proxies.
So Kubernetes ingress acts like reverse proxy, while Spring Cloud Gateway is implementation of API Gateway pattern. As I mentioned in the definition above, I can say few things you can't do with Kubernetes.
Can you implement API composition? No
Can you implement JWT authentication by Kubernetes? If so, Can you carry JWTs more than 8 KB to downstream service by Kubernetes? No
Can you combine all Swagger/Open API documentation by Kubernetes? No
I'm having a really tough time with this one. We want to move our legacy app to Microservice application(Spring-boot, Java 8) .
As per Architect, we do-not need Service Disvovery and API Gateway is enough for the doing Service Discovery and Routing.
Note that currently , deployments are On premise server and we will have fixed number of nodes and F5/load balancer will be able to route the request to API gateway and then to the microservices.
Can we survive with Spring Cloud API Gateway and no Service Discovery?
A short answer Yes, you can survive with Spring Cloud API Gateway and no Service Discovery.
But it's really dependent on the size of your application and the amount of traffic it will be handling.
You can start migration to microservices without Service discovery.
For internal service-to-service communication just use real hardcoded IP addresses and ports.
Regarding to the API Gateway doing Service Discovery. I can be wrong, but you won't be able to communicate through Api Gateway because it also has no clue about the location of the targets (services locations have to be hardcoded as well).
Once you begin feeling that you need scaling out you won't avoid using Service Registry tool. If you start considering which one to take I can suggest using HashiCorp Consul.
Anyway, it's most likely that you finally will have to inject Service discovery mechanism to your infrastructure. You can either do it from the beginning or take care of it later if the new architecture will be beneficial to you and there will be a plan of extending it further.
If you have plans of migration to the clouds then you can think about Kubernetes for your infrastructure in advance. It provides you with Service discovery mechanism out of the box.
Kubernetes is a great platform for this, if you can opt.
It can handle parts ranging from service discovery to deployment.
You just need to make a cloud ready docker image (preferably) and deploy it to kubernetes, Kubernetes will map an internal endpoint to this, based on your configuration and your services will be registered with it ( if I talk in terms of spring-cloud and eureka server).
If there is no Service-Registry-backed DiscoveryClient then you can configure spring.cloud.discovery.client.simple.instances.userservice[0].uri=http://s11:8080
You can host this userservice on kubernetes cluster .For further details go to this docs
https://cloud.spring.io/spring-cloud-commons/2.2.x/reference/html/
Like wise to have communcation between sevices ,suppose userservice wants to communicate to password service easily configure via ribbon
passwordservice.ribbon.listOfServers:${PASSWORDSERIVCE}:http://localhost:8081
I do not see any problem with this strcuture .
I'm developing a web application based on microservices architecture. Its primary framework is Spring Cloud Data Flow, microservices are communicating with each other via message bus (RabbitMQ), REST-endpoints are exposed only by a gateway wjich is also a central point of authentication.
I want to follow the global authentication, local authorization approach using OAuth2 tokens, but a problem has occurred: I don't understand how to configure authorization process on microservices a.k.a use #PreAuthorize on methods annotated with #StreamListener, and I can't find any examples for this.
WRT http://camel.apache.org/rest.html.
Is this component used by the client to set-up endpoint to reach an existent server?
if so, does it mean camel provides me more than one way to do it? Should I be using http component .to("http://endpointuri") instead?
What is the advantage of client using rest component over http component?
Or
used by the service provider to set-up the service provider??
if so, does this mean camel provides me more than one way to do it? Refer to http://camel.apache.org/rest-dsl.html .
What is the advantage of client using rest component over http-dsl?
1 or 2? For use by client or server? As usual, the camel docs has unspecified indirection.
This component allows Camel to expose REST services. These services will be invoked by your client. In the internal processing of a service you can do anything you want like calling other services. The DSL relies on underlying http components so you can use undertow, jetty, netty and others to set this up.
There is no such thing as a http-dsl. Essentially you use the rest-dsl together with some http framework such as undertow to expose some REST services. The DSL makes the creation of the REST services easier. I think it can also generate swagger docs for you.
I am tasked with creating a layer in Java/Spring that consumes web services from a couple different providers. These services define specific request beans but the end points do not publish XSD information.
What would be the best way to generate the artifacts required to consume these services? It seems building our own request objects is not the best way of doing things.
REST services do not offer XSD as the WSDL of a traditional SOAP service. Some REST frameworks offer WADL, or the may user Swagger.io to describe the service, or expose documentation like Spring boots actuator /docs.
If there is no such documentation, and you can't get the source code for the system you are integrating with, I recommend that you build your own set of Java POJOs so you can interface with the service in a typed manner.
I have done that for multiple systems that expose (online) documented REST services, but do not provide a set of DTO that you can use when consuming them.