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

Fixes route overloading for dynamic routes #360

Conversation

seemethere
Copy link
Member

Overview

Addresses #353, now dynamic routes work alongside our newly minted
overloaded routes! Also fixed an unintended side effect where methods
were still being passed in as None for Sanic.add_route.

I'll add in some tests so this shouldn't be merged until I add this in.

Addresses sanic-org#353, now dynamic routes work alongside our newly minted
overloaded routes! Also fixed an unintended side effect where methods
were still being passed in as None for `Sanic.add_route`.
@seemethere seemethere modified the milestone: 0.3.1 Jan 28, 2017
@seemethere
Copy link
Member Author

Actually, this doesn't fully work with HTTPMethodView, due to the way it gets added. Maybe it would be better to just have an add_view function that dynamically gets what methods the view is allowed for? What do you think @AntonDnepr?

@seemethere
Copy link
Member Author

Actually have a fix for HTTPMethodView, but it isn't ideal. Also for some reason calls to HEAD method endpoints don't work for me locally. 🤔

@r0fls
Copy link
Contributor

r0fls commented Jan 28, 2017

@seemethere how're you testing the HEAD method? This works for me:

from sanic import Sanic
from sanic.response import text

app = Sanic()

@app.head("/")
async def test(request):
    return text("OK")

app.run()
$ curl --head localhost:8000
00
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 2
Connection: keep-alive
Keep-Alive: timeout=60

@seemethere
Copy link
Member Author

@r0fls I figured it out, the HEAD method doesn't return a body so trying to verify the body would be useless. Instead I just switched the test to verify the headers!

@seemethere seemethere requested a review from r0fls January 28, 2017 04:18
Copy link
Contributor

@r0fls r0fls left a comment

Choose a reason for hiding this comment

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

Can we incorporate the unit test from #353? Does this pass that?

@r0fls
Copy link
Contributor

r0fls commented Jan 28, 2017

I vote we add this test case, or some variant, which passes:

from sanic import Sanic
from sanic.response import text
from sanic.utils import sanic_endpoint_test
from sanic.router import RouteExists
import pytest

@pytest.mark.parametrize("method,attr, expected", [
        ("get", "text", "OK1 test"),
        ("post", "text", "OK2 test"),
        ("put", "text", "OK2 test"),
        ("delete", "status", 405),
])
def test_overload_dynamic_routes(method, attr, expected):
    app = Sanic('test_dynamic_route')

    @app.route('/overload/<param>', methods=['GET'])
    async def handler1(request, param):
        return text('OK1 ' + param)

    @app.route('/overload/<param>', methods=['POST', 'PUT'])
    async def handler2(request, param):
        return text('OK2 ' + param)


    request, response = sanic_endpoint_test(app,
                                            method,
                                            uri='/overload/test')
    assert getattr(response, attr) == expected

Then open an issue when we close the other one, and include this test case:

def test_overload_dynamic_routes_exist():
    app = Sanic('test_dynamic_route')

    @app.route('/overload/<param>', methods=['GET'])
    async def handler1(request, param):
        return text('OK1 ' + param)

    @app.route('/overload/<param>', methods=['POST', 'PUT'])
    async def handler2(request, param):
        return text('OK2 ' + param)


    # if this doesn't raise an error, than at least the below should happen:
    # assert response.text == 'Duplicated' 
    with pytest.raises(RouteExists):
        @app.route('/overload', methods=['PUT', 'DELETE'])
        async def handler3(request):
            return text('Duplicated')

    request, response = sanic_endpoint_test(app,
                                            'PUT',
                                            uri='/overload/test')
    assert response.text == 'Duplicated'

Unless we can get this to pass this second test before we merge. It should either raise an error or update the existing PUT handler.

@youknowone
Copy link
Contributor

Thanks for a nice fix. Now I learned I tried a stupid way than an easy way.

About routing handlers, I suggest:

  • class-based view can be a default view handler
  • Add common method handler getter to both HTTPMethodView and CompositionView
  • Add a wrapper or attribute to function handlers

Then they will share same interface as router's point of view.

About the get-handler overhead, I think Router._get can cache them with uri+method input to specific handler function output.

@seemethere
Copy link
Member Author

@youknowone I think we can simplify the views portion as well as the adding routes portion, for this PR though I think it's good to focus on the hot-fix for dynamic route overloading.

@youknowone
Copy link
Contributor

I also definitely agree about this PR. sorry for making confusion.

@seemethere
Copy link
Member Author

@r0fls I'll add those test cases tomorrow and then push up 0.3.1. Don't merge until I push up the test cases.

This is by no means the final solution but it's a start in the right
direction. Eventually what needs to happen is we need to reduce the
complexity of the routing. CompsitionView can probably be removed later
on in favor of better Route objects. Also in the next version of sanic
we need to move merge_route and add_parameter out of the add_route logic
and just have them as standalone methods.

The tests should cover everything that we need so that if any changes
are made we can identify regression.
@seemethere
Copy link
Member Author

Test cases have been put in, will merge and roll into 0.3.1 later today.

@seemethere seemethere merged commit a547798 into sanic-org:master Jan 29, 2017
@seemethere seemethere deleted the fix_route_overloading_for_dynamic_routes branch January 29, 2017 21:35
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.

None yet

3 participants