Transcript for:
Spring Interface Clients Lecture

[Music] okay let's start hi hello how are you today are you enjoying the conference yeah awesome so thanks a lot for coming to my talk about spring interface clients that is not from this year but we still feel like all the community doesn't know about it so we would like to show it more and have people to try it and give give us more feedback um yeah let me switch this on okay better uh my name is Olga maash Sharma I work on the spring Cloud team where I am the committer of all the projects but I mainly just work on springcloud load balancer spring Cloud old Fame spring Cloud Netflix and I've been also doing a ton of work to make spring Cloud projects work with aot and spring grvm native images and yeah I also have been collaborating for some time with the spring framework team on the interface clients and have contributed a lot of the functionalities that I will be showing here uh so what is a declarative client basically if we have two Services a customer service let's say that wants to to register customers and a verification service so the customer service will ask hi is this a real person or is this a fraud can I uh register them and the verification service will respond with some kind of customer verification result now there are many ways to do this in our class let's say we have some service class that is supposed to register people and then what can we do well the simplest way not necessarily the best way is just to take a an HTTP client put it into that class do some kind of setup to set the URL and maybe some header prepare somebody and just do a post and get a result and then we can obviously do this for each and every call that we want to do to that service uh so obviously as you can imagine that is not a way of doing it that I would suggest we can make it a bit nicer we can create an interface and in this way first of all we have known parameters we have secondly known return types more people can use it more people can implemented and have different implementations for let's say different environments testing staging and so on and it's more readable more usable looks nicer it's more friendly uh and then obviously we need an implementation of this so again thanks to this we can have different implementation this one with rest template we are doing all the same but this will will not we will not be now be able to reuse it in any class that wants to contact this service and obviously we can now move a lot of the helper code to some utility methods because if we are contacting that verification service very often even though let's say we are going to call different endpoints but very often we will have some similar setups so the base URL might be the same there may be a subset of headers or cookies that will repeat so we can move though and then obviously we instantiate a class um that implements that interface so we have a verification service client object and now in our service class it is very readable and nicer now uh is this a completely new idea no can libraries and Frameworks help us with it yes so basically what people always want it is to just have this interface paste some annotations on it to be able to indicate what actually is going to be my header and what's going to be my body and so on and then have a library or framework to actually do all these HTTP real client setup and all the codes Under the Hood how is this done so mostly what the libraries do is they take that interface interpret it and based on that they create a proxy of that type and it's the proxy that places the actual calls and again there have been some earlier implementations of this a super popular project is Fain Fain has like 9,000 more than 9,000 stars on GitHub it is a NE project and uh we also have spring Cloud open F that provides integration for it this is the way that a Fain C looks like so we have the interface and then we have the request line which is The annotation that will tell us what we actually want to do so which HTTP method what end Point any additional information can be also passed in parameters as the params one and we can pass the body and so on and then we have spring Cloud open fan which what it allows you to do is have the F client underneath but kind of copy paste all this uh spring MVC server side annotations and use them on the client side so as you can see we have post mapping that is the same we have request body request Fe and so on we also have the ne F client annotation and that allowed us to create all the auto configurations so we instantiate all the beans but not only we instantiate them we also set up the load balancing for them and we use this as a service ID we set up circuit breaking if you so want we set up tracing and so on nice many people use it but some problems started appearing for us so um basically were free problems the first problem was that somehow enthusiastically the all the serers side anotations were now put to the client side and it's awesome because you can take your controller just copy it paste it to the client remove the bodies and you have your interface client however if we look at this in more detail actually the server wants to do more elastic things than the client for example if we have a request mapping we might map various HTTP methods in a client we need to know exactly what method we will use otherwise we cannot make the call same with the URL the server can accept some sort of patterns placeholders wild cards possibly serve various requests that start the same way but have a different ending of the URL we cannot do this in the client also spring MVC has very s specific things like you can have a model attribute with model attribute annotation passed in the arguments you can return a view things that didn't really make sense for us for this client but the community kind of expected all of this to work and we got issues like okay I copy paste it I remove the bodies and it's not working why is it not working if it's working on the server side do we want to make it work do we want to have some kind of process where we try to think oh what did the user want to do maybe but maybe not because it would be very ambiguous and people would have different ideas of what it should do so we took something an annotation that did something broader to use on something narrower that was maybe not the best choice another problem that we had um is that it is a third party Library Fain core and then spring Cloud open Fain is maintained by us and the F core team is fantastic they are really great developers but um they have their own schedule they have their own priorities and if we want to introduce something or have some issues we don't necessarily get all the changes in core that would support it as fast as we want because obviously it's a different team and they can do it this way but since it was very popular we would still just continue with it however a few years ago as you may know spring put a lot of effort to make sure that we fully support the reactive stack so we got the project reactor support and in web we got web client and web flex and we got our socket support and it was all added in framework and then our users started asking us okay how do I do this with Fain and how do I do this with spring Cloud open Fain and can you guys provide that integration so we started looking at it if there would be any way that we could possibly provide it but unfortunately the way fan is created it would need some re architecting in the core Fame to allow us to handle this so we started thinking what to do with this and since it was coming out of the spring Cloud team and we mostly did Integrations we thought okay if we use retrofit actually the underlying architecture is such that we can plug in web client underneath and we can also use reactive return times so we can handle it and we proposed it as an incubator project to handle any reactive request with a declarative clients and provide autoc configuration and load balance and tracing support and all the goodness that we provided with open fan and then when it comes to uh our sockets uh Josh long created the Retro socket another incubator project to create interface clients for that so at some point we had many projects and we were thinking like okay do we move the spring Cloud square and retrofit support out of the incubator do we take this retro socket on as a proper project do we join them so had a big call because on the spring team any major decisions uh are taken in a So-Cal lead call where and the tech leads for different teams discuss things together with the people that bring up new topics and then the framework team told us you know what we actually had an issue to create something like this but we always close these kind of issues because we wrote them okay we have spring Cloud open Fain that integrates Fain and it's perfect there is nothing that it doesn't handle and then we realized okay so we don't handle our sockets we don't handle reactive HTTP uh requests and maybe actually it's the time to start having something within the framework especially that framework traditionally has always done things has always handled HTTP communication uh so and and made things easier to set up for developers when it comes to communicating over the web so why not and so in this way the spring interface clients project was created it came in in 6.0 it is now fully usable so if you want to use this you need uh well let's start with HTTP and later talk about our socket but for HTTP you choose if you want to use web flx or if you want to use web firstly we started just with web flx support now we have both and you have a new annotation HTTP exchange so this is the one that we have introduced to solve the problems that we have with request mapping and we decided not to go into that corner again it will be a tiny bit more complex because people cannot just copy paste stuff they will need to put this new annotation but then they will also actually need to think what is this that I'm really trying to do as a client so we thought it would make sense and then obviously you need an interface and in that interface you need to put methods that you will annotate with this new annotation and it takes several attributes um you can specify HTTP method or even you may need to unless you pass it as an argument which I will show and you can specify the URL and then when you instantiate such a client which I will also show you can just call the method you get your result and it translates to a simple get that we will do underneath from a proxy other attributes uh content type and accept that you can put on HTTP exchange obvious ly this will add either accept or a content type header we also have shortcut annotations so you can do get exchange but you can also do all The Usual Suspects and yeah it's handy and nicer to use when it comes to parameters uh you can pass first thing that you can pass is HTTP method so actually if you have an HTTP exchange you either need to specify the method the attribute or you set a method as the argument and then when you call it you pass it and you get write method called uh what is fun about this it is that you can actually override the method during the call so even if you make a get exchange but you allow passing the method as the argument you can while doing the call decide to send it else well with a different method you can also override the URI so obviously if you don't pass it anything you get the default one without any additional segments uh but you can just pass your segments in the URL as we have count above but then you can set it as an argument and if you pass the URI as an argument what we will do is override the whole thing so the call will only go to Stats count and will not have another count appended to it we ignore whatever was said in the attribute and that was fun and well but then people told us that look guys we do it sometimes but what we really do is to have the same end of our URL and the other segments but just change the Bas URL because we want to do the same thing but on a different machine or different instance whatever so we decided to address it and now we also provide a way to change as the base of override the base of that URL and what you need to use for this is provide URI Builder Factory as your argument so again you can just use the default U Builder Factory and pass a URI string and then what we will do we will change it so let's say it was Local Host 80 81 and a base URL but we can change it during the call uh and that will be also helpful yeah if you want to work with different environments for example this is something that can be done another thing that we have added ah and going back to this if you see this this kind of star icon H it is one of the newer things added over the past year so as you see we keep adding features to this um another thing that we've added is to allow you to prefix all your calls from a given client with a certain segment of your path so that's similar to request mapping if we have this placed on the interface it will always have the slash verification before whichever uh segment comes from the URL on meta level so that is also probably useful and then we can do all the other stuff we had we can pass the request body and then as you can see this is the same annotation that we use on server level so while we didn't want to introduce this ambiguity and provide annotations that do more stuff in a different context we wanted to reuse those that would do exactly the same so request body is a request body it wouldn't behave differently in a client context versus a server context so we reuse it obviously the same goes for headers and we can pass objects we can pass maps multivalue maps or a collection of values obviously we also want to handle any path variable so you can use placeholders uh request parameters with the request param annotation and there you handle objects again maps multivalue maps or you can pass a collection of values and the same types you can also pass with cookie value annotation to set your cookies okay this is a fun thing so uh for web client another thing that is available in the web client itself is request attributes there is also now an issue in framework for rest clients so it is possible that it will appear in rest client as well and then we will uh support it nearly automatically I think there's like a one bullion that we need to change to support it in the interface clients so if the the request attributes are very neat if you are doing something if if you want to transform or further work with your request still on the client side uh this is an example with web client and web client allows us to Implement Exchange filter functions and in a kind of a group way modify whichever request pass through and the way it is done is if you implement the filter method you can basically change your request and as you can see here we had uh one request but then we have a new one and uh we are going to send a new one and this is an actual example example from an issue that we got from a user so basically the user said I want to look for um request attribute named org on my requests and if I find them then I want to build a authorization header per given organization and add it for that request and if I don't find it I just want to continue with the request as it was so request attributes need are useful and soon probably also in rest client and we have also been handling them from the beginning you can add them for whichever client supports them uh we also handle request parts and you can either have them just set like this separately with a request part annotation or if you give us a multi-art file uh it doesn't even need to be annotated we will see the type and handle it properly and here you can also see the example of setting the content type and the attributes return values um okay so you can return pretty much anything that you may need uh we have a normal concrete value what you need to keep in mind is that if you do this but your underlying web um HTTP client is web client so a reactive stack what will happen is we do return this concrete value but there is no magic some somewhere it has to be blocked for us to return it so yeah what we we do is actually call a block underneath and you need to keep in mind that there are some scenarios where this may make sense but mostly if you're are working on a reactive staff it will not make sense and even if you will try for example to call that um let's say in a controller you will get an exception because you cannot be blocking in that thread so mostly you will do this if you are working with web client obviously mono flux and any producer that can be converted to a reactive stream publisher using a reactive adapter registry uh so yeah a mono and obviously if you have rest template or rest client you will not be able to use mono or flux then we also provide response entity so that gives you status headers and body or HTTP headers or execute only okay how do we get this kind of clients so at this point this is a twep process the steps are two but they are very simple and easy so first we need a service proxy Factory which is a bin that will be able to create a proxy in this case HTTP service proxy Factory once we have the proxy Factory we can create the service instance beans so in order to have the factory we need an underlying client because again we are using whatever spring ring already had so we need either web client or rest client or a rest template and we build it whichever way we want or we have it already configured as a bin in our application and we can just inject it or we can use a builder and for example I use some setup from boot or some tracing any additional instrumentation that we have and just change whatever we need to change and what usually want to change is a base URL so this will be the URL for the instance that we want to communicate with and then we can just create a builder and we wrap the client in an adapter so we have web client adapter and we will also see adapters for other kinds of clients and and then we build it and once it's built it just one line you just call HTTP service proxy Factory create client and then we add so the verification service is the interface that we've been looking at so we add that signature and it will be created for us obviously if there is a builder for something it usually means that there are more things that we can configure so in this case we can configure the embedded value resolver at the custom one so that is a string value resolver for resolving placeholders and expressions in the URL then there is a conversion service that is what that's doing is formatting uh inputs as string and these are all fun and well but I don't think many people would change them what is most important here is the custom argument resolver so if you want to handle an argument either a type or a specific annotation that we don't handle but you have some custom scenario and you want to handle something else it is very easy you just need to implement the HTTP service argument resolver and then you get the argument the parameter and request Valu so basically what you can do is first of all check stuff on the parameter what type is it uh does it have some kind of annotation you can take the argument and you can transform it in any way you like and then what you do is you add it to the request values so that it is accessible later on and you can register a custom argument resolver like this on the HTTP service proxy Factory Builder so yeah it should be straightforward it gives you a lot of flexibility in terms of your specific scenarios and then obviously for rest client we do all the same we just have a rest client adapter instead of web client adapter and again we can also do the same for the rest template just using a rest template adapter Okay so we've done this and we've released it and people started asking question and actually one of the most frequently asked questions was okay this is all fine and nice but how do I handle any errors if I want to handle them in my own way and not just end up with whatever default handling and actually since it is our infrastructure uh you don't need to handle it on the interface client itself or in the proxy service Factory you can handle it in whichever client you are going to put in the adapter so it's very easily done for web client you can just set a default status Handler and that will have a predicate on one side to decide what is this that we want to handle so in this case anything that has an error and then uh you have a part where you decide how you want to handle it so in this case we are handling it with an exception in this rest client example we are handling it with logging an error and again it's the same method default status Handler obviously can also be used on web client or rest client and not in the context of interface clients separately but in interface clients we are just reusing the infra that we have and obviously we can do it also for rest template is pretty much same the API is just older but what it does is same tell me what is your error and then what do I do with it once I have it and then we use the set error Handler method to actually put it there another very frequently used thing would be load balancing because in any modern distributed system the topology of that system will continue changing as instances are brought up to life and are killed and we want a way to know where the new instance is or which instances we have and then based on some kind of configuration that we set we want to be able to pick okay I have all these instances which is the best one for me so we want to use some kind of load balancing and normally we would use a service registry to find the instances so for spring Cloud we integrate with Eureka conso zuk keeper we have kubernetes support and this is something that people ask about because I think we speak about it less if you do not have service registry which usually it does it is not the best solution in production but there are some scenarios where it makes sense you can use a simple Discovery client and just set up your instances in the properties which uh is actually how this is set up in the sample so if you're interested you can take a look and this is also good for testing because you might not want to be setting up a service registry while running your test uh and then what we need is load balancers so we just add spring Cloud starter load balancer and that's basically most of it it uh the only other thing we need to do is we need to make sure that whichever HTTP client we are passing to it is load balanced and to ensure that it is we just annotate it we when we create the bin we annotate that bin with load balance so for rest client that would be the rest client Builder not the rest client being itself and then we just have to get that one and of if you have more rest client builders in your application then you can use load balanc uh with the parameter and it also serves as a qualifier that's actually one of the things that people ask a lot about in stock overflow for some reason and then the only other thing you need to do is make sure that your base URL doesn't point to an actual host or Port because you don't know which instance you want to contact it instead you use the service ID so you put your schema and then you put the service ID and if it is HTTP verification it means that the service that we want to talk to uh has its spring application name set to http verification and if it's in ureka zoo or even console or with spring Cloud kubernetes it will register under this name so then the underline client will just get all the instances and pick the best one for US based on this and that's it same for web client we want to instrument the web client Builder and then the rest the same but for rest template this was created much before uh the other two and the the instrumentation for that and for those Legacy reasons it is rest template and not rest template Builder that you annotate with load balanc and now that I'm thinking about it I'm wondering why we don't have the rest template Builder I think the reason is that nobody has requested it uh so yeah maybe we will have it uh I might add it but yeah for now you need to use the rest template itself and then what about tracing again so as you can see the underlying theme in this presentation the tracing is also handled by web client rest client rest template which well makes for less things for me to show in this presentation but I think it makes also for better experience actually using it you don't need to additionally do any setup on the interface client uh okay HTTP exchange on server sites so for those of you that were paying attention at the beginning we might be thinking like why what is happening here we just talked how this was a terrible idea to use the same annotation on the server side and on the client side so I since I've been uh supporting and maintaining open Fame for many years I was of this strong opinion that yeah that was a terrible idea let's never do this and when people started asking us can I use it on the server side can I anot my controller with this I was like no but then I talked to my colleagues uh in the framework team and I talked to rossen and he has actually convinced me that it's a different scenario because before we took something broader and more ambiguous and with more options and try to apply it to something more concrete and specific and that obviously caused issues but now we are taking something more limited more specific with only like one option so we only have one method that will call or one only get requests from the specific URLs or send request to a specific URLs so we are taking something with more specificity and applying it to a more open scenario and the only thing it means is that if you use this and not request mapping on your server then you only get whatever that brings so basically your server also has the same limited set of capabilities in the annotated mappers but you don't really get any issues of like it should do more than it's doing so yeah I decided like I agreed with him that yeah if you look at this this way it's not a bad idea and then the team decided to go forward with it but why would you even want to use it if you have the request mapping which is by all means better for Server because handles more things that you use for Server uh so the users told us that something they did with open fan was having the controller Implement interface because then what you can do is kind of treated like a a contract and um do I specifically recommend it no I recommend spring Cloud contract if you want to have contracts it is created for that purpose because the way it is done here it will introduce very tight coupling but some organizations still decide okay for their purposes for their internal apis this is what they want and they just want to have this client even on server side share it with the actual client then implement this in the controller and it is a strong contract they're not able to call any other method and then you obviously in the implemented methods you don't need to repeat all the annotations they are already implied um so yeah possibly a questionable thing to do as I say they might be better ways of implementing contracts but sometimes it's used an important thing um I would strongly discourage doing any such thing with a public API but within an organization for an internal API this may be what you need because it's way simpler probably to start with than sprink Cloud contract but yeah if you really want to enter into the contract realm and have um proper consumer contracts uh you should try spring Cloud contract instead but anyhow we decided it would not be an issue and if people liked it we could support it so here it is it actually I think required changing one line of code so yeah not a big deal to maintain it's here and another thing that we introduced together with the HTTP interface clients are the rsocket interface clients so how many of you have ever used R socket in production in Sample how many of you know our soet okay so I will do like a quick quick intro uh subate is a very neat protocol so basically you have a protocol that takes the reactive stream semantics to the protocol level it is fully message driven and asynchronous there is no client server distinction like you can send request and response but you can also have a channels there are four modes of communicating fire and forget the traditional request response uh a case where you send a request and you get a stream or a channel and it handles all the communication as a stream uh of like as a multi Multiplex stream of messages over one single network connection it is really neat I it is not very popular and I don't know why because I think it's awesome it's very performant and if your team doesn't work with reactive streams probably it's and like you might not want to spend time doing this but if you are working with reactive stream streams it's and you have the Kno how how to work with reactive types it can be very handy to use and uh spring Cloud also provides a router similar to sprink Cloud Gateway a router for our socket and it also handles already back pressure on protocol level and it never blocks and it supports TCP web sockets and Aon as underlying protocol and uh what they write about quick in their documentation is that it was not yet brought to a level which was useful for them but as soon as quick becomes um more usable they will be able to provide support as well so yeah I always try to advertise our socket because I it's very performant and not difficult to use because spring Pro provides full support you will see the interface clients will make which make it super easy and on server side you can use the message mapping annotations similar to the ones you use in messaging to handle it on the responder and and yeah it's very easy so you will need the spring boot starter our socket and then our dedicated annotation is our socket exchange while in the responders we use message mapping again an interface annotated methods here we have less options so for example uh we had more attributes for HTTP exchange here we can only set the destination so that is also the value that we will set on the responder side in the message mapping and when it and that's that's the only one we have one attribute when it comes to what we can send again there are only few things we have the payload that is mostly what we are trying to send but we also have a destination variable which is a concrete value and this is same as pu variable so if you have plus holders in your puff you can use this argument to set the actual URL but this is neat so uh our soet uses the cont uh the concept of metadata which is similar to message headers let's say but it's it's refers to as metadata it's a bit broader use and we also handle this so for the aret metadata you need to know what the mime type is and you need to indicate what the mime type is so for the interface client if you give us an object which is followed by a mime type we know that is a metadata entry otherwise if you just give us an nonannotated object we will probably throw an exception it's not something we handle but if this is a mind time behind it we know that this is a metadata entry so we will handle this as such and that's what it will look like on the client side and that's basically all you just need one method call and you can uh send these requests it's a tiny bit um more complex on the respond side and I'm I'm going to do this quick digression to the responder to show you how to read these metadata entries so uh basically in order to be able to handle this you need to add a strategy and in strategies you need to set metadata extractor registry and there provide the information what mind type you are looking for what class you will be serializing this two and what is the entry name or header name I'm saying head because later in the message mapping on the responder side you will use the header annotation to or the headers one uh to get access to those entries uh but yeah basically two method calls to get this done ah and also look at the decoders and encoders and strategies so in um if you have an artsocket application it happened to me when I was starting the creating the demos and working with it whenever staff just refuses to serialize and deserialize properly usually just need to add decoders or uh encoders to your strategies uh return values so again mono flux any producer that can be converted to a reactive stream Publishers will work and again we can blog this for you usually not a good idea uh but yeah if you know what you are doing you can choose it just not not put the reactive type around it and then we will just block it underneath again super simple to instantiate it's pretty much the same so I will not be going into much detail because it's very similar um you will just need rsocket service proxy Factory instead of the HTTP service proxy Factory and what is uh the what is your client here let's say it is not exactly a client it's called a NR soet requester but it would do the same role as the web client rest client and so on in the HTTP interface so you just create that same as you would create it without having the interface clients because again this requester can be used to do calls similar as rest client can be used but if you do this additional few lines of setup you can later just use the interface and call the interface methods and is more readable uh so then yeah you have your Builder you create this service proxy Factory passing their rsocket request to it you build it again you can customize it here you can add uh also reactive adapter registry and HTTP you can still add it but it's deprecated so we will be moving this uh but yeah again the most important thing you can add your own custom argument resolver just Implement one method in the interface and you can decide alone what to do with this and again not going into much detail but since we allowed using um The annotation for like server side and HTTP here on responder side we are also allowing uh to use these annotations so you can have an rsocket controller that implements an rsocket interface clients and then when you implement the method you don't need to repeat all these annotations and this will work this is also one of the newer things we've added and yeah another topic autoc configurations so actually what we had in open fan or in Spring Cloud Square most of it we are now able to handle with the spring interface clients and we have Beyond feature parity for reactive scenarios and reactive types we have feature parity for most of the other headers param Etc whatever you can do with your requests uh we have Feature Part in terms of providing load balancing and tracing uh what we still lack is the auto configurations and the users have been asking for it so this is something that is now in the works uh I've started working on it before I left for here and that's going to be the first thing I will come back to and then yeah I really hope we manage to get it in uh so this is more of a trailer some kind of questions or like considerations uh that we are trying to keep in mind while creating this feature and I thought I would share it with you um yeah so that you can participate in this discussion maybe or have some other ideas so first thing if we want to add something like this we need to think how will we enable the auto configuration how will we even tell it that we want to Spring to just start instantiating the means for us and setting them up and so on so with Fain we use um enable Fain clients and that annotation allows you to specify for example specific classes or packages that you want to scan and that kind of solution with a separate annotation is nice because of this because it's more fine grade so you can tell them okay scan for me this but don't scan that so I want this client but not the other one you can pass some additional configuration but it's another annotation maybe it's enough to have a property that's something to think about another thing how do we find the actual interfaces again if we had that previous annotation then maybe we just indicate there but if we don't decide to go with it then maybe we look just for the HTTP exchange or socket exchange annotated ones H but for example in Fain we had a Fain client annotation and that allowed us to also pass the service ID and that we used for load balancing and we used uh for circuit breaking and also additional configuration but again this is another um annotation and while in Spring Cloud we provide an integration layer and we are a bit more liberal with adding stuff with framework since this is API and this is like core level they have to be very conscientious and also in boot should we really have another annotation so this is something to decide if we create these annotations where do they go since it's out of configuration the configuration probably go to boot but various um similar situations are such that even when there is an annotation for used for auto configuration for example with data that is used in boot it still lives in framework so something to consider another thing how do we find or create the underlying client because let's say I have an interface and I need a client now do I set up the client uh in the auto config fation and then just use whatever I think is the best default or do I want the user to set up the clients and I just find them and if yes how do I find them should I use an some kind of qualifier or maybe some kind of a naming strategy should we handle only one per client or should there be a default that we can fall back to and also we could once we have the client we could just alone create the service proxy Factory but service proxy Factory also has some possible configuration so maybe we should also allow the user to create this one so as you see a lot of things to think about and consider and then once we have found these clients or decided what they should be like and we have decided which proxies we need and based on which interfaces we create this Proxes we need to add Bean definitions and this again can be done in various ways there is a very neat interface uh import bin definition register which does exactly what it says it does so if you want to import additional bin uh definitions you can use it but there is also bin definition registry post processor where you can basically modify the bin definition registry and then again you can have a very simple bin definition or create Factory bin that's what we use in open F that allows you to do more setup and for example store the service ID and other details and there are some existing implementations for auto configurations especially for HTTP clients so myov that I'm I'm sure many of you know who is also the maintainer of spring Cloud AWS and an awesome developer has created one for HTTP and yeah I recommend you use it if you want to use something now uh but obviously this is again a kind of feature that is very close to our stack so we would like to have something internal so we have started working on it as a team Josh long has created a PC and now uh we are having this kind of discussion and work to see how to adapt it to more scenarios and and more complex scenarios and probably we'll start there to uh provide the solution and why am I doing this whole trailer section since I'm not showing you any code yet this is because we have an issue and if you're interested in this you can participate in discussion and once any po request appears it will be there by whoever like link there whoever creates it whether it's me or anybody else and then you can provide your own scenarios or your own ideas or criticize and write no this will not work because of such so that's why I've added this section uh here and a sample okay so there is a reason I'm calling it a sample and not a demo and the reason is um that since I'm not showing any complex setups of anything here and I'm talking about apis um the sample really just contains um the API so we have a service that does verification and we have a client that uses interface clients uh to communicate of with it over HTTP as you can see we are doing all the same things that were available in the presentation and then we have a controller which is a point of entry so basically we will use the client if you hit this controller uh we will use the client to contact the other service and then there's the same thing for our socket so there is the r soet verification which has the annotated respond there and it's here there are two actually one that implements the interface client and one that doesn't and then there is another application that actually does the call and I've added a controller and HTTP as a point of entry and also added a command line Runner that will uh output the blocking value that would fail if I tried to do it from a controller because we would be blocking on a threet where we are not supposed to block and I figured that you guys know how to do HP codes and that is probably not going to be interesting if I now start just calling these end points for you so I decided that instead of demo there is a sample and this might be used F if you want to do this in your own project and set up your own interface clients because most of the scenarios I've discussed I've set up in the sample you can also see uh the load balancing and non-load balance scenarios how to instantiated uh any additional setup that we need for it to work but mostly just all the possible usages I think there's most that you can do with interface clients so I will share the link to this when I share the slides and I'm not going to try to call these end points now because yeah you can do this at home um it's the link um yeah I will also share the slid so you don't need to take pictures but you may if you want and yeah feel free to visit the spring and tanzu boof there were colleagues such as dasan and then and I think J before but yeah people come and go so you may find people from our team and yeah thank you very much um yeah we don't have much time for questions but I'm very happy to take questions in the corridor or after it or for the app that comes or Twitter yeah uh do we have okay we have time for one question probably uh yeah thank you for the presentation uh in Fain there is a concept of Child Spring context like you have an interface and configuration class which you want to exclude from your main component scan otherwise you will end up with overriding and I've uh seen many people confused with that so are you going to use this concept in your out configurations yeah it is confusing it was kind of difficult for us also when we were working vot uh for example um yeah so I think the team will be against using that same thing we still want to provide the load balancing but since we probably want these Auto configurations to live in boot that has not been yet decided we want to allow the users to set up their load balancing and we may then just use the setup instances so this is done underneath but will not probably happen in the actual interface clients and yes I think I don't have more time but uh I will stay here so if anybody has any questions I'm very happy to discuss thank you [Applause]