spring-cloud / spring-cloud-netflix

Integration with Netflix OSS components
http://cloud.spring.io/spring-cloud-netflix/
Apache License 2.0
4.87k stars 2.44k forks source link

[ Question / Feature Request] Complex Prefixes #1235

Closed matanshukry closed 5 years ago

matanshukry commented 8 years ago

I would like to have 2 "groups" of routes in my configuration:

(1), a group that starts with /api, which will be stripped. e.g.

(2) A group that starts with /web, which will be stripped

It seems each one of those options is possible by it's own, using a global prefix (either "/api" or "/web"), and strip-prefix (set to false) at the service level. However, how can I achieve them both in the same zuul?

If it's not possible, what you guys think about this as a feature?

spencergibb commented 8 years ago

There are many routing requests about, such as #435. You can always write your own pre filter to do this. Maybe at that point you could contribute it back.

kakawait commented 8 years ago

@spencergibb the fact that routing requests become more and more present, we can think about proposing a programmatic interface to write your custom routing rules? Something less generic than ZuulFilter

spencergibb commented 8 years ago

@kakawait we're open to suggestions.

kakawait commented 8 years ago

@spencergibb I'm working on it (solution not suggestions)

matanshukry commented 8 years ago

@kakawait - can you share you're solution (idea), so I'll know if it should work for me as well?

kakawait commented 8 years ago

@matanshukry you could try that filter https://gist.github.com/kakawait/e1b5c67a9a262a684c5d0f3c2b61ae4d

ATTENTION is just a POC/workaround (not heavily tested) and it will break any zuul.routes.<serviceId>.url= that not using serviceId as hostname (ex: http://localhost:8080/). Because I didn't find any way to extend ZuulRoute inside ZuulProperties (@ConfigurationProperties from my point of view is not really design to be extend easily if you have nested class) to be able to add a flag to enable/disable loadbalancing for specific route.

In your case try following configuration

zuul:
  routes:
    user-service:
      path: /api/users/**
      url: http://user-service/users
      strip-prefix: true
    image-service:
      path: /api/images/**
      url: http://image-service/images
      strip-prefix: true
    web-service
      path: /web/login/**
      url: http://web-service/login
      strip-prefix: true

If any issue with this filter please continue discussion on gist


Is just a workaround we need to think about how to integrate it inside core. Moreover in addition to extend routing capability, zuul should be able to be more configurable, for example by allowing circuit breaking on plain old url...

aivans commented 8 years ago

@kakawait What is the novelty in your suggestion? I though you can already do this kind of routing configuration. You basically do not use the global prefix and you incorporate it into each route's path.

kakawait commented 8 years ago

@aivans you can't use http://<serviceId> inside url parameter actually. I really don't how how can you resolve such routing or from #435 using current base code/configuration (with Eureka enabled)

aivans commented 8 years ago

I see. I was confused because the original description mentions complex prefixes.

I think the fundamental question here is whether Zuul shall remain simple and mainly do coarse grained routing out of the box, or be enhanced with API Editing features. Adhoc requests like this one will only reduce maintainability and make upgrades a nightmare.

For API Editing I would take a look at AWS API Gateway. It is quite straight forward in what it does. While the developer can still do wildcard routing (/user/** goes to user-service), more granular API-s can be built. An API Designer would take care of:

kakawait commented 8 years ago

@aivans agree with that. If you (community + core dev) think that zuul routing configuration should keep simple no problem and simply close all related issues by proposing user to write it own ZuulFilter to achieve what they want.

aivans commented 8 years ago

@kakawait Just expressing my opinion. An API Manager would solve all issues with a consistent long term approach.

kakawait commented 8 years ago

My last comment may a bit too "direct". What I want to said is just I'm open to any options 👍 BTW a custom ZuulFilter can solve any problem for the moment so maybe just wait for more advice before starting any PR or something real.

aivans commented 8 years ago

@kakawait no worries

aivans commented 8 years ago

I would like to start an initiative where we can build an API Manager on top of Zuul together. I have an initial idea, but I would like more people to contribute. anyone interested?

spencergibb commented 8 years ago

@aivans I am :-)

aivans commented 8 years ago

cool. I will gather my thoughts over the weekend.

What would be the best structure to work together? Another branch, fork? Where shall we talk about it? Normally I use confluence in my closed corporate environment :)

daniellavoie commented 8 years ago

@aivans Besides from sub domain redirections, what kind of features you have in mind that Zuul and Eureka cannot handle ? Access management ?

kakawait commented 8 years ago

@aivans Same but not before 3 weeks (vacancies are starting :))

aivans commented 8 years ago

When I said API Manager, I meant an API Designer that allows designing API-s and expose them on top of Zuul/Spring Cloud. Rate Limiting, Throttling, Access Management, etc may be a longer term plan.

daniellavoie commented 8 years ago

Sounds interesting, actuators provides plenty of KPI that can be used by this API Manager.

count me in ;)

aivans commented 8 years ago

cool

spencergibb commented 8 years ago

@aivans PR's are nice because of the communication features.

aivans commented 8 years ago

Hi guys, it was bank holiday here and I didn't have time to write down my thoughts. I'll do it in the coming days.

aivans commented 8 years ago

I would like to kick off the discussion by expressing my thoughts.

Zuul provides the foundation for building an API Gateway (routing, load balancing, ...) Spring Clouds adds another set of pre-built features. Other features required by an API Gateway solution do not exist and questions/issues raised show that people do need them. For example: configurable and flexible rate limiting, throttling, security It is very useful for defining a microservices perimeter.

The main challenge faced by Microservice Architectures (IMO) is in exposing the microservices API-s to external clients in a coherent manner. External Clients need a friendly, stable API that hides away the underneath complexity. At the same time the API developers require the tools to serve different client needs, be able to evolve public API-s. There is also a higher level of flexibility required:

This is where the current solution based on Zuul starts to show its limits. The concept of Route is too coarse grained. There is a need for a more fined grained concept, like Endpoint. Amazon AWS API Gateway is a good example. AWS has an API Designer where you define endpoints (path + Http Method). For each Endpoint you are able to configure: routing, transformations (headers, body, etc), access control, throttling. It also provides for testing and deploying changes on the fly. Endpoints can also be imported by providing a Swagger spec. Basically this allows you to define contracts for public API-s with the additional NFR configs.

First I would like to hear what other people think about this. Can the solution be reduced to adding features to SC Zuul? Are there any other architecture patterns where SC Zuul is only a component in the solution?

aivans commented 8 years ago

Great work seems to be happening here: https://github.com/gravitee-io I am wondering what triggered them to start from scratch. There is a lot of overlap with SC Zuul.

Here is an example how to define an API: https://github.com/gravitee-io/gravitee-definition/blob/7a9d46a06e138082f3921c2820ee23a311b7753c/jackson/src/test/resources/io/gravitee/definition/jackson/api-multiplepath.json

There is also a Swagger Importer.

aivans commented 8 years ago

In a few words, after doing more research and thinking, I think that SC Zuul can be enhanced in order to support features available in API Management Tools.

Generally API Management tools offer a complete end to end solution for building and monetizing an API from scratch. Additionally they offer all kind of connectors (Salesforce, SAP, ...) and integration with Identity Providers. A lot of the features provided generally overlap with capabilities that may (and probably) already exist in aa running system (Pricing, Plans/Subscriptions), so companies do not really want to change their current systems. At the same time they offer Reporting and Analytics, but it may very probably be that companies heve their own metrics and want more flexibility. It may be that some API Management tools are very flexible.

My opinion is that SC Zuul should keep it simple. It needs to do the following:

Should not do the following:

The high level Architecture and Design I have in mind is in line with the MSA style and relying n proper Continuous Delivery practices and tools. This means that everything goes through a proper delivery pipeline (origin services, api gateway, etc) versus some invented persons (Alice the Produuct Manager, John Solution Architect, etc) dragging and dropping stuff in a GUI.

The corner stone of the Design would be an API Definition artifact (Swagger, Raml, etc). SC Zuul would proxy requests to a logical layer of origin services - the API Layer Services. These services are responsible for exposing the Public APIs and the contracts are specified in a definition file (Sagger, Raml). The files are either designed (API First approach) or engineered (code annotations, etc). These spec files would need to get into SC Zuul. At this moment the simplest thing SC Zuul can do is to provide interactive documentation base don these files. The files can be decorated with other info: Rate Limits for example. I'll draw a diagram.

The advantages of such a design are:

Any opinions so far? Would be nice to come up together with a set of requirements and a Design.

kakawait commented 8 years ago

Globally agree with that, key point is to keep Zuul simple (routing) but with fully customizable and user friendly (cf idea of definition file you just proposed).

spencergibb commented 8 years ago

Some rambling thoughts

https://apiblueprint.org is similar to swagger and RAML.

I'm not convinced that having the API gateway know about all API's is a good thing. In other words, one gateway api spec to rule them all might not be optimal. I'd prefer if backing services were still in control.

expose interactive API documentation (for the exposed API-s)

I don't that that is absolutely required. It also may end up somewhere else in the spring cloud ecosystem that could be exposed through zuul.

aivans commented 8 years ago

Thanks for the comments.

The documentation can live somewhere else technically speaking. Swagger, Raml, etc - I have no preference. Raml seems to be pushed heavily by Mule, otherwise Swagger seems quite popular.

The services are in control since they are providing the API spec and are responsible for the actual implementation.

The main point is that the API Gateway handles a few concerns like Rate Limiting at the edge and these concerns require fine grained endpoint knowledge in order to be really useful. The API spec provided and interpreted by the API Gateway may provide this granularity.

stiyyagura commented 7 years ago

@aivans @spencergibb Regarding --> intensive manipulation of requests/responses: Transformations (I will explain shortly). Does Zuul support transformations (request/response) currently? By design API Gateway probably does all the custom transformations needed and if Zuul doesn't support do we have any work around for the same. Also in case if we wanted to send a context of user session data how can we send it to back end services, currently i can add the data in Zuul Headers but i feel its too much to add user context/session data to headers. Please let me know your comments.

spencergibb commented 7 years ago

@stiyyagura in custom filters you can do anything you want since you have access to the request and response. Not sure this fits in complex prefixes discussion though.

stiyyagura commented 7 years ago

@spencergibb I felt that zuul having different templates for transformation may help everyone something like we have in AWS gateway. Not really sure if this is correct thought process.

spencergibb commented 7 years ago

@stiyyagura keep the transformation conversation to #1733

spencergibb commented 5 years ago

This module has entered maintenance mode. This means that the Spring Cloud team will no longer be adding new features to the module. We will fix blocker bugs and security issues, and we will also consider and review small pull requests from the community.