graphql_compose_file_upload
Security covered
About
Enable file upload mutations for GraphQL using the Multipart HTTP Request. Based on module graphql_compose.
Features
- Upload files via GraphQL mutations
- Validates file uploads against field instance settings
- Supports any file field on any entity type
- Returns proper error violations for invalid uploads
- Based on the GraphQL Compose schema
Requirements
- Drupal: 10.1+
- PHP: 8.1+
- Module: graphql_compose
Usage
GraphQL Mutation
The module adds a fileUpload mutation to the GraphQL schema:
mutation UploadFile($file: Upload!, $metadata: fieldMetadata!) {
fileUpload(file: $file, metadata: $metadata) {
errors {
message
}
results {
entity {
... on File {
id
url
filename
}
}
}
}
}
Metadata Input
The fieldMetadata input requires:
field_name
String!
The machine name of the file field
entity_type
EntityType!
The entity type (node, user, etc.)
entity_bundle
String!
The bundle of the entity
Example: Upload a File
JS example
const operation = {
query: `
mutation UploadFile($file: Upload!, $metadata: fieldMetadata!) {
fileUpload(file: $file, metadata: $metadata) {
errors {
message
}
results {
entity {
... on File {
id
url
filename
mimetype
filesize
}
}
}
}
}
`,
variables: {
file: null, // Set by FormData
metadata: {
field_name: 'field_document',
entity_type: 'node',
entity_bundle: 'article',
},
},
};
const formData = new FormData();
formData.append('operations', JSON.stringify(operation));
formData.append('map', JSON.stringify({ 0: ['variables.file'] }));
formData.append(0, fileUpload);
fetch('https://example.com/graphql', {
method: 'POST',
body: formData,
});
curl example
# Create file
curl https://example.com/graphql \
-F operations='{ "query": "fileUploadMutation ($file: Upload!) { fileUpload( file: $file, metadata: { field_name: \"field_my_file\", entity_type: NODE, entity_bundle: \"event\" } ) { errors results { entity_bundle entity_type id values } }}", "variables": { "file": null }}' \
-F map='{ "0": ["variables.file"] }' \
-F 0=@/path/to/myfile.pdf
# Create image
curl https://example.com/graphql \
-F operations='{ "query": "mutation ($file: Upload!) { fileUpload( file: $file, metadata: { field_name: \"field_my_file\", entity_type: NODE, entity_bundle: \"event\" } ) { errors results { entity_bundle entity_type id values } }}", "variables": { "file": null }}' \
-F map='{ "0": ["variables.file"] }' \
-F 0=@/path/to/myimage.jpeg
Response Type
The mutation returns an AnyFileUploadResponse with:
errors
[Violation]
Array of validation violations (if any)
results
AnyEntity
The uploaded file entity
Security
- File uploads are validated against Drupal's field instance settings
- File size restrictions are enforced
- Allowed file extensions are validated
- Access control respects Drupal's permissions
Troubleshooting
Upload returns validation errors
Check that:
- The field exists on the specified entity bundle
- The file extension is allowed by the field settings
- The file size is within limits
- The user has permission to create files
File is not saved
Ensure:
- The file system is writable
- The upload directory exists and is configured
- PHP's
upload_max_filesizeandpost_max_sizeare sufficient