Laravel Meetup #11: Building APIs & Spotlight and Modals With Livewire

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody and welcome to another edition of the larval worldwide meetup like usual we have two very interesting dogs lined up for you after the break we'll have steve mcdougall talking about how to create a quality api uh steve is i think uh now a professional streamer by the amount of streams that uh that he does so i'm pretty sure it will be an awesome talk but first we have philo hairman's here uh to talk about two packages that he made uh with livewire let's see filo here and you see philo but you don't see me so i'm going to i'm going to correct that while i talk a little bit to you filo um yeah it seems to me that uh yeah you're suddenly all over the place nowadays with your packages and uh yeah with uh with some cool products even an electron app um but i guess that you've been doing laravel for quite some time could you tell us a little bit about uh about yeah how you got into larval and all the things that you do yeah sure um also share it in a minute like uh on the keynote but um yeah i've been using uh level since i think version three or something i've always been into uh php and programming i think it was uh around eight years old when i got started with um what's called again front page so working with just html and followed with php shortly after and yeah over the years i've been a freelancer i've been a co-founder and cto at a startup and at the start of this year i decided to start from scratch and to see if i'd like hey kind of make a living on by building products so that's why i've been all over the place this year or at the start of this year so on twitter but also building packages like the likewire ui and the modal and spotlight package but also the electron app which allows you to like manage multiple horizon instances um so it's been an interesting journey so building both commercial and open source pro products uh but i'm guessing like uh with you with spatzy and i say you guys almost reached 200 million downloads that's really crazy yeah um thanks and like having to maintain like these are just two packages but um having the issues coming in and um it's it's an interesting journey and it makes me more um yeah i got a lot more respect for everyone who's maintaining open source packages because um yeah there are a lot of people um who come with feature requests and uh need help so uh giving that you guys have so many packages uh it's really awesome that you guys are able to keep that up thanks yeah i yeah you mentioned our amount of packages but i think everybody who already created just one package deserves a lot of respect because yeah you've already done a lot to uh to help to help others why why you you didn't have to yeah you're going to talk about two of your uh packages uh during your talk right yeah correct maybe you should just start with your talk right you shall share your screen yeah sounds good okay um the stage is your fellow uh have fun i'll be listening in if there is anything um yeah i'll i'll let you know but i guess everything will be fine yeah is there any question is there any questions feel free to chime in like i don't have the chat open so uh if there are any questions from the people watching um feel free to interrupt and to ask a question if it's necessary okay perfect fm okay thanks um so hello everyone good evening good morning good night uh from where we are um in this talk i'm going to share a little bit of uh about my packages i've been building this year which is the modal and the spotlight packages for livewire and before we dive in um a little introduction um i already mentioned a couple of things just now from the netherlands i'm living in amsterdam i'm a self-taught developer and yeah i started with front page at like eight years old and been getting into php shortly after um started with i think yeah wordpress then moved on to codeigniter and eventually ended up using laravel and since i made the switch i've never stopped using it um so yeah at the moment i'm building my own products like unlock which is a platform where you can disroot and sell your code and um yeah it's it's i'm trying to see if i can help other people make a living on the side uh while you can just focus on writing code and building products and let unlock take care of the rest and so you can just sell your product in your code in like five minutes but it all integrates within the development stack of the developer so you can just use a composer to download the php package or use the npm manager to download an npm package or share auto updates for electron and one other product i've been working on is observer which is a electron desktop application to manage your laravel horizon instances and you basically can manage multiple instances within one application and i'm also been sharing my learnings on my blog and on twitter and yeah previously i've been a cto and co-founder at a startup for five or a little bit of five years and i've been freelancing for 11 years um so yeah i really enjoy programming um coming up with an ide and making something in reality i think that's something really awesome that everyone here as a developer can do you can just build your own stuff or whatever it comes to mind you can just just start um so yeah um these two packages that i've been working on um were the result of me having to need something uh like a model and like a spotlight um so it's pretty cool to like being able to build something that you just need yourself so you can i think uh scratch your own age what they say so yeah you can get the livewire modal package at github.com livewire ui modal and the spotlight is the same url but spotlight at the end and in this talk it's going to probably take about 30 to 40 minutes i'm going to show you how easy it is to like use or transform a existing live wire component into a model so for this demo i've set up a overview of just a bunch of users and these are two components so this is the user overview component and there is a edit user component and it doesn't do anything at the moment besides it it does save but you don't get any feedback but it does save the data and we're going to take a look like how easy it is to make this a modal and to see what is possible by combining combining the modal and the spotlight packages together so let's dive in so i'm going to switch to phpswarm and here i have my user overview component it's just a simple table with all the users and like you see right now it goes to a route and um we want to change this so when we click the edit button we open a modal and it's quite easy to get started we can simply change this into a button and use the wiring click attribute and live forex ships with a helper that works together with alpine like there's really tight integration so we can use a dollar sign emit and the moto package uses javascript events um to open and close modals so this gives you a lot of flexibility because you can open modals from anywhere so we can just say open moodle and as the second parameter we can pass the component name in this case it's the user you can see so on the left side right here that we have the edit user component and finally we want to make sure that we provide the user id so this by passing a json encoded string and we just say user and that's it user id now when we switch back and try to edit we'll probably get an [Music] exception something i forgot great like having the first talk and [Music] have something not working um let me see phones can be a bit bigger um and in my practice run everything worked [Music] take your time no worries sir we're not we're not really on the clock here so let me see weird oh wait sorry i know you found it no i know i've got to um when you i already installed the pictures via composer and the only thing you have to do to get started is make sure that you have alpine included and then you have to include the directive or load the component the modal is on the bottom of every page and that allows you to open the modal everywhere so if we um [Music] we should now have something there you go um we don't want to of course have any live wire component as a model so it's protected in that way that you must implement a specific contract so if we head back over to our added user component um obviously it's a basic livewire component that just has a bunch of properties with a little bit of validation and updates the user and to make this a com a motor component we'll just change this to auto component if now switch back and refresh the page and click edit we can now see that we have the added page inside a modal and the cool thing is that the existing page of course also still works so now we want to of course make sure that we can delete a user or cancel or save and that the motor will close so when we head back to our edit user model um it's just a little basic markup with everything already set up um i assume that you already have a little bit of knowledge of live wire and um we're going to focus on these three buttons so delete cancel and save so the easy one is to cancel out of the modal we want to close so we can use wire click and use the emit helper and we just say close modal back and click cancel you can see that the model will now close the model will also close when you click escape by the way next up we got save user so when we click save we want the model to close as well we can do this by heading back to our component heading down to the update user method which updates the given user and because we now extend the moto component we get access to a bunch of different helpers so we can just say this and say close modal now if we refresh page it and click save you can see that the model now closes but you also notice if i add a bunch of exclamation marks and click save that the underlying table containing all the users is not updating and that's a refresh page of course we want to make it so that once we click edit and we make some changes that these changes are reflected in the existing users overview table so we can do this by emitting events so we have a helper method for this as well so we can say close modal events we can pass the array with events that we want to emit in this case we want to update the user's overview component so we can simply say users of you has the name of the so we'll say user updated now switch to our user's overview we need to make sure that we have a business we're going to make a public function and hold get listeners return an array we're going to say when we get an event user updated we want to refresh the user overview component basically all takes so now let's head back and if you now edit this user [Music] save see that the user has now been updated and the user overview as well it's really cool how easy lifewire makes it to introduce these little changes and to update uh components using events that they can talk to each other okay so now that we have cancelled save done we can move on to delete now for the delete component i've made a very simple liver component that just gets a user and when you click the delete button it will delete the user so again in order for this to make to work we need to make sure that this component exits the component class let's roll one there we go and let's head back to our edit user and now we want to make sure that when we click the delete button we get the delete user component so we can use wire click the emit helper and we're going to say open modal this time it's the remote model that we want to reference and we want to pass the user and and there you go you can now see that it switches between the two different models um and this doesn't do anything just yet so let's dive into the delete user model and let's wire this up as well so again we can [Music] as well and i think i made a property or a method called delete so we can just say where click delete and i think that you do [Music] and refresh the page and you can see that the user was deleted but again the underlying user overview model did or overview did not update go back to our component and now we can say it's closed modal uh sorry good photo and users or view components and let's set it to user deleted of course we need to make sure that we define a listener so we head back and we can say user deleted and as well you can see that the component got updated but because the model got closed it tried to open the previous modal and that's of course something that we don't want because this user does not exist anymore so to fix this we can go to our weekly user and that's set workloads basically means that it will ignore any existing modals um and just close the entire modal and any child models that exist so let's give it one more try and there you go the model did not close it did not open the previous added user model and the existing table got updated what else do we got i mean by the way what's really cool uh buying these scenes um the package keeps tracks of all the modals that have been open and this maintains the existing state so if i came to filo and i click delete and i click cancel we can see that the existing properties that i've altered are still there if the modal closes completely then all the state is destroyed so if i click cancel and i click edit again you can see that the values have been set to the original model okay so what else have we got um yeah in some cases um of course the you might have like a really big form with a lot of things you have to fill out or your customer and it's always a bit of pain like when you click escape by accident that the model gets close and you lose all your data or when you click outside the modal that you lose all your data so there are a bunch of helper methods that you can use to change properties for the modal component so if we head back and go to our added user component and dive into the motor component you can see that there are a bunch of configuration options which have defaults that you can set via config and let me paste these into our the user component and let's go over them one by one the first one is the modal width by default it's set to two times xl so it's it's a modal component based on until when css changes we can say four time excel for example we now open the model you can see that the size has changed [Music] next we have the closed model on click away property and that's basically when you click outside the model that it closes so if you set this to false see that the modal now stays open even when we click outside the modal finally we have the same for the escape button well we can no longer close the model with the escape button so definitely recommend you to enable this or disable a bunch of these options depending on the form and the amount of information is there because it can be quite frustrating for your users to fill out a form and to lose a bunch of data by accidentally clicking the escape key or closing the model finally we have something called closed modal on escape is forceful and to show you what that means if i click delete and if i click escape it now completes completely close the modal it does not go to the previous one but if you click the cancel button you can see that it goes back so if we go over to our delete user component return false ap is no longer forceful in regards to closing escape you can now see that it goes back to the previous component instead of closing the entire model finally there is one more property you can change which is dispatch close event if you set this to stream it will dispatch a event via javascript that you can listen to in case you want to do something extra or have something on the other on the page or any customizations you want to make in regards to when a component closed you can change that here um so yeah that's the modal component in a nutshell so next we're going to dive into spotlight and i've already gone ahead and installed it as well and the only thing you need to do to get started with spotlight is add live wire and reference the component name which is in this case it's livewire ui spotlight and that's literally all it takes so if we now head back every page click the command k key or notice control k you get like this prompt and spotlight is a command palette similar to alfred that you might know from mac or spotlight you can add commands here so by default it has one command which is logout i don't have any login or authorization implement right now so we're gonna not execute them and then come on um but let's take a look and create our own commands to edit a user uh but instead of having to click edit we can use the command palette that we have right here so to do so we're going to switch to i'm going to see size right here we're going to say php artisan make spotlight and say user we can see here we have a new directory here called spotlight and it has created a spotlight command called edit user it already includes some boilerplate and some explanation on how it works um so in this case we can provide a name um yeah before we continue by default this command is not registered so we can dive into either the spotlight config or we can use the app service provider to register a command so we can say user right here head back to the browser you can see that this command shows up next dive into spotlight dependencies so you can have a spotlight command and just one does one thing for example redirect to a certain page but you can also request the user for specific dependencies so in this case we want to edit a user so we want to make sure that we know which user we are or which user user the given user wants it um so we can do so by defining a collection of dependencies and you can add as many as you want in this case we only need one so we're gonna set a identifier this is just a unique value and in this case we want to have the user want our user to ask to enter the user that they want to enter edit so we're going to say user you like to edit let's head back okay you can see that the next question is which error would you like to reduce or would you like to edit now spotlight uses this unique identifier to call a method so in this case it's a search dependency and so it's going to try and find a method called search user so you need to make sure that this matches up with the identifier that you've defined your dependency and in this example let's say we want to search for aim here the user model and spotlight expects a collection with spotlight with objects and these must be spotlight result objects so as the user username id is the unique value that's being stored behind the scenes the second parameter is the value that we're going to display and you can also add a little description so i'm going to say edit should show something like edit filo okay so let's switch back and now when we type edit user it should um use the method so we can search work just that but it automatically completes results while we're typing and use a little bit of fussy searching um with the javascript clients to get the best result so finally we have the execute command and like it failed because it tried to redirect us to a route and in this case that's not what we want to do we need to open the edit user pretty cool the dependencies are resolved from the container and but also the values that we or the dependencies that we define up here so our dependency has a unique identifier called user which means that we can reference this here and any other dependency that we have defined and it will automatically resolve a modal if it's a model in this or model in this case the user model um and the spotlight variable gives us access to each spotlight [Music] we have access to all the live frame methods and you can expect so in this case we want to emit a javascript event to open our model so we can just say email model to edit open our edit user component and we can add our user and i think say user there you go so that's really powerful because this means anywhere in the application you can just open spotlight type what you want to do and have the modal presented to you on any screen without having to navigate between different pages on your application um the spotlight command also comes with a method called should be shown and here you can resolve things from the iec container as well and you can for example check permissions if someone has access to this given command or not and finally there's one more thing i wanted to show you like now we have defined a search dependency but you can also just use regular input so yes and i'm going to say that we want to have another let's see and just for this example let's put message let's say here now we have another dependency called message we don't have to implement a search method because this is a input type we can say edit user now asks me to type a message which of course doesn't do anything just yet but what's really cool is you can pass these parameters uh via the open modal component so if we head over here we can switch and add now we're going to switch back to our added user and on the top we're gonna add a new vintage and our edit user model yes it doesn't make any sense but it just shows you the power that you get when you use slide and the motor component scanner so now we're going to say add a user hello world that we entered has been passed so it's really convenient that you can for example use spotlight to pre-fill pre-fill certain fields of your modal and like you said their dependencies are unlimited so you can add like 20 questions if you want um and i think that should cover it yeah be sure to check out the get a page there are a couple of configuration files that you can take a look at so the livewire moto package has some configuration options like i said to set some some of your defaults for your model and the spotlight um config allows you to register commands and it has some options to include or include css of javascript and by the way if you want to register your command from app service provider that's also possible simply do spotlight and take register command and pass the class name of the command that you want to register alright um yeah looking forward to what you guys think um you can get the package on getup it's been getting a lot of downloads recently it's really easy to get started and it adds a lot of convenience and when you combine this together with spotlight it's really powerful and i think spotlight is something i would like to see on like on every website because it makes navigating super easy and super quick and um i'll show you one more a little bit more advanced example this is unlock on the test environment and i've i'm using the moto component here as well and in this case for example i don't want to break the creation flow when creating a license so in this case i need to have a product or a license c i can select one but if i want to create one i don't want to navigate to a different page to have to come back so this is what makes it very powerful combining these chart components so i can just say hello i have it pre-selected inside the modal um so that's something i just wanted to show you real quick um you can make some really powerful combinations by combining these two components um so again uh thanks for watching uh looking forward you guys hear what you guys think and um back to you frank yeah i can already say that i'm super impressed by both of uh of these packages yeah as a long time alfred user yeah we see the the value of uh of spotlight nice yeah this is probably something that that i'll use in some of my own projects as well um i i got one question for you how did you get started with these packages that you had a need for for those in your own projects yeah so the modal package i i got started with so when i started building unlock i got started with live wire and immediately fell in love with how easy it is and not having to write javascript or have everything separated so i looked at level jet stream for example it already had a modal component in there but that motor component required you to have a modal included on every page so if you if you would use the setup that jet stream uses this means that every row in this table would have a associated modal already rendered inside the page so i was looking for a way to mitigate that and have a dynamic model where i could just load any model that i want from any page where i want it so that's when i tried and see like hey house is possible for you live and that's how i ended up building the motor component which is a combination of both javascript there is a little bit of javascript involved with alpine and live wire of course and the spotlight feature is something i i just had this idea like hey why don't we have this on on on websites like it's i use it on a daily basis um when i'm navigating throughout my system to open applications or to switch between applications i was like why don't we have this on a website and that's how the id um started and i just started building and i'm sharing like a lot of things that i'm building i'm sharing on twitter and i get like a lot of feedback which is really cool so people said like hey can you add like a bunch of dependencies um because at first it would just allow you to to execute one command and i got started and then it evolved a bit by bit and i got some really cool feedback from the companies um messaging me like hey this is really cool and that they already use it um so it's it's really cool to see like um having this great feedback and um yeah both of the ids started like well the model was a necessity like i needed this for unlock and the spotlight components which is an idea like i thought like hey this is cool to have yeah i think it's it's a it's a very cool idea and yeah personally i very much like packages that yeah use a little bit of javascript as well it feels a little bit magical like hey there's like the back end in the front end inside of a package uh helping your application now i really i really like it thanks okay filo yeah i'm sure i'll see you uh again at a lara con or another event but thank you for for now for uh for doing this thanks for having me okay thank you uh everybody for watching this talk we're going to have like a five minute break and then we'll be back by steve and after that we'll have a mystery guest so you have to stay until the end to find out uh who or what the mystery guest is we'll be back after five minutes see you then [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] and we are back i hope that you enjoyed this uh little break and uh did let's sink in the magic of filo's packages there be sure to check them out on github there's links in the chat and if you watch a recording of this video you'll find the links to the packages below this video okay let's go now uh to our second guest and that is steve mcdougall hey steve good evening hi frank how are you doing pretty good pretty good uh yeah we were just talking a little bit during during the break uh saying that you're like a professional streamer now yeah i don't know if it's professional or just addicted to streaming so let people decide their own on that one why uh why choose when you can be both you know addicted and professional i i can accept that compromise i think um okay um i think we can start with your talk if you're ready always ready let me share your screen and we can see it and wait i'm going to before we start i'm going to maybe mirror you a little bit so that you're talking towards your screen and then we are ready to go effendi so thanks everyone all i'm gonna say is that livewire ui package looks amazing i've used it myself definitely give it a go um i feel it's an amazing job with that one but on to my talk he's had his time that's mine eh so i'm going to talk today about building and testing apis um specifically laravel because that's why we're here um i've been building apis now for going on 10 years um they they've grown and they've changed over that time and what i've learned is an accumulation of what's going to be shown here today so who am i i'm steve mcdougall you've seen me most places as just steve king the reason for the difference in name is that i took my wife's name when we got married but i wasn't willing to give up my github or twitter handle it's only so far you can go with those sorts of things i am the engineering manager at jump 24 who are a laravel partner um a huge advocate for php most people know me as an advocate for php or tool stack or apis in general and as you can see i'm quite clearly a bearded man i'm more follicly challenged than our previous guests i don't quite have the hair that he does but i do have a good good little beard on me so we're just pulling opposites on this one so we are actually hiring at jump at the moment so just going to segue into this one before i jump into my talk if you love working with startup scale ups smes uh you love working with laravel we're creating some really cool php code we're hiring um but there is you can click on these uh which probably isn't very good for anybody watching but uh jump24.co.uk um we've got some jobs going come work with us we did some really cool stuff and what i'll do i'll probably tweet out that link a little later so other people can see it but before i do that let's have a look at how people do go wrong with apis so i've seen a lot of people before they will you know they'll do their data modeling okay okay so we want some users we want some posts we want uh some cred action going on so we can do create read update and delete and we're going to embed them slightly so you can get users posts through a nice simple restish uri and that's great all of that sort of stuff is really really good but the problem is it's not really an api unless it's serving a purpose and then people back in the three laravel seven days when everything all the models were in the app folder we'd have hundreds of models all in this big one directory then now we just moved it to a models directory um things start to get a little bit busy basically um and as as your models grow and as the complexity grows it's hard to kind of grow what's going on and how to find things you know you look at something like okay i've got a you know mentally move my head up and down three or four times to find that model or find that class that i'm trying to edit and it's the same with scopes if you're as your application's growing and you're adding more query scopes and more query scopes suddenly your model's got more scopes than your average gamer call of duty and you just don't know what to do with it um finding and editing these scopes starts to become a bit more of a hassle than what it's worth and it's not the purpose of scopes so in this i'm going to go through how you can work with apis and my wife's just going to do a quick walk there she goes a child has woken up to a bottle so without further ado we're going to go into some live coding because that is what i like to do why talk about my problem when i can actually just go through and work on it so i've done a little bit of a basic api already we've done some really really simple stuff currently all of my tests are failing as to be expected okay so i've got a couple passing uh by pure luck so what we've got uh we can create a new device can show a device can get a list of devices show a single device passing there um i don't know why that name is different and it can update a device so what we're going to be building today is i've recently found myself in a situation where we're looking at the devices we've got as a company and we're going okay so we've got 12 at macbooks we've got four on the lease when's the lease going to be up we just bought this macbook and we've got this internal policy where every x amount of years we're gonna recycle that and get a new one so that people are always on the right machines i've looked at solutions out there can figure anything out so i thought why not build a solution now this api is kind of part of that um so what we're going to do is if i come up and show you my basic changes this is a very basic laravel app so far the only changes i've done which i do to every api is instead of having an api file i create api directory so i can version my api really easily well i'll just zoom out so you can see this easier so within here i've got all of my routes all pre-set up ready to rock and roll all of the data modeling has been done because that's a boring stuff you know i'm not teaching you how to make models and migrations and controllers i want to teach you how we can make more maintainable apis so what we've got is we've got a nice prefix here we've got a nice block which if we create a v2 we can come down here we can create a new php file we can call that v2 and then when we create v2 we can just swap this over to v2 create a new one because we're using name spacing and that is all good and that will work but right now i'm sticking with v1 because i won't get v2 for quite a while i hope so what i'm doing here i'm using invokable controllers the reason for this is having a single entry point for your api is super useful you can go directly to it you can click through really nicely and easily and it's just all there it's self-contained it doesn't even need to extend the controller you know it can be a very basic plain old phpl uh playing plano php object it doesn't need to do too much so here is a very basic index controller we are getting all of the devices and we are just returning a status code of http okay which is 200 nice simple integer there so what we will do is we will quickly have a look at that let's just organize those because i don't you might slide for a little while come over to insomnia let's create a new request we're going to create a list devices yes here so typically what i do i would do open api at this point where i would start to describe it in an open api document go through all of that setup and go through the api design loop and create the polish view of what the api wants to look like but we're not here for that we're here to talk about laravel apis so we're going to focus on that one so we can go to assets.test because this is on laravel ballet we can go to api b1 devices and currently we have none so we want to accept application json again so what we can quickly do would be tinker and we can go to app models device actually we're going to create 12. that's all you need to do quickly this is great 12. there we go we've got 12 nice and easy there are 12 devices that have been registered here's what they look like there's a uuid a serial number a manufacturer model type operating system storage storage type all useful things that will be very useful to store as a business the the domain specifics for this aren't super vital um this is a a toy project that i'm playing with so the first thing that i'd look to do here is let's go down to my tests and let's see how my tests are working so i've got a nice index test in pestici let's see if i've got devices um create one insert empty basically i like to make sure i'm in an empty state in my tests run this and that all works fine so what we're doing is we're gonna say okay so make sure that our we haven't got any devices when we're starting this okay so now let's create one then we're going to do a get request pass into the name and assert that status coming back is in fact http okay and then make sure that we've actually got one stored in the database um just a nice way that i like to test i like to surround it with some kind of something that's going to fail before i send that http request so that i can i only ever get to that when i'm set up to do this test so what we can do we can actually extend this so what i would do here we will extend this to say okay so we've asserted that the status is fine but what we also want to do is we've got this device here and we're going to want to make sure that we can see it right so we can then jump in and we can say except jason um i'm going to put a closure here so what we've got here now is we can now fluently test our api at this point so okay so jason we want to make sure that it has one for example we should only expect to see one within there now that so let's quickly just run this so great it's working it can get a list of devices it only has one if we swap that to 12 for example then we should fail it fails so asserting that one matches size 12 perfect um but then we can go even further okay okay so we've got one but we kind of want to get the first one right so let's go grab that first one let's get the jason back in here as well what can we do with this jason so we're going to want to say where the byp device uid and that failed because [Music] okay so we're failing somewhere along there too so this is where we need to look at the json fragment i think so we want to look at assets let's do that then we could do that let's drop that and say as one etcetera and then we could do some like assert basin path our first one we're going to want to say um get some structure maybe or jsonpath which one which one's going to be nicer no we might have to jump into a circle jason a little bit more so etc so we want to say first item json i can use server direction what we want to do at this point is we could say um something like a where i think is going gonna be the best bet there settable jason stuff what can we do what can we do get the first one is he's gonna complain or is this gonna work for me okay he's complaining okay something's going slightly wonky on that one so i'm not going to spend too much time on it um probably not enough setup time done on my part if i am honest let me just run that again and we'll focus mostly on getting this built and working so we can say that we've only got one we've only got one here nothing's showing that shouldn't be showing and we have got devices available let's just do some tidy up because that is no longer needed so the first thing i look at when i'm doing this is personally i hate using these these helper methods um i've had some conversations um in the past with um a few people about using them nothing wrong with them at all just not what i like to do so my first step is always to move this and then get that status in there too i like to be very declarative with my code it makes working with it very easy and very obvious what's happening and what's going on there's my first step it's a very small improvement it's not um you know you're not going to see massive massive improvements in it this way but it's how i like to do it so that's my first thing let's move to that that works that is fine uh using a library that i built called um http status code which basically just allows me to have um nice constant so i can quickly reference instead of using um you know 200 or using the helper method for you know okay i like to be very specific for when i override these things so there's there's not too much you can do to improve upon this other than allow more flexibility so the first step with this is to say okay so if i'm going to let people access my devices i want to give them options and there's a really good package for this um i've already installed it so i'm just going to show you how we use it so devices you need a query builder spotty query builder i'm going to say for subject is going to be the device yes and then we are going to say the allowed includes if we click through have we got any relationships yet no relationships just yet but we can sort and filter so instead of that way we can do loud filters and allowed sorts then we would get them for example so what we can do now is we can swap that for this so filters what this is going to take it's going to take an argument of filters which is like an array or a string so what we do is what what would we want to filter by so on our device we've got things like uh manufacturer model type os so we're going to want to be able to say okay so i don't actually want to see where the manufacturer's apple or the model is macbook pro or the os is el capitan um cpu ram storage not super useful and what i find is really what you really have to bear in mind when building some apis is it's got to be a useful api you can't just whack jason crud around there add loads of options and expect people to get on with it because giving people too many options leads to confusion giving people not enough leads to frustration so finding that right balance of why am i building this api what sort of people are going to be using it and how can i cater to them well that is how you build a good api so at this stage you know just doing manufacturing model and os that is pretty good sorts i actually don't think i'd need sorts um which means i can just move that up push that over to here and if i just run that again i can now say okay let's um let's filter the model to be let's open up the query in there send it and see if it's in there okay so it's dying [Music] 404 not found bad request filter [Music] requested filters are not pulled out this way i'm going to double check the package i'll tell you what i will bring over that window this is the package i am talking about um let me add spartan search here we go there it is sparty query builder it is um my go-to so let's say we want to say filtering so allow filters name name that's fine filter name equals so what we've got going on here is where have i gone wrong filter model equals and that's fine i am wondering whether it is complaining because i've added filters and named arguments because i've noticed that with some php packages that they do have some complaints allowed filters filter are not allowed question mark let's just copy how they've done it here and we'll adapt so we're gonna have a filter name that's gonna equal that this is filters a filter not allowed typical so allowed filters filters is an array this should be working fine so at this point we would debug and say if it's any consolation i can't also see why yeah it's it's it's complaining yeah um i don't see it i i think you were giving like the right url so so we want to get a filter an array named john that's fine so we want to pass through the model yeah that's good that's fine so that bits are all working fine and the query builder i don't know whether it's uh failing early because i've added too many named arguments um some packages do complain about that so i will test that first here we go so we have still got filter i'm not allowed cloud filters are manufactured model os very strange um yeah so it picks up on that allowed filters but it thinks that there's a filter in the request right yeah this is the way i've always used the package and this is the way you do use a baggage which which version do you have in your computer good question um because i think we recently attacked a new major and maybe this is something wrong in that new major yeah four try try three let's try three works six and if it starts working now i guess i have some work with version four again uh i say nothing i apologize for making work for you on an evening no no problem to my defense the tests were all passing yeah yeah so that's all updated let's make sure it runs properly and i'm going to quickly that's doing the autoload that's all good let's hope this works it's better yep it works so if i displayed it i can do that and then if i include it i get the one yes oh yeah something with a new version okay i'll fix that uh again steve yeah you also sorry for for this it happens right so what we're doing here we're allowing ourselves to quickly filter queries so um if we open up table plus for example let me just pull over some table plus goodness so we can quickly edit this to something a bit more reasonable so if we go to like assets here get the devices we go to models or we're going to manufacture we'll change some stuff to apple okay now if we come here and we say um we want to check that there and you factor is apple we've now got three what we can do we can further filter this we can say okay we also want to filter out um to a very specific model as well um you know we don't want that model we don't want this model we want this very specific model here send it what is it doing funny now isn't it so let's grab that and we're going to put that value in as let's do est because it's nice and simple yes t you can further filter it out which would help if i did that there we go we can filter it out which means that we're very quickly querying against our api with little effort without going to a new url we're simply using query parameters the way they're meant to be used almost creating our own little advanced search so what that allows us to do then is if we go back to our test for example we can come to our index test and we can add another one now maybe we can say okay so it can get a list of devices after applying footage so we can now add a function in here so again we'll do exactly the same thing nice create we're gonna do within here we're gonna say that the manufacturer is apple and the model is a macbook cash pro that's how we want to store things so then when we do this we want to do um that this will still brittle run that's all fine but what we want to do is we want to assert that we are getting a very specific amount back you know at first we should get all of them back but we want to make sure that we can filter out very specific ones so we could say okay so go to this route and the parameters we want to send across are going to be let's get a model and say okay we only want macbook pro as a model to come back if we change that spell it wrong for example it should fail and it doesn't fail for some reason why is it doing it to me uh okay so let's go for a manufacturer root helper root parameters i might just have to do this manually okay so we're going to get that api b1 v1 devices question mark filter that's because i didn't do a filter of course so filter model equals macbook pro so now let's test it and now if i spill it wrong it's still passing okay i don't i just don't know what's going wrong with that why is that now not working uh we're not interested in that just yet has to be passive thing um has won so let's create a couple let's create um some that aren't so we'll create three that aren't one that is so now we're failing so four matches one just looking for a loader i make sure everything's working as we expect so devices filter model equals macbook pro that if i was to hit request that that's going to fail because it's not we're just using a uh different database this should now will fail apparently so something's gone winky wonky there has should only have one because we're trying to be very specific um that's that's a me problem not an api problem so again let's just ignore that and i will figure that one out for a stream that i'm gonna do i can do a stream on that one so the next step let's carry on because i'm not too sure how long i've been going going on for i'm blabbing on for now so i will carry on with these this is how we create nice index boots next route so we can then move on to another route let's move on to something a bit more useful um let's say a create route so we've got a store controller here what we've got we're validating our request we're passing through all the things that we expect we then go through create that device using the request and then we return that request with the http status of created we have now created that request so let's test let's test it there is a test for this um it doesn't pass so that might be a good place to start i won't get too excitable with my testing because obviously it's not gonna work so we've got 302 we're failing at the minute so api v1 devices store device this is what we need to work on so where we are failing is on our validation so what we need to look at here is validating so we can just create a basic one in here or we can create a data set because this isn't all about testing i'm going to create it inline what i would typically do at this stage i would create a data set within pest and i would say this you know here i would add a width for example but for now i'm just going to do it this way here's our device manufacturer is required so we can just say [Music] manufacturer test model best laptop best these parts aren't really super important okay well that'll be quicker if i just grab that with comma on it and keep that in my clipboard as the os now storage best i'll be correct so that's going to be 1234 would be the first one i do and our storage type best ram is before our ram type which is typically where you do something like ddr3 ddr4 ddr5 um whatever spec that you need to put in there cpu you would pop in the makeup cpu uh lease start and release end and purchase date they're all another bug fields so i'm going to leave them no for now which means that i can now just remove that let's just collapse all these together and come back to our test and run it again we're still failing so we got a 302 the type field is required i didn't do it right there we go i wrote laptop into the type and okay so we are failing because we are expecting the status to be okay but it's not going to be okay because that's not how we want to do it what the way that we want to do it we want this to be created we want to make sure when we are sending the correct response codes back when you're building an api it's very important to make sure you send back a you know status codes that are relevant send it back at 200 all the time it's great because yeah it worked but you know if i'm asking you to do something are you accepting it i asked you to create something did you create it i asked you to delete something you know did you accept that request is there any content to give back um status codes are super super important so that now passes which is great which means we can now go back to focusing on the controller itself so the first thing to look at would be let's make a new request make a request hey we're going to put that into the api under v1 under devices and under a store request so i can do now here import that drop that remove that and we now got all of this which we can copy click through add that to default tree and drop that straight in there meaning this validate is now just going to work so to test that we can come back to our test make sure our validation is still running that is all good if i get something like type which i know is required if i run it again you get a failure perfect yeah we can we would typically add a unhappy path test here by saying it flows an exception uh but i'm not testing for that right now um this is maybe i talk as i have probably already said a few times so there's our first step we have created a very basic store request obviously if you've seen any of my streams before you know i'm a big fan of strict types um return types which i've done through the stubs and we've done all of this which is exactly what we had before so all we've done is simply simplified this request by moving all of our validation into a store request our next step is how can we simplify this now this is the part that gets a little bit more complicated there are many ways to do this there's many ways to do it right there's many ways to do it wrong there is no 100 correct way to do this you do it the way that works best for you and it's your standard the most important thing when you're building this uh apis and when you're building any laravel application is to add structure it is to add standards that you understand and that you agree with so that you can follow through with that so first things first i typically come up here and i start to look at creating actions i create value objects and i create value object factories so the first thing i'm going to do is let's get all of this and let's say let's move this to a value object so the first thing i would do this is a data transfer object for some people who might not be familiar with the term i've always called them value objects it's a habit that i'm not willing to break just yet so that is what i will carry on calling them for now uh the sparty package is absolutely fantastic i just prefer to do it in a very specific flat objective way especially with php 8 i can just simply create it in a constructor like this i can then come over to my controller here and i can quickly understand okay so i'm gonna have serial i'm gonna have a manufacturer a model type the way i see this is that is extra validation on top of what you're already doing um it's just a really nice way to write laravel codes for me so here's our os then we've got um os and then on storage this is an integer the storage public screen for the storage type then we've got integer for the ram what we'll do we're going to match for and typically case it that way but we're going to match it that way for what we're already passing in so we can public screen ram type there then we can just put public spring cpu and we're not going to worry about these last parts because we're not actually using them right now what we typically do here is um i would public carbon lease start this would i'd probably do this is yeah a nullable nullable instance at that point i'm not going to go into the specifics of how and why i do certain things certain ways because that's probably something for another day i want to make sure i focus on this specific task so you've got a serial manufacturer model type os storage ram and cpu that is all set up so now what we can do is we need to create a quick factory so we can go create a new class and we're going to call this a nice factory what this device factory is going to do its only job is to create a new dto so you play public static function which is going to accept an array of it's attributes to return a device value object now from there i will go return new device value object where the manufacturer is mix something what i do at this point i can go back model is model next one cpu cpu hey add that type in there yes and the reason for doing things this very specific way is so that when i'm creating a a web interface when i'm creating a um a cli interface i can use the exact same things i can use the same value object i can use the same value object factory i could use everything the same and the only thing that's changing is interface into how it is working is refactoring it into the most simplistic way that can be tested in isolation and within that business process so we'll just quickly drop in this storage type within here ram and type last one is their serial number which just need me to quickly sort the arguments out again and then that will give me all of that which will create this only thing that i'd want to do on top of this is i can add a two of a yeah which would basically return an array basically of all of the above but in the reverse of what we just did with that factory i won't go into that for now i will focus on this part so what we're going to be doing here is going for a really simple 918 no um action base so we can go okay let's create a new directory here's our actions here are our device actions and we're going to create a new php class click device very simple php action you have a public static handle this is how i like do them some people make these invokable some people make these um well they do various various approaches so what we've got here we this action it wants to accept a value object so here's our device value object we get our object and we are going to return a new device so all we need to do is return new return device and that is actually now going to be an eloquent model not a device itself and we would go object accept like sets attributes objects give away that so we can quickly come back to here and we can say save you please in fact uh i'm pretty sure this sparsi package can handle a lot of this for you um i definitely recommend people use it if they don't like doing it manually i'm quite a fan of doing going through this step with a fine tooth claim um especially with php8 um it just it makes sense to be able to do this myself storage we're going to say this storage storage pipe storage type get the ram ram type and then the last one is for now into cpu and what we'll do is we'll say this cpu so what this is doing here is we're just gonna take basically taking this php object turning it into an array so that when we come over to our create device action this two array is just gonna do exactly what we're expecting for a model so now what we can do in our store controller we can remove this completely and we can say forget that we don't even need the floating um variable at that point we can change the device we uh here but let's just turn it into a new json respond first it's about data you're going to want the same status let's do that for now so our status it's still going to be http created we're still going to want that same created what we're going to do here we're going to have a device factory which is our app factories here we're going to make attributes that we want to pass through is request elevated but bad advice factory we want to pass that as an argument through to create device there we go three lines nice and simple it's a device and returns it from reading it from having a good ide you can click through understand what's going on okay i'm creating it from this object to an array okay what's that look like okay so that's what's actually happening how do i get there i can click back okay we're passing through the request validated through to our device factory to create it to pass it through to here and it's all done nice and simple nice and easy and this hopefully we'll still run oh it failed to have failed uh undefined awakey serial in device factory right this is why it is always important to test your validation availing because and final reiki serial in device factory line 14 device factory she'll always have cereal coming through and if we come back to we don't need that value object anymore still request cereal is not enforced so what we need to do is we need to make sure we end vortex go back to our quick test this should now pass because we want [Music] device factory line 19 okay typos and live coding are very very familiar things for me storage there we go storage i felt storage wrong of all the things i could possibly do wrong it's my typos here we go all passing now it always happens it's typos are part of the job you can do database transactions and there's nothing wrong with that um it's there's many ways i can do this and one thing i typically do here is um i could do it this way what i typically do if i want this to scale is actually just um you know create a dispatchable job so if i want to improve this i will go okay so make a job and i want this to be in devices create new device i've now got a job available so what i can do instead is create new device i want to dispatch and i'm going to pass the exact same thing and pass all of that in because then i can just serialize the object really nice and easily instead of doing it this way i can now say okay return a new standard response we don't actually need a body because we're doing everything in the background so the content for this is going to be no but the status that we're going to want to return is http no content done because we can't return at this point so we can swap that over and this is as simple as it needs to get so now i can come over to here and within this constructor i can quite simply say my device value object is what's going to be walking and in my handle method just go to my action again say handle and the object is going to be this object and suddenly i i've pushed all my processing for background um yeah my test is going to fail so what i need to do at this stage stage is say no content don't look at accounts here's my post request um no point running that now and run this down and i can say cool let's run that that's now working what i could also do at the same time is take and that's doing that i can say um plus sir something a certain dispatched um bait new device ass um whatever options does that take uh a call back i've never actually done it this way to be honest i've never tested this part so this is where we test the job basically so what we're doing is uh we're just pushing everything in the background and in this test we can just now move everything to the background and say cool let's test in the background yeah test that the bus is running and that stuff is working um job was not dispatched though but the job will be dispatched that's the point of it this will be dispatched um and then what we'd do is we would just test the bus at this point or test our uh cue here and say okay we're faking our faking our event bus here probably the wrong way to do it i've not i've not done this part for a while um we want to fake out our job queue and then after we've had our post request make sure that's actually in the queue and then see what we've got going on after that it's nice and simple nice and easy and you've improved and you've got no content so for this specific use case if you're using a mobile ui uh or if you're using an sba like next or next um you'd you're using some like redux using internal state to then say okay so here's here's a form fill it in on my web interface i'm going to take that input i'm going to store that locally and i'm going to dispatch an action to your api to then create that in the background now our api doesn't need to give that response back with a newly created model it just needs to get okay cool thanks for that i've accepted that request we're going to create it we'll come back to you later um like this for example that shouldn't be no it should still be created realistically but what we're going to do there is um you know you've got a record of that but next time you need that is when you're going to do a list request and you're going to navigate away you're going to go to the page you're going to perform this request to get all of them back again and you're going to update it so what's the point in giving you back that whole new you know doing all of this in in process creation when i could push it to a background process give you a faster api and it's actually improving your experience of using my api yeah it's great to get that back sometimes but it's not always needed and that is how you improve an api you go step through piece by piece how can i improve it what can i do better and then to take that one step further you can go to your jobs your models here um like i have here a new eloquent builder which is a device and then you can start adding your scopes within here so if we take an example of um i don't know we'll go for our other example of apple so we can have a we want to get all expensive devices um i don't know what's going on with that typo as usual with me expensive so let's say return this where the model or the um that's it there's our brand new query scope and what we could do is if more things have this we can start to create traits what i typically do in my builders i create a separate directory here called concerns within there i can add a new trait so we can quite create a quick trait and we could say as active scope for example what this would do is public function active this is going to return builder which is going to be an elegant builder we can say return this where active is true then we can obviously do a flip of that an active act of default false and any model that has active flags you can just pull this into the builder um obviously not very relevant with what we've got here but we can say has an active escape and we're done that's now got active flags flicking switching really quickly really really nice and easy to use nice way to extend your how you'll do your queries and it means making things like this much easier so we can come down to our controllers our api device index controller and we can say okay we want to get all of these the allow filters is that and we also want to say um we also want to load the expensive ones so now if we come back to here let's just hide those we're now only getting apple if we ignore that we're getting manufacture of ripping and suns put it back in we are now only getting apple devices because that's how we're querying so while i might not be i might not use this because i've got the filters it is useful for if you're doing things like active or you only want to choke inactive or purchased within you can do carbon now okay but you've been the last three months give me all devices yeah it's a nice way to extend this awesome package our aquarium builder so in short a way to write really good apis is to use the right packages find a standard that works for you and do things very logically and broken up so what i will do now is go back to play so every time i give a talk i like to give a quote usually by myself because why not so rest apis don't have to be hard but they do have to be stateless this was a quote by a bearded fellow called steve mcdougall and basically your rest api needs to be stateless it did you know you don't have to remember stuff it doesn't always have to give that response back uh with a payload say okay you asked for this to be created here it is sometimes it's more efficient to say cool i'm going to create that for you come back in a little bit because then the next request can come in faster and faster and you know you you pair that with level octane and suddenly your your api is faster than the tesla so i want to say thank you everyone for listening uh i am at just steve king on twitter github most places love some feedback remember we're hiring a jump 24 and i will hand it back over to frank that was a great talk steve uh i really really liked it and again sorry for the the little bug in the package there what happens i i still don't know what was going on i checked the package code of version four but i can't really see it but i'll send you some hints that can help you the bucket uh uh somebody else also tried to do it and it seemed to work so it's it might be in your machine it might be uh in the package yeah we'll see yeah we'll see i'll i'll send you some uh some hints perfect but uh yeah thanks steve it was uh was really nice i think you should also uh if you if you want to uh put some of these ideas in a blog post or something because things are like really really nice techniques yeah you have to find the time probably a little bit uh yeah i know work i've got five kids i stream twice a week i manage open source package yeah indeed uh i don't know if you sleep uh it seems sometimes sometimes way you have the time yeah okay steve uh again thank you for your talk and yeah i'm pretty sure we'll talk again uh uh soon definitely all right bye man thanks take care okay we are going to do our little mystery segment now and um the the funny thing is that i know who's uh who is going to do the mystery segment but i don't know what the content of the mystery segment will be so it's a little bit exciting for me as well and uh our mystery guest will be can nico hey man hey a bit nervous this is going to crash maybe okay hi how are you all good pretty good pretty good getting a little bit tired if uh if i'm honest um yeah it's already getting a little bit late here and i guess for the viewers as well i'm going to be very very quick okay as uh we have sort of a theme so we started with really big hair now and then a really big beard now nothing so that's pretty much like a like a funny thing happen here so let's just share the screen and let's go with it hopefully yeah you can see my screen now let me just push back the p2p so can you see my screen hopefully you yes you are so are ready for this so this is pretty much one talk or a super fast lightning talk that i have and i didn't found any place to give it so i'm just trolling here and giving it away on the laravel worldwide meetup so i'm going to talk about uh first of all i'm kineco i'm a full stack developer at medicare if you not know me and i'm going to talk about lumen and let's go straight to the main question right so is worth using in 2020 and 2021 it is no thank you so this is my okay thanks thanks for that [Laughter] okay that's a good that's a good segment yeah man i i told you that it was like a super fast lightning talk okay this is good knowledge i would say write a blog post about that as well i'm going to think about it if i imagine the time yeah if you have the time for it and if you can yeah if it's not too many characters right tomorrow first yeah i think i need five [Laughter] okay sorry about this trolling but this is actually a little bit funny because i mostly agree with you but this week i had a good use case for lumen but i'll block i'll blog about that it's something very specific yeah let me know let me know if i need to change my slides okay you can do it you can do the same presentation next next time but okay if you do this maybe okay i'm going to share the slides on on twitter so please follow okay thanks thanks for this awesome talk no no i just it was i invested so much at the site so yeah a darkest days of work right yeah yeah i needed a lot a lot of thought on this talk but okay thanks for your time okay thanks kaneko okay so we had three amazing talks here i don't know which one was the best one they were all mind-blowing take all of the lessons that you learned here and all of the things that you see here uh too hard uh i hope you had a fun time uh this evening and i'll see you again for the next edition of the laravel meetup uh i have a few guests in mind but i still need some confirmation so i can't share them yet but the next meetup will be somewhere at the end of next month november already okay take care everybody and until the next time bye so [Music] so [Music] [Music] do [Music] [Music] [Music] you
Info
Channel: Freek Van der Herten
Views: 2,404
Rating: undefined out of 5
Keywords:
Id: 0pylMAlfw5k
Channel Id: undefined
Length: 117min 16sec (7036 seconds)
Published: Tue Oct 26 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.