Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DR-3313: Add POST endpoint for retrieving data in order to enable larger filter queries in UI #1535

Merged
merged 20 commits into from
Nov 27, 2023

Conversation

snf2ye
Copy link
Contributor

@snf2ye snf2ye commented Nov 7, 2023

Background

We have endpoints that enable retrieving and filtering on tabular data for a given dataset or snapshot. Before this change, these endpoints were GET endpoints, so there was a smaller limit to how big the filter statement could be. By switch these requests to be POST requests, we can support much larger filter statements.

The Changes

Mark existing GET endpoints as deprecated and "hidden" in swagger:

  • lookupDatasetDataById
  • lookupDatasetColumnStatisticsById
  • lookupSnapshotPreviewById
    Create new endpoints with slightly new names to more accurately described how they are used:
  • queryDatasetDataById
  • queryDatasetColumnStatisticsById
  • querySnapshotDataById

Testing

Changes were manually tested in the UI. More details in the UI PR description- DataBiosphere/jade-data-repo-ui#1540

Changes for both the UI and API are deployed to my dev instance: https://jade-sh.datarepo-dev.broadinstitute.org/

@snf2ye snf2ye force-pushed the sh-dr-3313-post branch 2 times, most recently from 724585e to 877b2fe Compare November 13, 2023 15:55
@snf2ye snf2ye marked this pull request as ready for review November 14, 2023 03:06
verifyDatasetAuthorization(userReq, id.toString(), IamAction.READ_DATA);
// TODO: Remove after https://broadworkbench.atlassian.net/browse/DR-2588 is fixed
SqlSortDirection sortDirection =
Objects.requireNonNullElse(queryDataRequest.getDirection(), SqlSortDirection.ASC);
Copy link
Contributor

@samanehsan samanehsan Nov 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this is still a problem now that this is not a query parameter 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great question - After testing this, it appears that it is still needed. If the user doesn't include direction in their request, then it will be null.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've realized that there are some issues with how we're setting our default values. I'm going to have a follow-on PR to address this: #1541

@Override
public ResponseEntity<SnapshotPreviewModel> querySnapshotDataById(
UUID id, String table, QueryDataRequestModel queryDataRequest) {
logger.debug("Verifying user access");
Copy link
Contributor

@samanehsan samanehsan Nov 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a leftover from testing! (same with line 275)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll clean these up!

Copy link
Contributor

@okotsopoulos okotsopoulos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good! I had a few small questions / suggestions.

Is there a plan or ticket for full removal of the deprecated endpoints? I know we theorize that TDR UI is the only programmatic caller.

return ResponseEntity.ok(previewModel);
}

@Hidden
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth it to change our @Hidden endpoints to redirect to their replacements? I'm not wording this super clearly, but something like this:

@Hidden
@Override
  public ResponseEntity<DatasetDataModel> lookupDatasetDataById(
      UUID id,
      String table,
      Integer offset,
      Integer limit,
      String sort,
      SqlSortDirection direction,
      String filter) {
      var queryDataRequest = <construct this from the raw inputs>;
      return queryDatasetDataById(id, table, queryDataRequest);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely a reasonable path forward - I've gone back and forth here.
My main hesitancy here is that I have switched all of our tests to use the post endpoint. I think it's reasonable to move our testing to the new endpoints since we're marking these old endpoints as deprecated. But, this also means that I feel less confident in making changes to these methods since we don't have the automated testing on it.
What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closing the loop after discussing in stand-up -- we agreed that maintaining unit test coverage of both old and new endpoints via parameterized tests would be good enough assurance, and we can leave integration / connected tests to use the new endpoints!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@okotsopoulos - Thanks! I think using the method source parameterized tests were a great idea. I've made this change and I've changed the lookup endpoints to reference the new query code in the controller.

- snapshots
- search
- repository
description: Retrieve data for a table in a snapshot.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just wondering why the new APIs are post methods. It seems their functions and descriptions state they retrieve.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an awesome question. There's a common misconception that POST is an operation that modifies state but it's really more of a catchall HTTP verb. For operations that fetch those can be GET or POST but the problem with GET (well, one of the problems with GET) is that it doesn't really allow for a request body (I mean you can, but a lot of clients flat out disallow it) because it's meant to just pass in all it needs in the URL (e.g. using path or query parameters). Some of the problems with that are that

  • URLs are limited in length and so you very quickly run into issues of max request length
  • It's super gross to model complex queries in URL parameters and much much easier in JSON bodies

So the idea here is moving the data fetch to a POST request so that we can pass in the full query parameters.

I'll note that this is a direction that a lot of even low level web REST APIs have moved to (e.g. Elasticsearch)

Hopefully this isn't too much of a novel :). This is a great topic for our Thursday design sessions!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah that makes sense thank you!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rjohanek if you're interested, we took on this work in response to a specific user pain point with the old endpoints, in case you'd like to see a concrete example of how this played out! https://broadinstitute.slack.com/archives/CD4HBRFMG/p1698249337991919

Copy link
Contributor

@nmalfroy nmalfroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great!

@snf2ye snf2ye force-pushed the sh-dr-3313-post branch 2 times, most recently from 22be7dc to 9ab2114 Compare November 16, 2023 00:34
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 1 Code Smell

84.6% 84.6% Coverage
0.0% 0.0% Duplication

@snf2ye snf2ye merged commit 45159af into develop Nov 27, 2023
11 checks passed
@snf2ye snf2ye deleted the sh-dr-3313-post branch November 27, 2023 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants