Google Drive is one of the most popular consumer and business cloud storage SaaS apps today. Like many cloud storage providers, Google Drive has a desktop app users use to sync files between their local file-system and their cloud account. This mirrors neatly with the organization of files in Google Drive, which are located in folders, or folder-equivalent Team Drives.

However, there is one major difference that quickly becomes apparent when accessing Google Drive through an API: files and folders in Google Drive can each have multiple parent folders!

You can try this for yourself via the web UI by selecting a file in Google Drive and typing Shift+Z on your keyboard. A menu opens that allows you to add the file or folder to another folder. In the screenshots below, the folder C has been added to folders B1 as well as B2 . The metadata of C shows both those folders as “parent” folders.





The secret shortcut and lack of equivalent menu options indicates that the Google Drive UI prefers to discourage users from creating these types of organizational structure. However, it still supports it—possibly for backwards compatibility. While Google Drive may have started out as a cloud service, the presence of a desktop sync app necessitates a solution compatible with traditional filesystems (ignoring symlinks).

The API makes this even clearer. The file/folder update endpoint accepts the query parameters addParents and removeParents that each allow multiple parent IDs. Here’s an example of it in action in Python from the Google Drive API guide:

file_id = '1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ' folder_id = '0BwwA4oUTeiV1TGRPeTVjaWRDY1E' # Retrieve the existing parents to remove file = drive_service.files().get( fileId=file_id, fields='parents').execute() previous_parents = ",".join(file.get('parents')) # Move the file to the new folder file = drive_service.files().update( fileId=file_id, addParents=folder_id, removeParents=previous_parents, fields='id, parents').execute() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 file_id = '1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ' folder_id = '0BwwA4oUTeiV1TGRPeTVjaWRDY1E' # Retrieve the existing parents to remove file = drive_service . files ( ) . get ( fileId = file_id , fields = 'parents' ) . execute ( ) previous_parents = "," . join ( file . get ( 'parents' ) ) # Move the file to the new folder file = drive_service . files ( ) . update ( fileId = file_id , addParents = folder_id , removeParents = previous_parents , fields = 'id, parents' ) . execute ( )

A Tree or a Graph?

This raises the question as to whether the Google Drive layout is a tree or closer to a directed acyclic graph (DAG). The Google Drive layout resembles a directed acyclic graph since it does not permit any item to be the parent of an item it is already within.

Recreating the user experience via the API

API-based uploads and folder creations require additional steps as a result of the ability to add multiple parents to an item.

The Google web UI attempts to conceal this functionality by overwriting files with the same name by default as shown in the screenshot below.

Uploading the same file twice

Selecting the option to keep the files separate actually proceeds to rename the file instead of preserve the file name. This helps maintain the illusion that Google Drive behaves similar to a file-system tree that requires unique names for each item in a folder.

The file automatically renames!

To mirror this behavior via the API, first query Google Drive (docs) for files within the target parent folder that match the new file or folder name, and then either overwrite that item or create a new one with a different name.

The Kloudless API handles this complex series of steps automatically, since our mission is to provide an abstraction layer that ensures a uniform API regardless of accessing Google Drive or other services like Dropbox. Here is an example of an upload request using the Kloudless API:

curl -XPOST -H 'Authorization: Bearer [TOKEN]' \ -H 'Content-Type: application/octet-stream' -H 'X-Kloudless-Metadata: {"name": "test.png", "parent_id": "fL2hp"}' \ 'https://api.kloudless.com/v1/accounts/me/storage/files' \ --data-binary @test.png 1 2 3 4 5 curl - XPOST - H 'Authorization: Bearer [TOKEN]' \ - H 'Content-Type: application/octet-stream' - H 'X-Kloudless-Metadata: {"name": "test.png", "parent_id": "fL2hp"}' \ 'https://api.kloudless.com/v1/accounts/me/storage/files' \ -- data - binary @ test . png

While each cloud storage provider Kloudless supports has unique features, Google Drive’s graph-based filesystem structure under the hood stands out. Gmail’s innovative use of labels as folders, and message threads, parallels the approach to folders in Google Drive. Let us know which benefits you’ve found from this power-user feature in the comments, and check out Kloudless to simplify your cloud storage integration!