Being able to extend existing types is brilliant because it allows modularisation of the code and separation of privilege. I have found good examples as to how to extend objects outputs in query (see below), but no good way to extend what inputs a given object has.
For the sake of the example lets say we have a class User
.
class User {
String firstName;
String lastName;
}
If we declare a bean, we can have a query like so:
/**
* This is valid and can be invoked using
* query {
* user(id=1) {
* firstName
* lastName
* }
* }
*/
@GraphQLQuery(name = "user")
public User getUser(@GraphQLArgument(name = "id") long id) {
}
Then in another bean bean we can extend the User
/**
* <<this currently works>>
* So now this query becomes valid
* query {
* user(id=1) {
* firstName
* lastName
* address { <-- this is not a top level, but extends User
* streetNam
* }
* }
* }
*/
@GraphQLQuery(name = "address")
public Address getUserAddress(@GraphQLContext User) {
}
Similarly for mutation, we can define:
/**
* <<this currently works>>
* This can be invoked using:
* mutation {
* addUser(user :{
* firstName: "John"
* lastName: "Smith"
* })
* fistName
* }
*/
@GraphQLMutation(name = "addUser")
public User addUser(@GraphQLArgument(name = "user") User user) {
}
Now I am trying to add address
, in the same manner we added it for query, but add be an input argument of User
.
The following is still declared in some bean.
/**
* << this is what I am trying to achieve>>
* I want to be able to invoke the following query and not having to declare 'Address' inside of 'User' class.
* mutation {
* addUser(user :{
* firstName: "John"
* lastName: "Smith"
* address: { <-- being able to pass address as argument now, and be part of user.
* streetName: "1 str"
* }
* })
* fistName
* }
*/
// e.g. something like ...
@GraphQLInputField(name = "address")
public void addAddressToUser(@GraphQLContext User user, @GraphQLArgument Address address) {
}
I came up with a way you can do this currently, but it requires some effort.
I'm using GraphQL-SPQR 0.9.8 (that I'll release in a matter of days). You can achieve the same in 0.9.7, it's just a little less ergonomic.
That said, it would maybe be easier to just register a custom deserializer in Jackson (or Gson, whatever you're using) and skip the custom
ArgumentInjector
.