hapifhir / hapi-fhir

🔥 HAPI FHIR - Java API for HL7 FHIR Clients and Servers
http://hapifhir.io
Apache License 2.0
2.04k stars 1.33k forks source link

Challenges with _count and total in HAPI #1585

Open keithboone opened 5 years ago

keithboone commented 5 years ago

Keith Boone: I'm working on pagination in my server (not using PaginationProvider), returning a Bundle. It appears that HAPI is rewriting the bundle I return and changing the value of Total to -1 (one of my test cases is for _count=-1, which seems to be related). I suspect I need to return an IBundleProvider or something, but thought I would mention the weird behavior.

Keith Boone: Issue appears to be in BaseMethodBinding.toResourceList() method.

Keith Boone: Tracked it back to BaseResourceReturningMethodBinding. doInvokeServer(IRestfulServer<?> theServer, RequestDetails theRequest) where: Integer count = RestfulServerUtils.extractCountParameter(theRequest); ... And then: bundleFactory.addRootPropertiesToBundle(null, theRequest.getFhirServerBase(), linkSelf, null, null, count, getResponseBundleType(), lastUpdated);

BUT: count is clearly not theTotalResults, and in fact, there's really no way to know what that value SHOULD be based on the response unless Bundle.total is populated.

I'll log a bug for this, and see what I can do to work around it.

To Reproduce Steps to reproduce the behavior: Create a ResourceProvider that returns a Bundle that does not populate total, and supports _count, and pass in a _count value to the query.

The _count value is used for the Bundle.total (even though that's not right).

Expected behavior Total should be not be altered from what was returned.

Environment (please complete the following information):

Additional context See https://chat.fhir.org/#narrow/stream/179167-hapi/topic/Challenges.20with.20_count.20and.20total.20in.20HAPI

Total should not be overwritten, even when not present. The HAPI Server has NO clue what the right value should be, and cannot know.

keithboone commented 5 years ago

Workaround follows:

  1. Add RequestDetails theDetails to your query method if not already present.
  2. Add this before you return the bundle. It removes _count from theDetails so it won't be changed if there is no total, or sets it to the actual total.

    // This is a hack to work around https://github.com/jamesagnew/hapi-fhir/issues/1585
    // We remove the _count parameter from theDetails so that total is not modified.
    Map<String, String[]> params = new HashMap<String, String[]>(theDetails.getParameters());
    Integer total = bundle.hasTotal() ? null : bundle.getTotal();
    if (params.remove(Constants.PARAM_COUNT) != null || total != null) {
        if (total != null) {
            params.put(Constants.PARAM_COUNT, new String[] { total.toString() });
        }
        // Remove _count parameter from the current request details
        theDetails.setParameters(params);
    }
    
    return bundle;
RickHawesUSDS commented 4 years ago

Thanks for this issue report. I ran into the same bug where the HAPI server code was adding a total (an incorrect one at that) when my Bundle didn't have one before. This report helped me work-around the issue.