filesystem abstraction with flysystem

47
FILESYSTEM ABSTRACTION WITH FLYSYSTEM By @FrankDeJonge

Upload: frank-de-jonge

Post on 15-Jan-2015

1.160 views

Category:

Technology


7 download

DESCRIPTION

These are the slide for my talk about Abstract Filesystems I did at Laracon 2014.

TRANSCRIPT

Page 1: Filesystem Abstraction with Flysystem

FILESYSTEMABSTRACTION

WITH FLYSYSTEMBy @FrankDeJonge

Page 2: Filesystem Abstraction with Flysystem

WHAT IS FILESYSTEM ABSTRACTION?Bridging the gap between filesystems so the storage engine

becomes an implementation detail.

Page 3: Filesystem Abstraction with Flysystem

FILESYSTEMABSTRACTION 101

What are filesystems?How do we use filesystems?Moving to remote filesystems.Abstraction saves the day.

Page 4: Filesystem Abstraction with Flysystem

WHAT IS A FILESYSTEM?

LOGIC & STRUCTURE

Page 5: Filesystem Abstraction with Flysystem

WHAT IS A FILESYSTEM?Logic to structure and organize pieces of data in a storage

system.

Page 6: Filesystem Abstraction with Flysystem

WHAT'S IN A FILESYSTEM?FilesDirectoriesMetadata

Page 7: Filesystem Abstraction with Flysystem

COMMON METADATALocation / PathTimestampsPermissions / Ownership

Page 8: Filesystem Abstraction with Flysystem

FILE SPECIFICMime-typeFile sizeContents

Page 9: Filesystem Abstraction with Flysystem

DERIVED INFORMATION / PATHINFO():FilenameBasenameExtensionDirnameMime-type

Page 10: Filesystem Abstraction with Flysystem

FILESYSTEM STRUCTURE

Page 11: Filesystem Abstraction with Flysystem

STRUCTURE TYPES:Nested or Linear

src/

Filesystem.php

AdapterInterface.php

tests/

Filesystem.php

AdapterInterface.php

src/Filesystem.php

src/AdapterInterface.php

tests/Filesystem.php

tests/AdapterInterface.php

Page 12: Filesystem Abstraction with Flysystem

NESTED FILESYSTEMSAre the most commonHave directorieswhich have files and more directories... which have more files and directories... which have more files and directories.We're really used to this structure.

Page 13: Filesystem Abstraction with Flysystem

LINEAR FILESYSTEMAre like key/value storesdo have files, of courserequire a different approachdon't really have directories.

Page 14: Filesystem Abstraction with Flysystem

DIRECTORIES ARE A MYTH

Page 15: Filesystem Abstraction with Flysystem

WHAT CAN WE DO WITHA FILESYSTEM?

Several operations:

writereadupdatedelete

move / renamecopylistinspect

Page 16: Filesystem Abstraction with Flysystem

HANDLING FILESYSTEMS WITH PHP, A WORLDOF HURT.

Page 17: Filesystem Abstraction with Flysystem

In vanilla PHP for local files:

$result = file_put_contents($location, $contents);

$contents = file_get_contents($location);

unlink($location);

$timestamp = mtime($location);

$mimetype = mime_content_type($location); // DEPRECATED

$mimetype = (new Finfo(FILEINFO_MIME_TYPE))->file($location);

Page 18: Filesystem Abstraction with Flysystem

LISTING FILESglob($location . '/*'); // ?

scandir($location); // ?

readdir(opendir($location)); // ?

array_map('normalize_fileinfo',

iterator_to_array(new DirectoryIterator($location))); // ?

array_map('normalize_fileinfo',

iterator_to_array(new RecursiveIteratorIterator(

new RecursiveDirectoryIterator($location)

))); // ?

Page 19: Filesystem Abstraction with Flysystem

Memory problems? Use streams:

$resource = fopen($rLocation, 'r+');

$handle = fopen($location, 'w+');

while ( ! feof($resource)) {

fwrite($handle, fread($resource, 1024), 1024);

}

$result = fclose($handle);

fclose($resource);

Page 20: Filesystem Abstraction with Flysystem

WORKING WITH OTHERFILESYSTEMS.

BECAUSE REASONS.

Page 21: Filesystem Abstraction with Flysystem

SOME REASONS WHY:We want to scale (horizontally).... so, we want stateless apps.We don't have to serve files ourselves.Share files across multiple application.We want to enable a nice experience to our users which wasnot possible otherwise.

Page 22: Filesystem Abstraction with Flysystem

SOME CONSEQUENCESWe can't use built-in PHP function anymore.We'll have to start using API'sWe'll have to depend on third party code.

Page 23: Filesystem Abstraction with Flysystem

COMPARING INTEGRATIONS: WRITING FILESAWS/S3:

$options = [

'Body' => $contents,

'ContentType' => 'plain/text',

'ContentLength' => mb_strlen($contents),

];

$result = $awsClient->putObject($options);

Dropbox:

$result = $dropboxClient->uploadFileFromString(

$location,

$contents,

WriteMode::add());

Page 24: Filesystem Abstraction with Flysystem

Rackspace:

$result = $rackspaceClient->uploadObject($location, $contents);

WebDAV:

$result = $client->request('PUT', $location, $contents);

FTP:

$stream = tmpfile();

fwrite($stream, $contents);

ftp_fput($connection, $destination, $stream, FTP_BINARY);

fclose($stream);

Page 25: Filesystem Abstraction with Flysystem

DOWNSIDESDifferent APISupport different kinds of input (string vs stream support)Different results for EVERY operation

Page 26: Filesystem Abstraction with Flysystem

CHOOSING A FILESYSTEM ...can create technical deptcan create vendor lock-inrequire you to invest in them

Page 27: Filesystem Abstraction with Flysystem

SOLUTION?

USE AN ABSTRACTFILESYSTEM.

Page 28: Filesystem Abstraction with Flysystem

WHAT IS AN ABSTRACT FILESYSTEM?Logic and structure that enable a generalized API to work with

different filesystems.

Page 29: Filesystem Abstraction with Flysystem

WHAT DOES A ABSTRACT FILESYSTEM DO?It bridges the gap between different filesystem

implementations/packages and normalizes responses.

Page 30: Filesystem Abstraction with Flysystem

INTRODUCING:

FLYSYSTEMMANY FILESYSTEMS, ONE API

Page 31: Filesystem Abstraction with Flysystem

FLYSYSTEM IS:A filesystem abstraction layerLike a DBAL for files.Like illuminate/filesystem on steroids.

Page 32: Filesystem Abstraction with Flysystem

PACKED WITH SUPERPOWERS:Well tested codeEasy APICachable metadataEasy stream handling

Page 33: Filesystem Abstraction with Flysystem

FIRST LOOK AT FLYSYSTEMuse League\Flysystem\Adapter\Local;

$adapter = new Local(__DIR__.'/path/to/dir');

$fs = new Filesystem($adapter);

BASIC FS OPERATIONS:$fs->write($location, $contents);

$fs->read($location);

$fs->update($location, $contents);

$fs->listContents($location, $recursive);

$fs->delete($location);

$fs->getTimestamp($location);

Page 34: Filesystem Abstraction with Flysystem

USING AWS S3use League\Flysystem\Adapter\AwsS3;

$adapter = new AwsS3($client, 'bucket-name');

$fs = new Filesystem($adapter);

BASIC FS OPERATIONS:$fs->write($location, $contents);

$fs->read($location);

$fs->update($location, $contents);

$fs->listContents($location, $recursive);

$fs->delete($location);

$fs->getTimestamp($location);

Page 35: Filesystem Abstraction with Flysystem

USING FTPuse League\Flysystem\Adapter\Ftp;

$adapter = new Ftp($ftpSettings);

$fs = new Filesystem($adapter);

BASIC FS OPERATIONS:$fs->write($location, $contents);

$fs->read($location);

$fs->update($location, $contents);

$fs->listContents($location, $recursive);

$fs->delete($location);

$fs->getTimestamp($location);

Page 36: Filesystem Abstraction with Flysystem

MANY FILESYSTEMS

ONE API

Page 37: Filesystem Abstraction with Flysystem

FLYSYSTEM AND STREAMS:$resource = $dropbox->readStream($location);

$awsS3->writeStream($destination, $resource);

Page 38: Filesystem Abstraction with Flysystem

FLYSYSTEM IS A GATEWAY DRUG FOR...... DRY code... centralized problem domain handling... easily testable FS interactions... reduced technical dept... lower development costs... having less to learn.

Page 39: Filesystem Abstraction with Flysystem

TESTING FILESYSTEM INTERACTIONSUSING FLYSYSTEM

Becomes easier.Becomes more reliable.Might even become fun again.

Page 40: Filesystem Abstraction with Flysystem

DEPENDING ON FLYSYSTEMclass Author

{

public function __construct(FilesystemInterface $filesystem)

{

$this->filesystem = $filesystem;

}

public function getBio()

{

return $this->filesystem->read($this->getBioLocation());

}

}

Page 41: Filesystem Abstraction with Flysystem

TESTING THE DEPENDANT CODEpublic function testGetBio()

{

$expected = 'Some Bio';

$fsMock = Mockery::mock('League\Flysystem\FilesystemInterface');

$fsMock->shouldReceive('read')

->with('james-doe-bio.txt')

->andReturn($expected);

$autor = new Author($fsMock);

$this->assertEquals($expected, $author->getBio());

}

BONUS: this makes tests run super fast because you don't haveto wait for blocking filesystem operations (slow).

Page 42: Filesystem Abstraction with Flysystem

IMPROVED STABILITY OF DEPENDANT CODEClass should have one reason to change... changing filesystems isn't one of them.Most code shouldn't have to care where files are stored.Flysystem enables classes to be unaware of this.

Page 43: Filesystem Abstraction with Flysystem

OPENING UP TO NEW POSSIBILITIESUsing Dropbox for uploadsEase development by deferring filesystem choice.Painless pivots during application lifecycle.Nice to build a package on.

Page 44: Filesystem Abstraction with Flysystem

FLYSYSTEM INTEGRATIONSLaravel Integration:https://github.com/GrahamCampbell/Laravel-FlysystemSymfony Bundle:https://github.com/1up-lab/OneupFlysystemBundleBackup Manager:https://github.com/heybigname/backup-managerCartalyst Media:http://cartalyst.com

Page 45: Filesystem Abstraction with Flysystem

CRAZY FLYSYSTEM ADAPTERSNOTE: some might be urban myths, I haven't seen them all.

FlickrYoutubeReddit

Page 46: Filesystem Abstraction with Flysystem

THE LEAGUE OF EXTRAORDINARY PACKAGES

HTTP://GITHUB.COM/THEPHPLEAGUE/FLYSYSTEM

Page 47: Filesystem Abstraction with Flysystem

THANKS FOR LISTENING!Find me on twitter @FrankDeJonge