[API] Introducing files upload #918

Closed
batopa opened this Issue Jul 18, 2016 · 6 comments

Projects

None yet

2 participants

@batopa
Member
batopa commented Jul 18, 2016

Uploading files via REST API is missing. Any files uploaded should be linked to a multimedia (video, image, audio, ...) or a custom object type in a configurable way.

Upload flow

  1. A client makes a file upload request

    POST /files/:object_type/file_name.jpg
    Host: example.com
    Authorization: Bearer <access_token>
    Accept: application/json
    Content-Type: image/jpeg
    Content-Length: 284
    
    <raw image content>

    where object_type is the type of BEdita object linked to that file (for example image). In this way we can perform specific checks per object type before accept files. For example we may check some size/extension related to a specific type.
    Furthmore every object type could have a particular way to treat the file using local filesystem, Amazon S3, ...

  2. The server responds with some error if something goes wrong or with the relative path of file uploaded if it succeeded, for example

    {
       "api": "files",
       "data": {
           "file": "ab/cd/filename-on-filesystem.jpg"
       },
       "method": "post",
       "params": [],
       "url": "https://example.com/api/files/image/file_name.jpg"
    }
  3. the client proceeds creating the object type with file associated to it

    POST /objects
    Host: example.com
    Authorization: Bearer <access_token>
    Accept: application/json
    Content-Type: application/json
    
    {
      "data": {
          "object_type": "image",
          "title": "Image title",
          "uploaded_file: "ab/cd/filename-on-filesystem.jpg"
      }
    }
  4. If uploaded_file is not already linked to other object and the file is supported from the specified object_type the server will respond with a 201 Created with the object data as it happens now (http://bedita.readthedocs.io/en/v3.7.0/endpoints/objects.html#create-an-object).

@batopa batopa added this to the 3-updates milestone Jul 18, 2016
@batopa batopa self-assigned this Jul 18, 2016
@batopa batopa changed the title from [API] Introduce files upload to [API] Introducing files upload Jul 18, 2016
@stefanorosanelli
Member

Seems fine
As a security enhancement, to avoid orphan uploaded files we could use also a sort of hash_job between steps 2 and 3, for instance:

  1. in step 2, server reponds also with a hash an creates corresponding hash_job "multimedia object creation is pending"
  2. in step 3 we may use this hash to ensure a multimedia file association is pending and we may close the hash job after object creation
  3. with a cron shell script we may look for multimedia files not associated after upload and remove them, looking for timed out hash jobs of same type

This could be done after this issue or in BE4 only

@batopa
Member
batopa commented Jul 18, 2016 edited

@stefanorosanelli I agree, in that case the client could set a custom header to specify the hash operation instead of pass uploaded_file. The uploaded_file could be stay in hash_jobs.params
For example:

 POST /objects
 Host: example.com
 Authorization: Bearer <access_token>
 Accept: application/json
 Content-Type: application/json
 X-BEdita-Upload-Hash: 5a192d3f5716e9709df81974f5ee2aba
 X-BEdita-Upload-Command: associate

 {
    "data": {
        "object_type": "image",
        "title": "Image title"
    }
 }
@batopa
Member
batopa commented Jul 18, 2016

Or simply as query string

 POST /objects?upload_hash=5a192d3f5716e9709df81974f5ee2aba
 Host: example.com
 Authorization: Bearer <access_token>
 Accept: application/json
 Content-Type: application/json

 {
    "data": {
        "object_type": "image",
        "title": "Image title"
    }
 }
@stefanorosanelli
Member

๐Ÿ‘
I prefer second version, use of query string maybe more intuitive for a developer

@batopa batopa added a commit that referenced this issue Jul 20, 2016
@batopa batopa #918 feat: API upload first two steps
1. file upload
2. save in hash_jobs and response with upload_token
b57cb6e
@batopa
Member
batopa commented Jul 21, 2016

Due to the way query string check is implemented it is difficult to customize valid query string per endpoint for requests different to GET. We could improve it but could be a bit messy because we need to maintain backward compatibility.

I'll stay simple so I'll pass upload_token in the data payload

 POST /objects
 Host: example.com
 Authorization: Bearer <access_token>
 Accept: application/json
 Content-Type: application/json

 {
    "data": {
        "object_type": "image",
        "title": "Image title",
        "upload_token": "5a192d3f5716e9709df81974f5ee2aba"
    }
 }
@batopa batopa referenced this issue Jul 27, 2016
Merged

API upload #927

@batopa batopa added the Status - PR label Jul 27, 2016
@batopa batopa closed this Aug 29, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment