Home > Mobile >  Code duplication in API design for URL route functions vs. real world object methods
Code duplication in API design for URL route functions vs. real world object methods

Time:05-27

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" 

    
    
  • Related