I want to use one resource with two endpoints. The first one uses GET to fetch an object with a given id. The second one is used by POST when calling a function on an object with a given ID.
On Windows, this works:
api.add_resource(Shipment, '/shipments/<int:id>')
api.add_resource(Shipment, '/shipments/<int:id>/<string:action>')
But on Linux, it doesn't and results in an error:
File "/flask/lib/python2.7/site-packages/flask/app.py", line 984, in add_url_rule
'existing endpoint function: %s' % endpoint)
AssertionError: View function mapping is overwriting an existing endpoint function: shipment
Here I can solve it by using both paths in one add_resource:
api.add_resource(Shipment, '/shipments/<int:id>', '/shipments/<int:id>/<string:action>')
This also works on Windows.
Looking at the docs I believe the latter is the 'official' way of doing this, though I like the Windows way where every add_resource call seems to add to the list of enabled URLs.
Shouldn't this behaviour at least be consistend accross platforms?
And (maybe this should be a separate issue?), wouldn't it be better if the list of given URLs would be either ONE URL as a regular string, of MULTIPLE URLs given as a list, instead of a series of strings?
I don't think this has anything to do with Windows vs. Linux. Please check your version of Flask on both systems. Flask 0.9 did not have a check for adding a route to the same view function multiple times, whereas 0.10 and after will throw that exception you are seeing.
Regarding your other question, such a change would not be backwards compatible and I'd rather not break it. Could you elaborate why you think passing a list instead would be more correct? Both ways feel approximately equivalent to me. If you feel more comfortable using a list instead, you could do this:
routes = [
'/shipments/<int:id>',
'/shipments/<int:id>/<string:action>',
]
api.add_resource(Shipment, *routes)
My computer is the Linux one while a friend is running it on Windows; when he changed this code I started to see the error. I'm indeed running 0.10.1, so I think he might be running 0.9 (asked him bit didn't get a response yet).
Concerning the list; most of the times you define and call functions like this:
def myFunction(arg1, arg2, arg3):
print arg1 # "first"
print arg2 # 2
print arg3 # 3
myFunction("first", 2, 3)
You call the function with as many arguments as you used when defining the function. So for me, when I use multiple arguments separated with comma's (the routes), it feels like I'm sending multiple arguments, instead of sending a single argument that happens to be a list.
If we change the function above to behave like add_resource, it would look something like this (pseudo-code):
def myFunction(arg1, arg2, arg3="some default):
print arg1 # "first"
print arg2 # 2, or [2, 3]?
print arg3 # 3, or "some default"?
myFunction("first", 2, 3)
It's not clear anymore what's happening just from looking at the function call myFunction("first, 2, 3) Technically it doesn't work like this of course, but I hope you can see what I mean.
But, I guess in the end it's just be a matter of preference.
Most helpful comment
I don't think this has anything to do with Windows vs. Linux. Please check your version of Flask on both systems. Flask 0.9 did not have a check for adding a route to the same view function multiple times, whereas 0.10 and after will throw that exception you are seeing.
Regarding your other question, such a change would not be backwards compatible and I'd rather not break it. Could you elaborate why you think passing a list instead would be more correct? Both ways feel approximately equivalent to me. If you feel more comfortable using a list instead, you could do this: