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

Handling next and previous pagination of results #352

Open
bdowling opened this issue Feb 19, 2018 · 4 comments
Open

Handling next and previous pagination of results #352

bdowling opened this issue Feb 19, 2018 · 4 comments

Comments

@bdowling
Copy link

I'm looking for an example of dealing with pagination in the case where the API provides a next/previous URL for you to follow.

It is not clear to me if there is a streamlined way of handling this in Bravado already, but I was attempting to craft a wrapper class that would handle this in my schema. If there is and someone can point me to the light I'd be happy to write some additional docs around this useful case.

I have done it initially for a single operation, but I am trying so see if there is an easy way to do this for all operations more generically.

Is there a way to pass back the URL and have it process it per the spec/model as defined? What I did in my test was parse out the params (cursor) in the URL and craft a new operation request, but it feels like there should be a simpler shortcut here.

I'm sure this has been encountered, so any input you can provide would be helpful.

The latest 3.0 OpenAPI specs try to address this with links, wondering if a x-links feature may make this suit the generic case (where other URLs to other Models in the API also are returned).

@bdowling
Copy link
Author

bdowling commented Mar 1, 2018

Thoughts on this?

@bdowling
Copy link
Author

bdowling commented Apr 2, 2018

@macisamuele @sjaensch have any input on this? Seems like a common need, lots of APIs are designed to return URL refs back into the API, next/prev is just another case of that. How can one generically map those URLs back into the bravado client so you can fetch the model they point to? There is a convert_path_to_resource method, but this doesn't go deeper into the operation or path parameters embedded in the URL.

This seems common enough that their could be generic support for handling this?

@bdowling
Copy link
Author

bdowling commented Apr 6, 2018

I came up with this, feels like I'm doing something that there should already be an easier way to do. Ideally I was thinking that with the format: url and x-operationId: some_op that I added into my schema, I could return back a custom type for the URLs in the response that could have a next.fetch() function. Looks like currently unmarshall_schema_object isn't passed enough info though to re-implement what I did here in that context.

    def fetch_op_from_url(self, data, key, req, res):
        # lookup the last op response_spec
        # check the content_spec for x-operationId on key
        # call the model_op on the url
        url = data[key]
        op = req.operation
        response_spec = get_response_spec(status_code=res.status_code, op=op)
        content_spec = op.swagger_spec.deref(response_spec['schema'])

        model_op_id = content_spec['properties'][key].get('x-operationId', op.operation_id)
        if model_op_id == op.operation_id:
            # short circuit, common for next/prev links, etc
            model_op = op
        else:
            # Find it on another resource, surprised there is no single dict
            # for operationId since it is required to be unique across spec
            for resource in self.swagger_spec.resources.values():
                model_op = resource.operations.get(model_op_id)
                if model_op:
                    break

        http_client = op.swagger_spec.http_client
        return http_client.request({'method': 'GET', 'url': url},
                                   operation=model_op,
                                   also_return_response=True)

@sjaensch
Copy link
Contributor

sjaensch commented Apr 6, 2018

@bdowling I guess the main reason there isn't a single dict to look up operation IDs is that up to this point bravado doesn't need it. :)
This could be an interesting feature, and if it doesn't cause too many issues in terms of code architecture, I could see bravado adopting this feature from OpenAPI 3.0. Pull requests always welcome. ;)

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

No branches or pull requests

2 participants