Python – Designing a RESTful API for a file manager

designfile handlingpythonrestweb services

I am building a file manager web UI (front end ReactJS, back end Flask). RESTful API seems to be very suitable in this situation at first sight, but I get into trouble.

I need API contain:

  • List Operation: get all path info under a folder(path), like ls command
  • Delete Operation: delete path
  • Rename Operation: rename path
  • Change permission Operation: change path permission
  • Move Operation: move path to another path
  • Copy Operation: copy path to another path

"Rename" and "change permission" can be included in a modify Operation.

Needless:

  • getPathInfo Operation: get path info (permission, is a folder or not, something else), because the list Operation gets the info and sets to each child, so no need to query a single path.

At first, I thought a path is easy to change into a restful API, but there are some problems now.

I use node to point path:

api = Blueprint('api', __name__, url_prefix='/api')
api_wrap = Api(api)

@api_wrap.resource('/nodelist/<path:path>')
class NodeList(Resource):
    def get(self, path='.'):
        return filemgr.list(path)


@api_wrap.resource('/node/<path:path>')
class Node(Resource):
    def get(self, path):
        return ''

    def delete(self, path):
        if not path:
            return 403
        return filemgr.delete(path)

    def post(self, path):
        deserialized = NodeSerializer().deserialize(json.loads(request.data))
        return filemgr.create(path, deserialized)

    def put(self, path):
        deserialized = NodeSerializer().deserialize(json.loads(request.data))
        return filemgr.modify(path, deserialized)

The resource is node, but where do I place move and copy? What is the correct way to write move and copy Operation? Create another resource? It sounds weird, and common JSON API is clearer:

@api.route('/move', methods=['POST'])
def move():
    data = json.loads(request.data)
    ret = filemgr.move(data['src'], data['dst'])
    return jsonify(ret)

Actually, I am confusing as to whether or not I can use RESTful in my project.

Set a rename Operation is clearer than RESTful put too:

@api.route('/rename', methods=['POST'])
def rename():
    data = json.loads(request.data)
    ret = filemgr.rename(data['path'], data['name'])
    return jsonify(ret)

I wonder what is the correct way to design RESTful API for the file manager:

  1. Completely RESTful; how can it be named?
  2. Half RESTful, mixin common JSON API; is it good to mix RESTful API with others?
  3. Don't use RESTful here, and why?

Best Answer

Don't get too caught up with the way things are usually done, an API can be restful without having to have resource identifier specified in the URL. In your case I would say its perfectly acceptable to place the path(s) in the POST body.