In our GraphQL api (Apollo-Server) we would like to add a new dataSource which accesses GitHub's GraphQL api. We are looking to consume this data. It appears that using apollo-datasource-rest` is a good approach to do this. It's an established, still maintained module which provides caching, access to context and other dataSource benefits. It's also managed by the Apollo team. We want to verify that this is a good approach for making requests to other GraphQL APIs.
Other options are:
Roll your own datasource, which doesn't seem necessary or with apparent benefits
Build out a datasource using #apollo/client
There is a module, apollo-datasource-graphql, which appears fits this perfectly, though it has not been updated in two years and appears it may be unfinished with tests and request caching not complete.
Is using apollo-datasource-rest a good practice for accessing other GraphQL APIs as a dataSource in a GraphQL server service?
Is there a better, more established approach for doing this?
We are having the same concern since our backend needs to consume, as a client, a graphql api. The REST interface approach is expecting http GET queries to be cacheable, but not verbs like POST, PUT, DELETE... My understanding of GraphQL is that if you are only using http POST as a communication pattern this is going to prevent apollo-datasource-rest to handle caching for your queries and then it may not be the appropriate lib.
Other approaches to consider:
apollo-datasource-http
Apollo server (and the GraphQL specification) also supports GET queries so it may solve apollo-datasource-rest caching issues
usage of graphql-code-generator to generate the consumer of the target GraphQL api (and then use the client directly inside a service, or define a custom datasource to wrap the client)
Related
Background : I am using spring boot with embedded jetty. My app calls bunch of rest apis. For calling these rest apis I use spring rest template.
Question: Is Spring rest template any good at high concurrency? Searching on the web search suggests moving to reactive but still there are apps which are written in blocking way and need to continue that way. Question is what alternate is there or what can be done to make rest template more responsive under heavy load. PoolingHttpClientConnectionManager improves things a bit but essentially still not at par with is required.
There are suggestions to move to rest easy and other http clients but no slid reasoning behind it. End of the day, they all make pool of connections and essentially works the same. Please note, reactive is not an option yet. This question is very specific to traditional blocking rest calls. Any suggestions in optimizing connection pooling or using rest template right will be of great help.
RestTemplate does not do an actual rest call by itself, its just a "wrapper" - a convenient API.
Now when it comes to connection pooling, by default it doesn't use any kind of pooling and just opens URL connections available in Java anyway. No third-parties are required, but performance is not so good.
You can configure rest template to use, say, OkHttp Client under the hood. See here for different ways to work with different clients. The interesting part is that its possible to configure connection pools there and achieve a better performance.
So you should really check what exactly the expected performance is and configure the connection pool accordingly.
Now one more thing about Reactive stuff - it won't give you a performance gain, however it will allow to serve better multiple concurrent requests by reusing resources more efficiently. However if you'll measure how long it takes to perform one single request - its not expected to be performed faster.
In other words you should consider the transition to reactive stack if the application has too many concurrent requests that it can't serve, but not if you want to process every single request faster.
Spring RestTemplate is used to write application level code. It obtains the HTTP connection from ClientHttpRequestFactory implementation which is what glues low-level HTTP client library to Spring e.g. HttpComponentsClientHttpRequestFactory for Apache HTTP Client.
Bottom line, in most cases you have to tune the underlying low-level HTTP client library and not RestTemplate when you are tuning outgoing requests to external APIs.
You are confusing a lot of concepts in your question. Try understanding what is Reactive programming, HTTP, HTTP pipelining, and TCP/IP before you start tuning anything. Otherwise you won't find where is your code's bottleneck and you will end up tuning wrong part of the software stack.
I am in a dilemma over to use spring's rest template or elasticsearch's own high/low rest client while searching in es . Does es client provide any advantage like HTTP connection pooling , performance while compared to spring rest template . Which of the two take less time in getting response from the server . Can some one please explain this ?
The biggest advantage of using Spring Data Elasticsearch is that you don't have to bother about the things like converting your requests/request bodies/responses from your POJO domain classes to and from the JSON needed by Elasticsearch. You just use the methods defined in the ElasticsearchOperations class which is implemented by the *Template classes.
Or going one abstraction layer up, use the Repository interfaces the all the Spring Data modules provide to store and search/retrieve your data.
Firstly, This is a very broad question. Not sure if it suits the SO guidelines.
But my two cents:
High Level Client uses Low Level client which does provide connection pooling
High Level client manages the marshalling and unmarshalling of the Elastisearch query body and response, so it might be easier to work using the APIs.
On the other hand, if you are familiar with the Elasticsearch querying by providing the JSON body then you might find it a bit difficult to translate between the JSON body and the Java classes used for creating the query (i.e when you are using Kibana console or other REST API tools)
I generally overcome this by logging the query generated by the Java API so that I can use it with Kibana console or other REST API tools.
Regarding which one is efficient- the library will not matter that much to affect the response times.
If you want to use Spring Reactive features and make use of WebClient, ES Libraries do provide support for Async search.
Update:
Please check the answer by Wim Van den Brande below. He has mentioned a very valid point of using Transport Client which has been deprecated over REST API.
So it would be interesting to see how RestTemplate or Spring Data ElasticSearch will update their API to replace TransportClient.
One important remark and caveat with regards to the usage of Spring Data Elasticsearch. Currently, Spring Data Elasticsearch doesn't support the communication by the High Level REST Client API. They are using the transport client. Please note, the TransportClient is deprecated as of Elasticsearch 7.0.0 and is expected to be removed in Elasticsearch 8.0!!!
FYI, this statement has been confirmed already by another post: Elasticsearch Rest Client with Spring Data Elasticsearch
the technology stack in our company are:
Java, Spring MVC, Spring Boot, Jaxws etc..
and we provide webservices for the client to querying our services.
in terms of securing the SOAP service. some of the webservices uses spring OAuth security and some of them uses the Spring Basic Auth
recently one of the client flooded our server by sending huge amount of request in the short period of time.
we are going to implement something to provent this to happen. ideally a
per client based calling interval. which can recognize the high calling frequency. then ban the client or force the client to wait
before we code this from the scratch, I wonder if there are libraries we can reuse. Spring normally very good at providing solutions for most of the enterprise issues. but so far I have't found any thing. any hint, ideally a working sample. would be great!
EDIT1: ideally we want to implement this instead of fully rely on the HTTP server e.g tomcat or apache to handle this. because our own implementation would offer more fine grained rules, such as how long the interval should be,
what kind of customised message we can return, more important we can implement our own monitoring mechanism, and treating different client with different traffic allowance etc...
I have an application with Spring, and I need to call many different types of back-end systems (legacy mainframe, ESB, RESTful...). If we take e.g. REST, I can implement a RESTful client with e.g. RestTemplate. I can A) have developers use RestTemplate client directly, to which they pass the service url and dataobject. Or I can B) wrap RestTemplate inside our own, back-end specific client and offer explicit methods that developers can use. The methods themselves would then ofcourse use RestTemplate and make the explicit back-end calls.
The good with A) is that changes in back-end systems to not need changes to client. Downside is that we don't hide the architecture. B) is more clear for developers and easier to "manage", but changes to back-end systems require us to update all applications that want to use the new back-end functionality. Even worse, a change in back-end system functionality may require all services to be updated.
Still, I am personally leaning towards option B), because it is provides such a nice separation of business logic and architecture services for developers.
I don't understand how you came to the conclusion that clients don't need an update (option A) if they want to use new functionality or if the API breaks because of a change.
I think option B is better. But I would use the HTTP client Feign to create request templates and then publish the interfaces. This way you won't even have to wrap a RestTemplate and manually implement every request.
When using the an instance of the DataServiceContext class to materialise objects from an odata endpoint where the endpoint exposes some custom annotations, how does one get hold of the annotations data. I can't see any obvious extensibility points.
Custom annotations aren't exposed as a first-class concept on the DataServiceContext, but you can access them by hooking into the client response processing pipeline. This code will run after every entity is finished being read:
context.Configurations.ResponsePipeline.OnEntryEnded(
entryArgs => DoSomething(entryArgs.Entry.InstanceAnnotations));
Internally, the WCF Data Services Client uses a lower-level library called ODataLib (aka Microsoft.Data.OData on NuGet). The response and request pipelines allow you to dip into that lower level to get extra information when you need it, but you still get all the conveniences of using the full-fledged WCF Data Services client library. The classes like ODataEntry, ODataFeed, etc. that you work with on the processing pipelines are all part of the ODataLib API.