Data filtering in Dropwizard using DAOs based on optional parameters












0















I want to implement filtering of data in my Dropwizard server. Let us say we want to search for Monuments. The user could use filters like name, city, category for filtering from the list of monuments.



The uri will look something like /monuments?name="Eiffel"&city"Paris"&category="Engineering Marvel"



I am not clear on how to implement the API for this because some users may stop after just specifying the name filter, while others may use all 3.



In such a case how do I implement the Java code and Queries in my DAO to modify the query based on what filters were passed on?



What I thought of and tried :



1 (worst case) - Have a list of all possible combinations of queries for these filters and use one depending on which combination of arguments was passed on.



2 - I thought the JDBI would automatically eliminate the params that are null when calling the DAO method, but that isn't the case, at least with the ilike clause (since all the above params are strings).



3 - Use Case in Postgres. But this is not scale-able since I might have other params to search with over time as the use cases increase.



4 - Use Java data structures along with DAOs to filter down the results internally like get all the monuments based on (let's say) name first, then pass the Ids to an SQL Query with city clause and then same with category clause. But this will take a long time to process as data increases.



This seems like a fairly common scenario but I can't find any good answers around this, Most talk about the URI and RESTful design instead of the implementation details.



Any guidance would be of help.



Thanks










share|improve this question

























  • Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.

    – Hitobat
    Nov 25 '18 at 10:45













  • How do I write an SQL query to ignore null values?

    – LeoNeo
    Nov 27 '18 at 15:19











  • I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query like Select * from users where name = :name and if the passed in arg is null then just do `Select * from users.

    – LeoNeo
    Nov 27 '18 at 15:30











  • You can do something like SELECT * FROM users WHERE (:name IS NULL OR name=:name).

    – Hitobat
    Nov 30 '18 at 13:19
















0















I want to implement filtering of data in my Dropwizard server. Let us say we want to search for Monuments. The user could use filters like name, city, category for filtering from the list of monuments.



The uri will look something like /monuments?name="Eiffel"&city"Paris"&category="Engineering Marvel"



I am not clear on how to implement the API for this because some users may stop after just specifying the name filter, while others may use all 3.



In such a case how do I implement the Java code and Queries in my DAO to modify the query based on what filters were passed on?



What I thought of and tried :



1 (worst case) - Have a list of all possible combinations of queries for these filters and use one depending on which combination of arguments was passed on.



2 - I thought the JDBI would automatically eliminate the params that are null when calling the DAO method, but that isn't the case, at least with the ilike clause (since all the above params are strings).



3 - Use Case in Postgres. But this is not scale-able since I might have other params to search with over time as the use cases increase.



4 - Use Java data structures along with DAOs to filter down the results internally like get all the monuments based on (let's say) name first, then pass the Ids to an SQL Query with city clause and then same with category clause. But this will take a long time to process as data increases.



This seems like a fairly common scenario but I can't find any good answers around this, Most talk about the URI and RESTful design instead of the implementation details.



Any guidance would be of help.



Thanks










share|improve this question

























  • Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.

    – Hitobat
    Nov 25 '18 at 10:45













  • How do I write an SQL query to ignore null values?

    – LeoNeo
    Nov 27 '18 at 15:19











  • I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query like Select * from users where name = :name and if the passed in arg is null then just do `Select * from users.

    – LeoNeo
    Nov 27 '18 at 15:30











  • You can do something like SELECT * FROM users WHERE (:name IS NULL OR name=:name).

    – Hitobat
    Nov 30 '18 at 13:19














0












0








0








I want to implement filtering of data in my Dropwizard server. Let us say we want to search for Monuments. The user could use filters like name, city, category for filtering from the list of monuments.



The uri will look something like /monuments?name="Eiffel"&city"Paris"&category="Engineering Marvel"



I am not clear on how to implement the API for this because some users may stop after just specifying the name filter, while others may use all 3.



In such a case how do I implement the Java code and Queries in my DAO to modify the query based on what filters were passed on?



What I thought of and tried :



1 (worst case) - Have a list of all possible combinations of queries for these filters and use one depending on which combination of arguments was passed on.



2 - I thought the JDBI would automatically eliminate the params that are null when calling the DAO method, but that isn't the case, at least with the ilike clause (since all the above params are strings).



3 - Use Case in Postgres. But this is not scale-able since I might have other params to search with over time as the use cases increase.



4 - Use Java data structures along with DAOs to filter down the results internally like get all the monuments based on (let's say) name first, then pass the Ids to an SQL Query with city clause and then same with category clause. But this will take a long time to process as data increases.



This seems like a fairly common scenario but I can't find any good answers around this, Most talk about the URI and RESTful design instead of the implementation details.



Any guidance would be of help.



Thanks










share|improve this question
















I want to implement filtering of data in my Dropwizard server. Let us say we want to search for Monuments. The user could use filters like name, city, category for filtering from the list of monuments.



The uri will look something like /monuments?name="Eiffel"&city"Paris"&category="Engineering Marvel"



I am not clear on how to implement the API for this because some users may stop after just specifying the name filter, while others may use all 3.



In such a case how do I implement the Java code and Queries in my DAO to modify the query based on what filters were passed on?



What I thought of and tried :



1 (worst case) - Have a list of all possible combinations of queries for these filters and use one depending on which combination of arguments was passed on.



2 - I thought the JDBI would automatically eliminate the params that are null when calling the DAO method, but that isn't the case, at least with the ilike clause (since all the above params are strings).



3 - Use Case in Postgres. But this is not scale-able since I might have other params to search with over time as the use cases increase.



4 - Use Java data structures along with DAOs to filter down the results internally like get all the monuments based on (let's say) name first, then pass the Ids to an SQL Query with city clause and then same with category clause. But this will take a long time to process as data increases.



This seems like a fairly common scenario but I can't find any good answers around this, Most talk about the URI and RESTful design instead of the implementation details.



Any guidance would be of help.



Thanks







java filtering dropwizard jdbi






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited yesterday









Rishab178

11517




11517










asked Nov 25 '18 at 7:11









LeoNeoLeoNeo

472518




472518













  • Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.

    – Hitobat
    Nov 25 '18 at 10:45













  • How do I write an SQL query to ignore null values?

    – LeoNeo
    Nov 27 '18 at 15:19











  • I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query like Select * from users where name = :name and if the passed in arg is null then just do `Select * from users.

    – LeoNeo
    Nov 27 '18 at 15:30











  • You can do something like SELECT * FROM users WHERE (:name IS NULL OR name=:name).

    – Hitobat
    Nov 30 '18 at 13:19



















  • Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.

    – Hitobat
    Nov 25 '18 at 10:45













  • How do I write an SQL query to ignore null values?

    – LeoNeo
    Nov 27 '18 at 15:19











  • I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query like Select * from users where name = :name and if the passed in arg is null then just do `Select * from users.

    – LeoNeo
    Nov 27 '18 at 15:30











  • You can do something like SELECT * FROM users WHERE (:name IS NULL OR name=:name).

    – Hitobat
    Nov 30 '18 at 13:19

















Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.

– Hitobat
Nov 25 '18 at 10:45







Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.

– Hitobat
Nov 25 '18 at 10:45















How do I write an SQL query to ignore null values?

– LeoNeo
Nov 27 '18 at 15:19





How do I write an SQL query to ignore null values?

– LeoNeo
Nov 27 '18 at 15:19













I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query like Select * from users where name = :name and if the passed in arg is null then just do `Select * from users.

– LeoNeo
Nov 27 '18 at 15:30





I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query like Select * from users where name = :name and if the passed in arg is null then just do `Select * from users.

– LeoNeo
Nov 27 '18 at 15:30













You can do something like SELECT * FROM users WHERE (:name IS NULL OR name=:name).

– Hitobat
Nov 30 '18 at 13:19





You can do something like SELECT * FROM users WHERE (:name IS NULL OR name=:name).

– Hitobat
Nov 30 '18 at 13:19












1 Answer
1






active

oldest

votes


















0














While the answer suggested by @Hitobat would work fine when your optional arguments are few, but if you are dealing with a lot of optional arguments a more elegant solution would be to consider creating a request pojo and use Hibernate Criterias where you add a restriction only if the argument is not null.



Request class:



public class FilteredRequest{
String name;
String city;
String category;
}


Resource Class:



@GET
@Path("/monuments")
public Response searchMonuments(@ApiParam("filters") FilteredRequest filteredRequest){
return Response.ok().entity(monumentsDAO.findAll(filteredRequest)).build()
}


DAO:



public List<Monuments> class MonumentsDAO() {
public findAll(FilteredRequest filteredRequest){
Criteria criteria = getSearchCriteria(filteredRequest);
return list(criteria);
}

private Criteria getSearchCriteria(FilteredRequest filteredRequest){
Criteria criteria = criteria();
if (StringUtils.isNotEmpty(filteredRequest.getName())) {
criteria.add(Restrictions.eq("name", filteredRequest.getName()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCity())) {
criteria.add(Restrictions.eq("city", filteredRequest.getCity()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCategory())) {
criteria.add(Restrictions.eq("category", filteredRequest.getCategory()));
}
return criteria;
}
}





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53465419%2fdata-filtering-in-dropwizard-using-daos-based-on-optional-parameters%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    While the answer suggested by @Hitobat would work fine when your optional arguments are few, but if you are dealing with a lot of optional arguments a more elegant solution would be to consider creating a request pojo and use Hibernate Criterias where you add a restriction only if the argument is not null.



    Request class:



    public class FilteredRequest{
    String name;
    String city;
    String category;
    }


    Resource Class:



    @GET
    @Path("/monuments")
    public Response searchMonuments(@ApiParam("filters") FilteredRequest filteredRequest){
    return Response.ok().entity(monumentsDAO.findAll(filteredRequest)).build()
    }


    DAO:



    public List<Monuments> class MonumentsDAO() {
    public findAll(FilteredRequest filteredRequest){
    Criteria criteria = getSearchCriteria(filteredRequest);
    return list(criteria);
    }

    private Criteria getSearchCriteria(FilteredRequest filteredRequest){
    Criteria criteria = criteria();
    if (StringUtils.isNotEmpty(filteredRequest.getName())) {
    criteria.add(Restrictions.eq("name", filteredRequest.getName()));
    }
    if (StringUtils.isNotEmpty(filteredRequest.getCity())) {
    criteria.add(Restrictions.eq("city", filteredRequest.getCity()));
    }
    if (StringUtils.isNotEmpty(filteredRequest.getCategory())) {
    criteria.add(Restrictions.eq("category", filteredRequest.getCategory()));
    }
    return criteria;
    }
    }





    share|improve this answer




























      0














      While the answer suggested by @Hitobat would work fine when your optional arguments are few, but if you are dealing with a lot of optional arguments a more elegant solution would be to consider creating a request pojo and use Hibernate Criterias where you add a restriction only if the argument is not null.



      Request class:



      public class FilteredRequest{
      String name;
      String city;
      String category;
      }


      Resource Class:



      @GET
      @Path("/monuments")
      public Response searchMonuments(@ApiParam("filters") FilteredRequest filteredRequest){
      return Response.ok().entity(monumentsDAO.findAll(filteredRequest)).build()
      }


      DAO:



      public List<Monuments> class MonumentsDAO() {
      public findAll(FilteredRequest filteredRequest){
      Criteria criteria = getSearchCriteria(filteredRequest);
      return list(criteria);
      }

      private Criteria getSearchCriteria(FilteredRequest filteredRequest){
      Criteria criteria = criteria();
      if (StringUtils.isNotEmpty(filteredRequest.getName())) {
      criteria.add(Restrictions.eq("name", filteredRequest.getName()));
      }
      if (StringUtils.isNotEmpty(filteredRequest.getCity())) {
      criteria.add(Restrictions.eq("city", filteredRequest.getCity()));
      }
      if (StringUtils.isNotEmpty(filteredRequest.getCategory())) {
      criteria.add(Restrictions.eq("category", filteredRequest.getCategory()));
      }
      return criteria;
      }
      }





      share|improve this answer


























        0












        0








        0







        While the answer suggested by @Hitobat would work fine when your optional arguments are few, but if you are dealing with a lot of optional arguments a more elegant solution would be to consider creating a request pojo and use Hibernate Criterias where you add a restriction only if the argument is not null.



        Request class:



        public class FilteredRequest{
        String name;
        String city;
        String category;
        }


        Resource Class:



        @GET
        @Path("/monuments")
        public Response searchMonuments(@ApiParam("filters") FilteredRequest filteredRequest){
        return Response.ok().entity(monumentsDAO.findAll(filteredRequest)).build()
        }


        DAO:



        public List<Monuments> class MonumentsDAO() {
        public findAll(FilteredRequest filteredRequest){
        Criteria criteria = getSearchCriteria(filteredRequest);
        return list(criteria);
        }

        private Criteria getSearchCriteria(FilteredRequest filteredRequest){
        Criteria criteria = criteria();
        if (StringUtils.isNotEmpty(filteredRequest.getName())) {
        criteria.add(Restrictions.eq("name", filteredRequest.getName()));
        }
        if (StringUtils.isNotEmpty(filteredRequest.getCity())) {
        criteria.add(Restrictions.eq("city", filteredRequest.getCity()));
        }
        if (StringUtils.isNotEmpty(filteredRequest.getCategory())) {
        criteria.add(Restrictions.eq("category", filteredRequest.getCategory()));
        }
        return criteria;
        }
        }





        share|improve this answer













        While the answer suggested by @Hitobat would work fine when your optional arguments are few, but if you are dealing with a lot of optional arguments a more elegant solution would be to consider creating a request pojo and use Hibernate Criterias where you add a restriction only if the argument is not null.



        Request class:



        public class FilteredRequest{
        String name;
        String city;
        String category;
        }


        Resource Class:



        @GET
        @Path("/monuments")
        public Response searchMonuments(@ApiParam("filters") FilteredRequest filteredRequest){
        return Response.ok().entity(monumentsDAO.findAll(filteredRequest)).build()
        }


        DAO:



        public List<Monuments> class MonumentsDAO() {
        public findAll(FilteredRequest filteredRequest){
        Criteria criteria = getSearchCriteria(filteredRequest);
        return list(criteria);
        }

        private Criteria getSearchCriteria(FilteredRequest filteredRequest){
        Criteria criteria = criteria();
        if (StringUtils.isNotEmpty(filteredRequest.getName())) {
        criteria.add(Restrictions.eq("name", filteredRequest.getName()));
        }
        if (StringUtils.isNotEmpty(filteredRequest.getCity())) {
        criteria.add(Restrictions.eq("city", filteredRequest.getCity()));
        }
        if (StringUtils.isNotEmpty(filteredRequest.getCategory())) {
        criteria.add(Restrictions.eq("category", filteredRequest.getCategory()));
        }
        return criteria;
        }
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered yesterday









        Rishab178Rishab178

        11517




        11517






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53465419%2fdata-filtering-in-dropwizard-using-daos-based-on-optional-parameters%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)