I have code duplication in my API design for the object methods vs. the URL routing functions:
# door_model.py
class Door:
def open(self): # "Door.open" written once...
...
# http_api.py (the HTTP server is separated from the real-world object models)
@app.route('/api/door/open') # ... written twice
def dooropen(): # ... written three times
d.open() # ... written four times!
d = Door()
How to avoid this unnecessary duplication of names in a similar API design? (while keeping a separation between real-world object models vs. HTTP server).
Is there a general pattern to avoid unnecessary duplication of names when using an object model (with methods), and URL routes functions? (nearly a Model View Controller pattern)
See also Associate methods of an object to API URL routes with Python Flask.
CodePudding user response:
You can create dynamic routes. A dynamic route for your case would be api/door/<action>
.
Create a route like this to have a dynamic url:
@app.route('api/door/<action:str>')
def door(action):
door = Door()
if action in door.actions:
if action.lower() == 'open':
door.open()
r = 'oppened door'
return r
Create a class variable called actions to make the code work. For example like this actions = ['open','close']
CodePudding user response:
You can leverage the flask blueprint pattern
In your http_api.py
use
app = Flask(__name__)
# ... configs to app instance ...
app.register_blueprint(door_routes, url_prefix="/api/door")
In Your api/door.py
door_routes = Blueprint("door_routes", __name__)
door = Door()
@door_routes.route("/open")
def open():
d.open()
return
#other routes
Or alternatively, you can use:
class Door():
def open(self):
print("opened")
d = Door()
@app.route("/api/door/<action>", methods=["POST", "GET"])
def catch_all(action):
try:
function = getattr(d,action)
resp = function()
#return jsonify(resp),200 or the below line
return f"Executed {action}"
except Exception as e:
return f"URL {action} not found"