Problem: Standardize File Storage Clients

easy
15 min
Adapt different file storage systems to a shared upload/download interface.

Problem statement

Your backend uses two file storage systems:

  • local file system client for development, which saves files directly on disk.

  • mock S3 client in production, which uploads files to a cloud bucket.

Both expose similar functionality but with different method names and behaviors:

  • The local client uses save(file) and read(file).

  • The S3-like client uses uploadFile(file) and getFile(file).

This mismatch makes your file-handling code messy and repetitive. You need one consistent interface for both.

Goal

Implement a StorageAdapter class that wraps either client and exposes these two methods:

  • .upload(file)

  • .download(file)

Each method should internally call the appropriate function from the wrapped client and return its result.

Constraints

  • Do not modify the original clients.

  • The adapter must detect which client it’s wrapping.

  • The calling code should always use .upload() and .download().

  • No hardcoded conditionals like if (env === 'dev'); use method detection instead.

Sample output

The examples below illustrate what the output should look like:

const localStorage = new StorageAdapter(localFs);
const cloudStorage = new StorageAdapter(s3Client);
console.log(localStorage.upload('report.pdf'));
console.log(localStorage.download('report.pdf'));
console.log(cloudStorage.upload('report.pdf'));
console.log(cloudStorage.download('report.pdf'));
/* Expected output:
Saved report.pdf locally
Read report.pdf from local disk
Uploaded report.pdf to S3
Fetched report.pdf from S3
*/

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Problem: Standardize File Storage Clients

easy
15 min
Adapt different file storage systems to a shared upload/download interface.

Problem statement

Your backend uses two file storage systems:

  • local file system client for development, which saves files directly on disk.

  • mock S3 client in production, which uploads files to a cloud bucket.

Both expose similar functionality but with different method names and behaviors:

  • The local client uses save(file) and read(file).

  • The S3-like client uses uploadFile(file) and getFile(file).

This mismatch makes your file-handling code messy and repetitive. You need one consistent interface for both.

Goal

Implement a StorageAdapter class that wraps either client and exposes these two methods:

  • .upload(file)

  • .download(file)

Each method should internally call the appropriate function from the wrapped client and return its result.

Constraints

  • Do not modify the original clients.

  • The adapter must detect which client it’s wrapping.

  • The calling code should always use .upload() and .download().

  • No hardcoded conditionals like if (env === 'dev'); use method detection instead.

Sample output

The examples below illustrate what the output should look like:

const localStorage = new StorageAdapter(localFs);
const cloudStorage = new StorageAdapter(s3Client);
console.log(localStorage.upload('report.pdf'));
console.log(localStorage.download('report.pdf'));
console.log(cloudStorage.upload('report.pdf'));
console.log(cloudStorage.download('report.pdf'));
/* Expected output:
Saved report.pdf locally
Read report.pdf from local disk
Uploaded report.pdf to S3
Fetched report.pdf from S3
*/

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Node.js
// Simulated local file system client
const localFs = {
save(file) {
return `Saved ${file} locally`;
},
read(file) {
return `Read ${file} from local disk`;
}
};
// Simulated S3-like cloud client
const s3Client = {
uploadFile(file) {
return `Uploaded ${file} to S3`;
},
getFile(file) {
return `Fetched ${file} from S3`;
}
};
// Your code here
// Example usage
const localStorage = new StorageAdapter(localFs);
const cloudStorage = new StorageAdapter(s3Client);
console.log(localStorage.upload('report.pdf'));
console.log(localStorage.download('report.pdf'));
console.log(cloudStorage.upload('report.pdf'));
console.log(cloudStorage.download('report.pdf'));
/* Expected output:
Saved report.pdf locally
Read report.pdf from local disk
Uploaded report.pdf to S3
Fetched report.pdf from S3
*/