Laravel Nagpur Meetup - Dec 2020

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Anybody who follows me will know that I love Laravel packages. The ecosystem provided by the framework is amazing. I was really nervous when I started writing packages; Laravel does such a good job of removing complexity that we don't often understand how things work under the hook.

If you want to get started writing packages, you might find this talk useful.

Additionally, if you have any feedback I'd love to hear it. I put a lot of time into the presentation but there is always room for improvement.

Happy coding!

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/lukerdowning πŸ“…οΈŽ︎ Dec 30 2020 πŸ—«︎ replies

Congrats. Here’s to many more tech talks 🍺

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/SavishSalacious πŸ“…οΈŽ︎ Dec 30 2020 πŸ—«︎ replies
πŸ‘οΈŽ︎ 1 πŸ‘€οΈŽ︎ u/smnfms πŸ“…οΈŽ︎ Dec 30 2020 πŸ—«︎ replies
Captions
hello everyone thanks for joining us today let's wait for just one more minute and then we'll start thank you okay so let's start i hope everyone is keeping safe you and your family members are all good this has been a tremendous year 2020. uh as you all know we have been conducting monthly meetups uh first in-person monthly meetups and we did around 12 meetups in the year 2019 and we were hoping to continue the same in 2020 as well but starting march we were unable to do that so we started this online meetup since april 2020 and we got a good response both in the terms of speakers as well as audience and we're hoping to continue the same in the year 2021 as well so let's start uh last talk of the year 2020 let me add this to this speaker to the stream give me one please i hope everyone can hear me fine can you please put in comments if everyone can hear us fine okay great so uh we have luke dawning with us today uh he is a full star developer from derbyshire england he is a firm believer that happy developers make happy consumers he contributes to open source and try to help others do the same currently luke is interested in laravel package development composer edge cases and developer tooling he works as a lead developer with ricobox which is a web agency specializing in event management hospitality so without further ado i would like to hand over to loot now look it's all yours go for it thank you very much thank you everyone for being with me hopefully you can see my screen and everything should be okay from here on out so yeah my name's luke downing thank you for coming and spending one of the last days of 2020 listening to me and uh as has been said i'm a developer from derbyshire which is right in the middle of the uk it's nice there's lots of green fields and trees and grass and the internet's not too bad either so that's a bonus i'm going to be talking to you today on a theme that's close to my heart and that is thinking like a package developer the talk consists basically of two parts for the first 15 minutes uh it's going to be a slideshow where i'm talking more at you than anything else but it's important because we need to understand why package development is so important and why it's a big part of the laravel ecosystem but then for the second half of the talk we're going to be building a package together live so that's going to be quite fun so sit tight and hopefully we can get through this in time so there's this phrase that's thrown around often in software development and that is decoupled code you've you've probably heard of this expression and uh it's quite self-explanatory but we do tend to have this habit of using phrases in software development without really understanding what those phrases actually mean so what does it actually mean to decouple our code well to decouple is to separate something from something else that it was joined to or part of but i want to alter that a little bit because you can also proactively decouple so you can separate something from something else that it could be joined to or part of um so it's important to understand the distinction there and an analogy i like to use to describe this is a train right so a train is this massive vehicle and it's much longer than most of the vehicles in the world but it's made up of lots of small carriages right lots of small parts and you can add or remove carriages from that train and the whole thing still functions as a train you can even add different types of carriage carriages so you might have a passenger carriage but you could switch that out with a coal carriage and the whole thing would still be a train in other words lots of small pieces make one big thing just keep that expression in your mind lots of small pieces make one big thing decoupled code or good code we could call it is very much like that train we should be able to add or remove features and entire feature sets without the rest of the application breaking down with minimal impact on the code base and that's really what decoupled code is aiming to accomplish so what are some of the benefits when we properly decouple our code what do we gain from decoupled code well first of all it boosts feature output and i want you to note that i've crossed out the word code here you're probably going to write less code when you decouple then you would if you were writing tightly coupled code but what you will deliver are stable beautiful full-fledged feature sets that make a real difference to the application as a whole so it's an important thing to know it also prevents some of the most common bugs so i don't know whether you've ever worked in a project and you change a line in the http client and then something in the database layer breaks down that bug is only caused by coupled code because the http client and the database should know nothing about each other so when those two things are properly decoupled almost every obscure bug that can take weeks to figure out they disappear and you end up with not zero bugs but certainly far fewer bugs it makes automated testing simple so i don't know whether you write uh tests for your applications or not but if you do and you really should when you're in a coupled environment you tend to have to write more workarounds and mocks than actual tests and to go back to what we were talking about earlier that http client and that database imagine if every time you call the http endpoint it hit the database in your tests you'd have to mock out the database just to stop that from happening and what happens is your test becomes filled with dependencies rather than actual expectations and results so when you look through your test suite you can't actually understand what the tests are doing is unreadable and this leads to one of two things at best you write fewer tests because those tests are harder to write but at worst you write no tests because you just can't see the value in spending that long world building and mocking out dependencies on the other hand when we deal with decoupled code tests are easy to write they're small because we don't have to create lots of marks and lots of work around just to get a test to work so automated testing becomes much easier with decoupled code and it reduces cognitive load this is a really important one to me have you ever come into a big legacy coupled project and i mean you don't even understand what's going on right and it might take months just to get a picture of what the code base is actually doing in your mind but even then it doesn't mean you're confident with the code so instead of removing a class or a feature set that needs removing you comment it out and hope that nothing breaks right or rather than refactor a class that really could do with refactoring it just gets left as this big messy block of spaghetti code and your mind has to work overtime just to make small tweaks something that should take 20 minutes can end up taking 20 days whereas in decoupled code everything is easy to understand because each piece is only responsible for a single thing and it does that single thing really well so we don't have to understand the business logic of the entire application to understand what one class or feature does i'll just say that again we don't have to understand the entire business logic of the application to understand what one class or feature does and all of these points add up to something that is often overlooked but that is so incredibly important and that is developer happiness let me explain why this is so important unhappy developers make poor quality coders it's not that's not an opinion that's a fact if you are unhappy you will not write your best code and poor quality code creates bugs which make more unhappy developers right no developer wants to sit fixing bugs they want to write new features but bugs also cause unhappy shareholders and unhappy business owners and unhappy customers so what does that lead to well it leads to stress and as such you get more unhappy developers it's this endless vicious cycle where if we write in a decoupled manner the code is structured well it's simple and beautiful it knows its boundaries it's a pleasure to work with and so it leads to high quality easily maintainable well-structured applications and that makes for happy shareholders and happy business owners and happy consumers and you get this awesome end product and so you leave work at the end of the day or the week really pleased with what you've come out with it's so important that you can be happy when you're doing your job now why are we talking about decoupled code in a talk entitled how to think like a package developer well the reason is if you've not already grasped it a package is decoupled code it is really difficult to write a coupled package because it sits in its own entity so unless you're writing terrible code it's almost impossible to reach beyond the boundaries of the package you don't know what application is going to be installed in and so when we start thinking in terms of packages we also start thinking in terms of good decoupled code so how do we define a package well first of all it has to be a self-contained feature or set of features it has to be self-contained it can't reach outside of its own domain instead what we do is we allow hooks that give us a set of tools to extend the functionality that the package offers now this is not to say that in a laravel package we can't use laravel features in fact when we build the package that we're going to build in a moment we're going to be making extensive use of laravel features but we wouldn't know anything about the application that the package will eventually sit in second the package is designed to be used by developers it is in no way an application it's not for end users it's not for consumers rather it's a set of flexible abstracted apis to be used by people like you and me in fact you might even create a package where you are the only user of that package it should still not be an end product it's designed to be used by developers it has almost 100 unit tests and when i say this i'm not referring to code coverage and i'm also not referring to the amount of test code you've got versus the amount of application code you've got i'm referring to the type of test so a unit test is our lowest level of test and it targets things like functions and classes rather than end-to-end features and processors this kind of just highlights what levels our packages are they are low-level packages they provide abstractions over difficult concepts leave your applications to do the top-level work and finally it can work alongside other packages so you remember that train analogy each carriage is its own thing but each carriage also has a mechanism to allow another carriage to be attached it's so important that you get that in your mind we need to develop packages in such a way that other packages in the ecosystem can fit in without any difficulty now of course at some point there is going to be a conflict of interest but in as much as it is possible we should be writing our packages in a way that allows other packages to sit alongside without issue okay i think that gets in our mind the idea we're referring to when we talk about packages so let's build something i i think the best way to demonstrate how easy it is to kind of switch the or flip the switch in our brain and start thinking like a package developer is to actually build one and along the way i'm going to be showing you tips and tricks that i have used and that really helped me when i build packages so here's the scenario your boss asks you to implement password breach checks and the idea is that when someone registers for your site um if they try to use a password that has been recognized in a security breach a published security breach then they should not allow that password now straight away you can see that this is something that could be used across multiple projects it's quite a generic thing but even if you could only see use for it in one project you should still very much consider building a package for it because of the reasons we've discussed earlier on it helps us to write better code in this case we're almost certainly going to use it in more than one project so we're going to be using the have ibimponed api and that allows us via a rest api to check if a password has been involved in a security breach so if i can if i can find the right application here's the documentation for the api i'm going to walk you through it quickly this is about packages not about the implementation but it's good to have a little overview of what we're going to be building so you can see we can make a get request to this api endpoint and we passed the first five characters of our password hash and the password hash is uh sha1 hash and it has to be utf-8 encoded right and when we pass that hash have i been pound is going to return a list of hashes that have been found to be compromised so if our hash our password hash is in this list it means that we have an insecure password and that's the long and short of it that's what we're going to be building now before we do any code i think it's important to talk about um the api that we're going to use oftentimes it's tempting to dive straight into uh the implementation without thinking about the the end product the end api for a user so let's take a look at the api that we want to use for our have i been pwned application i have i've been putting package you can see here's my first iteration right i have this phone facade and this password method and i pass the password that my user has given me into this password method and obviously that's going to return whether it's secure or not now this is okay it technically works but it's a terrible api to use as a human first of all what does this password method do right we have no idea does it encrypt does it hash does it make a http request does it record something in the database we have no clue it doesn't tell us anything so after reworking this a bit here's another look so this time we use the pwn facade again and we check if the password is safe this is a lot better we now can read this like a sentence we can understand what this is doing and perhaps even a non-developer could tell us what this is trying to accomplish it's also open for extension we could add new methods to this check object such as perhaps is compromised or breaches that returns an array of websites that the password's been breached on and we can keep extending without having to modify the api too much but there's still something that i don't like about this implementation and that's this pwned facade the word pwned ties the package down to the implementation that we're going to use it kind of reveals that we're using the have ibm pound api when in actual fact we might want to use a different api or we might want to use something local so we shouldn't limit when we don't have to and after a little bit more thinking here's the api that i really settled on you can see it's very much the same we check the password is secure i switch the facade out for this padlock keyword i think padlock is a really nice option almost everybody knows what a padlock is and it's very evident that a padlock is to do with security again a non-developer could look at this and they would know that they're dealing with something that is to do with security this whole thing reads really nicely we wouldn't have to spend hours in documentation just to work out what's going on and i think this is one of the most important things for you to do when you start developing a package or any api in your developing career write the api first then create the implementation it helps you to catch mistakes and assumptions early it helps you to become familiar with the purpose and boundaries of the package it helps us to understand how we might structure the package ahead of time it allows us to make the correct abstractions and it leads to a much more natural api which means more time coding and less time reading the docs when using your package so let's actually implement this api in a package now as we develop i'm going to be explaining things in as much detail as i can i don't want you to think that i'm being condescending if there are certain things that you know it's just that when i start developing packages these are all things that i struggled with so i want to share them with you in case you struggle with the same things creating laravel packages does not have to be difficult at all so i'm going to open up the project that i've created and in order to save a little bit of time i've created some boilerplate plate but please don't worry i'm going to run through all this now the root of any laravel package is the composer.json file so let's open that up and take a look when you run composer init on a new directory it's going to generate this file and the first thing i want to say is that name description type and license and authors is all just metadata it will not affect how your package works so don't get tied up trying to work out what these values are going to be when you first start developing packages the ones that are important are these four keys here require require dev auto load and auto load dev and you might be familiar with them but you also might be scared of them and i think the reason is that laravel is just such an awesome framework right it's so good and it comes with such good defaults that you barely ever have to touch your composer.json file which can lead to not quite understanding the tool that we're working with every day so don't worry i'm going to break these four very important keys down for you now anything in this require key object is going to be a dependency that your package relies on any project or package that we require here will also be installed in the application that this package is installed in so imagine if you create this package and then you install it well your applications vendor directory will include these requirements so here we require illuminate support which is basically the laravel framework if you're creating a larval package you need illuminate support and you can see that we're targeting laravel version 8.2 and greater now what do we do if say laravel 9 comes out and we also want to add support for laravel 9. well composer allows us to do the pipe operator to specify multiple supported versions so we could also say it's greater than 9.0 and you'll be able to use version 9.0 as well obviously laravel 9.0 isn't out yet so let's remove that for now you'll notice that i also require guzzle which is a http client the reason i'm doing that is that the have i been pwned api will be using the laravel http client which itself relies on guzzle so we have to install that as a dependency require dev is the next key this is very similar to require with one key difference any dependencies required in the required dev object will not be installed in the application they will only be installed whilst you're editing the code in your package so if i drop my vendor directory down you can see i do have the orchestra testbench directory and you'll also see that i have the past php pest plugins expectations that match these two dependencies i've required but when i install this package in an application those two folders will not be there now why have i required these two particular packages well orchestra testbench is a wrapper over php unit which is our testing library and it allows us to write laravel tests so if you've ever written an automated test and used this get or this put then you're using orchestra testbench so we need that to be able to write laravel tests i also bring in the past php plugin expectations pes php if you don't know or not familiar is another wrapper on top of phpunit that allows you to write tests more as closures rather than classes now we're not going to be using past php in today's talk but this plugin allows us to write awesome expectations and assertions which you'll see in a moment it's super clean so that's why i've required it here we also have this auto load key now this is perhaps where you start getting scared you've used require before but maybe you've not touched auto load much or maybe if you have touched auto load everything's broken and you can't figure out why auto load is just a specification that describes how classes and files can be automatically included in php based on their namespace and you'll see that the first thing we include in this object is psr4 so psr4 is just a standard set down by the php body and if we didn't have standards obviously nothing would work on the web so it's a good job they've done that for us but there are multiple different standards there's also psr0 so we want to specify that we're using psr4 here every key and value in this object is going to be a namespace that relates to a directory in our project so here we have the source directory hopefully you can see that in our finder and everything in the source directory is going to start with the namespace luke raymond downing padlock you'll know that we've got double backward slashes here that's basically because we're working in a string and a backward slash in a string is a special character so we have to escape that special character with another backward slash now take a look at this auto load dev object this is very similar to the difference between require and required f but for auto loading so anything defined in this psr4 object will be included whilst we're developing directly on this package so whilst we're editing code in the package but once we require it in the application these name spaces won't exist so it's a perfect use case for things like tests we want to be able to name space and access tests while we're working on the padlock package itself but once it's installed in an application we're no longer bothered about accessing those tests we don't need to run the package tests in our application something a little more advanced but just as useful is for mocking out namespaces that exist in laravel that you don't have access to in uh the package development environment so for example i have some stubs here that i want to publish to the application and i can use the app namespace in autoload dev to pretend that these are already inside the application in my tests that's super useful if you don't understand what that means it's okay but if you do you can hopefully see the power that that would offer you okay enough of composer.json hopefully we can come back here later and add a couple more things to give our project superpowers but for now let's go to testing you'll notice i've included this phpunit.xml file again this is something that laravel provides great defaults with out of the box so if you've only ever developed in the laravel application environment you may never have had to create a php unit xml file but this is how simple it can be we basically tell phpunit where our autoload file is and hint it will basically always be in the same place and you can see i've set this property colors equals true it just means that when we're running our tests we get some nice red and green depending on if our tests fail or pass we also have this test suites array of nodes each item in this array is a location in our project where tests can be found so we only have one place and i would suggest keeping your test in the same place you'll notice that we say any file in the test directory which is here that ends with test.php should be classed as a php unit test so any test in the test directory where the class name ends in test.php contains tests we want to run okay let's jump into one of those tests and it's going to be this padlock facade test this is where we're going to spend most of the rest of the talk kind of jumping back and forward and this is what's known as test driven development i've not written any implementation code yet but what i've done is created two tests that will prove our code works when these two tests pass it's a really powerful way of working and you should definitely give it a try if you've not already so you can see here we have our final api right if i switch back to tinkerwell padlock check password is secure and now back to phpstorm you'll see that there our api is right so if this passes we finished our api we have a working package and a working api so we're going to say well check the password password is secure and obviously the password password is a terrible password so we would expect that to be false but if we check this long complex password is secure well then i would expect that to be true right i'd expect that to be secure so what we can do is run these two tests and i'll minimize that a little bit and you'll see that we failed both tests right but we got a reason for that failure the facade padlock wasn't found well obviously we've not started our implementation yet so you'll see in my source directory i've created four directories and i like to kind of try and set my structure up before i start working and again if you've decided on an api beforehand you tend to be able to do this so in this facade directory i've created let's create a new class called padlock and obviously being a facade it needs to extend rfl facades let's run our tests again and now we get a different error facade does not implement get accessor get facade accessor method so again perhaps if you've only ever worked in the laravel application environment you've never had to create your own facade and that's not always the case but often you can get away with what already exists in this case we want to write our own facade so we will override the get facade accessor method and all this expects is for us to return a key that can be resolved out of the container and i'll explain what that means in a moment i'm going to return the string padlock and rerun our tests and you'll see that it's going to tell us that the container could not find that key padlock so the laravel service container is just this awesome way of applying dependency injection and dependency inversion to your applications it is super powerful and if you don't quite know how it works go and look at the laravel docs the author of laravel taylor artwell has recently gone and revamped all of the documentation for laravel and it's super clear now it's so easy to understand how it works so go and read through it and get your head around the service container and how everything works the service container receives its bindings by your service providers so we're going to create a service provider now and obviously it would be good to call it the padlock service provider one thing to note is that all of my subdirectories in this source folder start with an uppercase letter and that's because they are an extension of the namespace that we defined in our composer.json file so you'll see that this provider's directory has a provider's namespace appended to it so it's important that you use uppercase for those directories again obviously being a service provider it should extend the service provider that comes with laravel and in there we have a method called register that every service provider has access to and this is where we bind things into our application so i can use this app and because it's a facade i want to bind a singleton let's remember what that key is that we used padlock as a string and we want this to point to a class that is going to have our methods on it so let's create that class and because it's going to be the core of the entire project i'll create at the root of the source folder we'll call it padlock let's switch back to our service provider and let's reference that class name run our tests again and oh we got the same error now the reason for this error is that our tests do not know about this service provider remember we're not working in a laravel environment here we're working in a completely separate environment and we're tricking it into thinking we're inside laravel this is where orchestra test bench comes in if we go back to our test class you'll see i extend this test case which is just this class i've created here and this class extends orchestra's test case so you'll probably want to do this in every package you create create some base test case and you're familiar with this from laravel anyway laravel has a base test case that you can alter and change and there's a method you can override called get package providers anything you return in the array that you should return from this function any service provider you return in that array will be loaded as a provider for your tests so you can see here that i can return the padlock service provider i run my tests again the error should change and indeed it did which means that we have successfully bound our facade to our concrete class now you see the error now says well there was no method called check on the padlock object so let's go ahead and create a public function called check and if you remember our api we pass a password to that function right so we'll switch back and we'll pass a password to that function run our tests again it now says well there was nothing called is secure back to our api of course we're going to chain a method on called is secure but at the moment check is returning nothing so i'm going to create a class in this password directory that i've created called password lookup and in there let's have a function called is secure obviously this class is going to need is going to need to know the password that we want to use so in the constructor let's require that you pass a password and if you're wondering what this is this is php8 so because our package is targeting php 8 and above we're able to use this syntactic sugar to say well we're going to pass a password in and we want it to be a class property so that's really useful a little shortcut for us of course now if we go back to our padlock class we can just return a new password lookup and we'll pass it the password run our test again okay the message changed but we're getting very close let's go back to the password lookup class we just created and i bet now if we return a boolean from here one of our past tests will pass and the other will fail and indeed that's the case that means that we're at the point where we would want to implement the have i been pwned api now we could implement the have i been pound api directly in this function but i want to go through something that will be altogether better it's going to take a few extra minutes but it will be well worth the effort so what i will do is in this contracts directory i'm going to create a new interface called sentry and the reason i've called it century is because century is a great name for anything that acts as a guard right and we're dealing with passwords so that makes sense the reason i've called this directory contracts is that that mirrors what a lot of the laravel ecosystem does already so laravel itself has a contracts directory and many of the first party packages have a contracts directory whenever you can follow the tradition that laravel sets out you should try to because it's been thought about for a long time and any developer using your package that is already familiar with laravel will become instantly familiar with your package remember it's all about developer happiness so in here let's have a public function called is secure and we pass it the password and we expect it to return a boolean based on whether the password is secure or not in our password directory i'm going to create an implementation of this and it's the have i been pwned api so have i been pwned and it's going to implement that sentry interface and of course that needs to use the is secure method in order to conform to it now this is not a talk necessarily about have i been pwned but it's such a simple api that we're going to implement it live so the first thing i want to do is when i receive this password i want to turn it into the hash that have i been pwned expect if you remember from the documentation that's basically going to be a matter of sha-1 hashing it and also utf encoding it now if i switch back here you can see that the results are all uppercase so it would be wise at this point to uppercase this string so we'll use the string helper for that and we'll just duplicate it so our hash is now ready it's time to make the request right so let's make a protected function called make request and we're going to be using the http client it's a get request and again let's switch back to here and we'll grab this url and let's paste that paste that in there and we need then to add the first five characters of our password hash so i'll use the substring method for that pass in the hash and we want uh the first we want offset of zero and the first five characters okay so we make a get request to this endpoint passing the first five characters of our password hash and we're gonna want the body of that request to our secure method we need to call this right let's return and if the body contains our hash that means that it's insecure so it's the opposite of that so if string contains will make the request and then what are we searching for in that body or we're searching for a substring of our hash and we want to offset it by five to get rid of the first five characters i think that is the entire implementation done that should actually work obviously if i run the tests again nothing's changed because we've not told our package about this implementation so let's go do that now in our password lookup we'll change this return true to return the century as resolved from the container is secure and we'll pass this password in if we run the tests again they're both going to fail and we've got a very similar error to what we had earlier in this talk so the container doesn't know about sentry let's go back to the padlock service provider and let's add another binding so we're going to bind the sentry interface and any time you ask from for the sensory interface from the container we're actually going to return okay let's run the test again and we have two passing tests that means that we have successfully implemented have i been poned in a package now that's well and good but what if a user doesn't want to use tavi bin phone what if they want to rule um run their own version right what if they want to create their own driver that conforms to the sentry interface and use that in their package because we've written in this manner because we've got tests backing us up we're able to make this change very easily so you'll notice at the top of my structure here i've created a config directory and a padlock.php file you're probably very familiar with config files they're everywhere in laravel so you've got app.php auth.php database.php all of those config files allow you to change how laravel works and packages can provide config files to do the same thing so all it has to be is an array it returns an array and in that array we're going to follow laravel tradition once again so that our developers feel at home and can be happy we're going to have a key called default and let's allow the user to declare an environment variable called padlock provider but by default let's say it's going to use the have i bimponed api now let's create a provider's array and in that array we want to define the provider that comes out of the box with our package which is have i been pwned in that have a vibe in pound array we want to point to the class that conforms to the sentry interface which is have i been pwned as a class and we can clean that up by importing the namespace at the top okay that is our config file done let's go back to our service provider and switch this hard coded have ibm pound implementation for dynamic content from our config file so the first thing we want to do is load the default that is set so we'll say provider equals and we'll use the config helper method and we'll load padlock.default and then rather than hard coding have i been found here let's change this for a call to the config helper method and we'll load in padlock.providers and then we want to use the key that came from our default config and then we want the driver key now if we run this test again it's actually going to fail the reason is that we've not explained to laravel how to load our default config file this is something again that if you've only ever worked in the laravel application ecosystem you won't be familiar with but there's a method on every service provider called merge config from all we have to do is point to our local config file so here i go here's padlock.php and the second parameter is the key that we want to use to access anything in that config file so you can see we access it with padlock here and we access it with padlock here so we're going to use the same here let's run our tests again and they're back to passing but what's even better is that a user would now be able to go and configure a new driver without any extra work from us they could make our package behave however they wanted with very little work but how do they actually access this config file to edit it obviously we can't just leave it in our package we need to publish it to their application when they install our package well for that there's another method in service providers called boot this runs after every register method in the application has been run and what we can say is if this app is running in a console environment we will make the config file available to publish so to do that we again need to reference the location of our config file and we point that key to a value that is the location you want to store that file in the application so there's a amazing helper method called config path and obviously we want to call it padlock.php now when the user runs a command like this php artisan vendor publish our config file will become available for them to publish i want to be able to specify that we want to publish padlock assets rather than making them choose for the from the long list that will appear when they run just vendor publish and to do that it's as simple as adding one extra variable which is going to be padlock to the end of this publisher's function now when the user uses our application they can run this command from inside their application and they will see our config file appear in their config directory and because we've used this merge config from command anything that doesn't exist in their config file application will fall back on our default so it's such a powerful way of working and because we've designed in this way we've made our package configurable for users there's so much more i want to show you and i'm going to show you how you can see all the extra stuff at the end of this presentation for now let's switch back to keynote i want to review what we've gone over when you're working look for ways to split down applications into reusable feature sets you are going to be working in laravel applications most of the time so when you are doing that think before you start implementing a feature just stop and think can this be a package and what are the benefits of it being a package go and gather some inspiration from packages that already exist there are so many amazing packages out there but some of the best are the first party packages from the laravel team themselves so go and look like how did taylor introduce publishing right how does taylor mock the database in his packages how does he test models in his packages you go and look through the source code and there is so much information that you can make use of to improve and pretty much do anything that you can do in a laravel application inside a package here's a dead ringer right if you ever need to copy code from one project into another project take the extra five minutes to write the boilerplate and build a package because when a third project comes along that you need it for again it's a composer install away on that note get confident with composer especially autoload so many developers aren't familiar with the tool that we use every single day in our applications so go read the documentation look at what all the different keys available to you are think about why you'd want to use them in package development when it comes to time to host your packages packages.org is the way to do it it's free it's open source and everybody will be able to download your package to use in their application obviously that doesn't fit every use case you might be creating a package for a company or even a private package for your own use in which case i can recommend rep manda io it's very similar to packages it's also completely free but it allows you to host private packages and all you have to do is add a little configuration to your composer.json file here are some links the main one is this padlock repo it's already available on github at luke raymond downing forward slash padlock and it contains tons more than we've had time to put in today so for example how do you mock the database how do you pretend that you're working with models and migrations how do you cause those migrations to be seeded when you run your tests how do you create hooks that the application can use to extend the functionality provided to you by your package all of that is there there's full test suites for the entire thing so you can look through the tests and see exactly how it's all put together i've tried to make it as simple as possible you can also find me on twitter i'm at luked19 i'd love for you to come and follow me but even if not just come and chat i'd love to talk tech and any questions you might have in the coming weeks about package development or laravel in general i'd be happy to discuss i also have a blog downing.tech where i infrequently post things but when i do i try to make sure they're high quality content so you can go and look there and see what interests me and what i'm currently working on but with that done i think i just want to say if you have any questions i'd be more than happy to take them so yeah if you've got any questions please don't hesitate feel free to put them forward [Music] thanks thanks a lot luke it was a wonderful session i'm sure everyone learned something new today including me so let's wait for people to ask questions yeah okay i'll start with myself luke so i have a question for you uh would you recommend developing each and every project a client project using packages or what is your criteria to determine whether to go with packages or build it as a normal application that's a good question um so in projects that we've worked on it's kind of when there is something at the core that we don't like so recently we had to integrate with a soap api and when you've worked with the http client in laravel like working with soap apis again is just disgusting so so rather than just diving straight into using the default soap implementation we created a package around soap and that's obviously made developing with those soap apis so much nicer so that's one area but another area would be just when you stop and think like is this specific to the application if it's not specific to the application it could very well be a package because it will likely fit in another application yeah especially because even uh we have seen that what we generally do is there is some piece some feature or piece of code that we repeat in each and every project that we built for the clients so i believe it is better to extract it into a package so that it is reusable definitely yeah absolutely any other questions from our audience okay so uh look we have a question from yash how can i install package without register on any packet service so i believe what he's asking is he doesn't want to upload the package to packages or rackmen or anywhere in that case is there a way we can develop a package for local consumption or consumption in our own projects only yes so you can use again using the composer.json file which is why it's like so important that you look that up and understand how how composer works um you can use a repositories key to state a local repository and you can literally provide a path that is sim linked in the application to that local repository which would be your package obviously once you want to go live with that you need a way to host it somewhere and but there are there are applications composers themselves provide a quite a low level package called status s-a-t-i-s and that allows you to publish um or host packages on your own servers uh again the reason i recommend something like packagist or repman is that it takes the complexity away but if that's not possible you can host your own basically your own packages oh i think you might be muted at us sorry yeah uh yes i hope uh luke was able to answer your question so anyone else has any questions let's see will give just 30 more seconds look and then we'll call it a day uh in the meantime i would like to thank all our audience who attended today's meetup thanks a lot for joining and i hope you will keep joining us each and every month uh also as mentioned earlier we are constantly looking for speakers so if you're interested in speaking in our next meetup please submit your talks at the url that is coming up on your screen right now you need not be we you need not be a seasoned speaker we are we welcome uh first-time speakers as well so please don't feel shy and submit your talks okay i think that's it thanks a lot luke once again thank you and hope to see you soon once again in the year 2021 brilliant thank you thanks thank you everyone have a good night bye cheers well
Info
Channel: Laravel Nagpur
Views: 251
Rating: undefined out of 5
Keywords:
Id: _5K51S2wFgY
Channel Id: undefined
Length: 55min 14sec (3314 seconds)
Published: Wed Dec 30 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.