Skip to content

jaskaransingh156/spring-boot-graphql-with-custom-rql

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 

Repository files navigation

spring-boot-graphql-with-custom-rsql

Context

As a Backend Engineer working on Microservices and creating REST APIs, I always felt the need of having some way so that I don't need to create multiple REST APIs for same resource. There are mainly two reasons due to which the requirement of having multiple APIs for same resource comes:

  • First reason is amount of data required is different in different scenarios. For eg: consider a User resource having say 20 attributes. Imagine two scenarios - first where all 20 attributes are required by client and second where only 2 of those 20 attributes are required. We can live with sending extra data in second scenario but it would unnecessarily impact the performance due to transfer of unneeded data over the wire.
  • Second reason is say earlier, we had given filtering & ordering functionality with a certain combination of certain fields and now we require to do filtering in some other particular way say some new combination of AND and OR of some fields.

Thankfully, there are solutions already available for both of the above problems. People, well versed with GraphQL, would be knowing that first problem is solved by it i.e. client of REST API can tell us the fields that it require in the request itself and same API will output different set of fields depending upon input. For second problem too, there are solutions available like RSQL and spring-boot-rest-api-helpers.

Although the solutions do exist for both the problems but if we go for first solution, we have to compromise on the second problem and vice versa. There is no combined solution available. My Aim was to somehow combine the functionality of both into one so that once I define a REST API on a resource, I don't need to make changes in it again due to new requirements coming up in any later stage of project.

Usage

Just we like we normally define schema and query for graphql, we will define them. The only difference would be we would be taking 3 strings of filter, range and sort as input in Query.

type Query {
    userList(filter: String, range: String, sort: String): [User!]!
    userCount(filter: String): Int!
}

type User {
    id: ID!
    name: String!
    userAddressList: [UserAddress!]!
}

type UserAddress {
    id: ID!
    userId: Int!
    address: String!
    user: User!
}

Now, we will define the functions, corresponding to the GraphQL query, in the following way:

@Component
public class GraphQLQueryService implements GraphQLQueryResolver {
    @Inject
    private FilterService<User, Integer> userFilterService;

    public List<User> getUserList(String filter, String range, String sort) {
        QueryParamWrapper queryParamWrapper = Utils.extractQueryParams(filter, range, sort);
        Page<User> pages = userFilterService.filterBy(queryParamWrapper, User.class);
        return pages.getContent();
    }

    public long getUserCount(String filter) {
        QueryParamWrapper queryParamWrapper = Utils.extractQueryParams(filter, null, null);
        return userFilterService.countBy(queryParamWrapper);
    }
}

So, some sample format of GraphQL queries would be like following:

{
  userList(filter: "{id: 2}", range: "[0, 100]", sort: "[name, DESC]") { # Fetch user with id = 2
    name
    userAddressList {
      id
      address
    }
  }
}

{
  userList(filter: "[{id: 2}, {name: 'Jaskaran Singh'}]") { # Fetch user with id = 2 or name = 'Jaskaran Singh'
    name
    userAddressList {
      id
      address
    }
  }
}

{
  userList(filter: "[{id: 2}, {name: 'Jaskaran Singh'}]") { # Fetch users with id = 2 or name = 'Jaskaran Singh'
    name
    userAddressList {
      id
      address
    }
  }
}

{
  userList(filter: "{userAddressList: {address: 'Address 1'}}") { # Fetch users with address = 'Address 1'
    name
    userAddressList {
      id
      address
    }
  }
}

Please note in the last example that we are able to query on the sub-resource too.

Credits

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages