File upload with SPQR Graphql - spring-boot

I'm using spring boot and spqr graphql library. I need to upload a file(s) via graphql. I don't know what object type to expect in the service and I'm assuming that this isn't even supported.
Has anyone tried this? Any advice?
Thanks.

(Assuming you're using SPQR Spring Starter)
Uploading/downloading binaries is currently inconvenient in SPQR, but not impossible. You'd need to override the provided controller with your own and decide how you want to receive the queries and binaries, and how you want to send the results and binaries back. To override the controller, just provide your own bean of GraphQLController type.
Your best bet is implementing the GraphQL multipart request spec which thanks to Spring shouldn't be too complicated.
Btw you can always get to the raw request by injecting #GraphQLRootContext DefaultGlobalContext<NativeWebRequest> request as a method argument. From there you can obtain input and output streams.
You can also wire in a custom ArgumentInjector that can inject something more precise if you want.
In the near future, the starter will support the GraphQL multipart request spec out of the box.
If you're not using the starter, the situation is similar in that you're kind of on your own with implementing the transport for binaries and queries.
But, with all that said, it is generally a best practice to handle dealing with binaries outside of GraphQL completely (only send download URLs and such using GraphQL), so I highly recommend that approach if possible. The reason is that requiring optional specs breaks out-of-the-box compatibility with most clients.

Related

Spring Data Rest modify Repository method URI

This may be a bit of a rudimentary question, but I have a repository where I can do a find by username as follows:
....../items/search/byUsername/?username=myusername
However, this is generally inconsistent with how AngularJS Resources treat queries. Is there a way to instead make the request URI for the same thing to be
....../items/?username=myusername
Or does that functionality not exist with spring data rest? custom methods can be made in the angular resource but it is tedious to do that for every possible search category
If Angular (read: a client library) defines what URI's have to look like, then it's fundamentally violating a core REST principle — which is that clients follow links and URI templates.
That said, if you're using Querydsl and let your repository extend QuerydslPredicateExecutor, collection resources can be filtered by using property expressions. See the reference documentation for details.
Another option would be to manually expose resources under the URIs expected and manually forward the calls. But again, I'd argue you're better off teaching Angular to behave like a proper REST client in the first place 🙃.

Spring MongoDB REST API without HAL?

This Guide shows how to easily create a RESTful interface to a Mongo Database. It produces Json-data in HAL format(Hypertext Application Language), but unfortunately I am unable to find a working Android Client that supports HAL.
Is there any way to disable this HAL format an just GET the documents from the DB without any extra? So that it can be directly parsed into my datatype classes?
It would be really nice to use this approach to somehow automatically generate the REST interface, I cannot go back to manually writing all the methods in controllers after seeing this very short code.
This post seems to deal with the same topic, but I do not understand how to do this configuration.
The guide you are linking to is specifically aimed at using Spring Data REST + Spring Data MongoDB, so to disable the hypermedia for a project designed to generate hypermedia, i.e. a RESTful interface, sounds very strange.
On a mobile platform like Android, the question is what are you trying to do? Are you trying to query for a single, small piece of JSON from MongoDB? The risk of not having any type of hypermedia layer in the middle is that you could query for a giant (i.e. humongous data set) and cripple both the server and mobile device.
For more details about hypermedia and Spring Data REST, check out Oliver Gierke's answer at Disable Hypertext Application Language (HAL) in JSON?.
Regarding the ability to communicate between Android and a HAL backend, of course it's possible. You may wish to look at Roy Clarkson's sample Android app used to talk to a HAL backend that was used at SpringOne 2014 at https://github.com/SpringOne2GX-2014/spring-a-gram-android.
The slides from that presentations are at https://speakerdeck.com/gregturn/springone2gx-2014-spring-data-rest-data-meets-hypermedia.

spring data neo4j - using server extension through repository

I read about the server extensions available in neo4j in server mode. I was wondering if it is possible to somehow annotate repository method to use this extension insted of allowing to create query based on method name or #Query annotation?
If not, is there easy way to invoke REST interface methods using Neo4jTemplate?
That's not possible right now, it would be cool though, feel free to raise a JIRA issue that describes your suggestion in more detail. Perhaps Spring-Data-REST Clients allow such a thing.

Managing method implementations on DTO's

I am looking for an elegant solution to writing methods on DTO's
The problem arises from the fact that methods on a DTO can be used both on the client side and server side. Subsequently problems arise when you make use of any Client or server side specific methods. This generally results in an java.lang.NoClassDefFoundError exception.
The project that I am currently working on uses GWT and spring. I experienced this problem when trying to format an date on a DTO. The format method was throwing an java.lang.NoClassDefFoundError when GWT.create(GlobalConstants.class) was called. I am looking for an elegant way to differentiate if an method is being called from the server side or client side and adapt the implementation of the method accordingly.
First off, if you have such methods, then your object is not just a DTO (by definition, a DTO only has accessors and mutators).
That being said, there are several ways to solve your problem with your objects.
to solve the NoClassDefFoundError, use com.google.gwt.core.shared.GWT instead of
com.google.gwt.core.client.GWT. The shared class is present in both gwt-user.jar and gwt-servlet.jar.
You can use GWT.isClient() to tell whether you're on the client-side or server-side and branch to the appropriate code.
Starting with GWT 2.6, GWT.create() can be used outside of a GWT client-side context, so
you can make it work on the server-side (you have to provide your own ClassInstantiator to com.google.gwt.core.server.ServerGwtBridge.getInstance()#register())
If you have a server-side-specific method that wouldn't even transpile to JavaScript, starting with GWT 2.6, you can annotate it with #GwtIncompatible (any such annotation will work, the package doesn't matter, only the annotation name) and GWT will do as if it isn't there at all.
finally, when none of the above works, you can "fork" your code into a super-source, so as to provide distinct server-specific and client-specific implementations. See “Overriding one package implementation with another” in the GWT documentation.

Spring mvc - get data from other server, what object to use and how to reuse it?

I have some url that I need to read data from there and use it in my controller.
Usually in java application I use http client, to get data from some url.
My questions are:
What object to use in spring mvc to get data from some url (like http client) ?
How to reuse this objects, so every time not to create it ?
Thank you!
In agreement with the comment by #Evgeny and #Beau above, you can use any client library you like. HttpClient is VERY bean friendly and, for cases where it might be difficult to construct the configuration, you can always provide a Spring factory bean to construct the object.
If you are looking to abstract away the plumbing of the HttpClient API usage, utilize the RestTemplate suggested by #Evgeny (I believe that it is also his brainchild) It is a VERY rich and simple API to leverage.

Resources