Strapi Headless CMS Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello class in this video i want to introduce you to strappy which is a great headless cms and if you don't know what that is quickly a headless cms is like a traditional content management system like wordpress the only difference is that headless meaning that it does not have a front-end it has only the api which can be a rest api or a graphql api or whatever which allows you to interact with your data create data and manage it there and then you fetch it and then you can use any tool to create your front end however however you like it and what's great about strappy is that it comes with so much functionality right out of the box and it's completely customizable and you have that code base there and then you can deploy it wherever you want which gives you this amazing freedom is completely decoupled from any cloud system or whatever it's completely your code and it's really easy to get started with speaking of get started let's do exactly that and to do that we click the button that says get started so we can as you can see you can just hit this one command and it will actually scaffold everything and start your app so let's copy this i'm going to copy the mpx one and let's go to our terminal wherever you want to put this project and we just paste that in and here we have this create strappy app and then we can call it anything here i'll just leave this my project and then we leave this quick start flag which installs dependencies and sets up our scaffolding and then it actually starts it straight away all right so i'm just going to wait for it to do all of that all right so now it's done building the app as you see it launched us into the admin area as you can see here local host in 37 slash admin and here we have to create our admin user so let's do that so i'm just going to say here admin admin and for email let's say admin at email.com just give it a password repeat that password and hit enter and there we go this is the admin area of strappy and here you can manage anything what's beautiful about strappy is that you can create here uh your database models you can create your users and permissions or actually just manage them and then do all of that and as you do that it actually modifies your code in the background so that those changes persist and then when you share your code or you deploy on a server those changes will still be that so as you see by default we have this uh up here this collection type user and a collection type basically is kind of like a database model think of it that way so we have users and notice we don't have our admin user in this list because this is the end user users not the admins and we can start to actually create data straight away so here we can click on add new users let's add a dummy user so here i'll say john for username john at email for email and password i'll just say one through six and here we can tick on for confirmed that's one of the nice things about strappy as well is that it comes with a lot of functionality and one of it is actually sending confirmation emails to your newly registered users so here let's hit save so important always hit save on your changes so now if we go back to our users we indeed see that user there so let's create more content types and uh more data to consume so let's say we want to create a blog right that's a perfect example for doing any crud app so to do that let's go to our content type builder and here as you see we already have three types here the user role and permission we can create a new one by clicking here create new collection type and by the way there are single types and components but let's ignore those for now so let's go again to create new collection type and here i'll call this post for blog post hit continue and then we can add fields so i'm going to add a text field and this will be the title so let's call it title and i'm gonna click add another one and let's do rich text and this will be the body of the post and actually i'm done so i'm just gonna close this and now i can hit save and now it actually rebuilds everything and then restarts the server and there we go we have posts up here and of course we can create new posts so here let's create a post let's call this new or maybe first oops first post and for the body i'm gonna say first first post body and hit save and now that's created so to interact with this data with this api we simply go to we grab this base url this localhost 1337 and we go to a new window paste that and then say slash posts hit enter and we actually get a 403 response and that's not a mistake that's meant to be like that and by the way this is json formatter chrome extension if you're wondering now we need to change this resources by default in strappy are hidden away which obviously is a good practice so we need to overwrite oops let me zoom out this we need to override some permission thingies so let's go to settings and here's settings we can manage a bunch of things one of them is this roles under users and permissions plugin and if we go to roles you see that we have two default roles the public which is self-explanatory and the authenticated which is a default role that is given to any user that authenticates so if we go to public which we are in right now we scroll down and here you see in permissions on the application we have our content types which so far we only have the post and now we can enable certain actions so we can enable in this case find one and find which by the way find gets all and find one does exactly that and now if we hit save here and if we go back here and refresh we indeed see an empty array which is actually interesting because we created a post oh okay my bad we did create a post but posts by default have this draft and publishing system so you actually have to create publish here for it to be visible and there we go now that post is visible that same mistake that i would have liked to be staged but they happened anyway so that's cool all right so now let's say actually we want to connect our posts to our users and we want to have like let's say you want to have tags like an actual blog will have tags that's easy we just create new fields and we can edit our content types so we just go to content types builder again and we go here click create new collection type i'm going to call it tag and let's go continue and here we can actually add a actually let's add the regular fields first so we have a text field which will be the name of the tag and we'll add another one and this will be the relation field and the relation is exactly that is the relation between the custom or the content types that we have so in this case a post can have multiple tags and a tag can also belong to multiple posts so this will be called a many-to-many relation actually let's select here the model so hit this drop down and select the uh post content type and here we select this uh many to many button and let's leave this these default names so now we just say finish and we hit save and there we go just like that strappy has created this tags collection and it also created a pivot table in the background that links this posts and tags so if we go to tags and we add let's say what do we have let's say we have a tag for cooking it's a blog right so let's say actually we have a published system here as well so we can actually just remove that so if we go to tag here in the content types and we go to actually let's click this edit button next to the name of it if we go to advanced settings we can disable this draft publish system so disable it yes disable and hit finish so now when we create tags we don't have to publish them they're straightaway published which makes sense so let's say we had cooking we'll have coding of course and let's say i'm just going to create another one here let's say we have one that's called home and we just save and now let's say we go to our posts and we select this first post let's say we want to add some tags to this post so we just go here to tags what is this i'm just going to give it coding and then save and now if we fetch our post again there we go we actually get tags and it's in its own array because of course we can have multiple ones per post that's how easy it is now when i add one thing obviously every post has a user that posted it so that's if we go to our content type builder we can easily just go to post and add another field so here click add another field and go to relation so this will be uh yeah actually it's this one so if we select from the drop down we go to make sure to select user from user's permission and not user from admin so select that user and here um no actually it's this it has one it's not or actually no let's go it's the has menu because that's the type of the relation so here for the field name i'm just going to call it user and click finish and then click save and now if we go to our posts we click on this post you see that it has this user field so we can from the drop down select john let's say john posted this and we save and again if we refresh this there we go we get that user and the user is attached to that post brilliant now let's say we want to log in through the api and create a post that way because obviously in the real world we're not going to be creating posts from here we're going to have our users create our posts from any front end like a web app or a mobile app interacting with this api so i'm going to open insomnia and here i'm going to go let's create a new request here and i'll call this login and this will be a post request and you can check the documentation i know that the login will be to http localhost actually let's add that to our environment so i'm just going to add that here so base environment i'm just going to add a variable here so i'll call it base underscore url and as you saw earlier it's actually http colon slash local host 13 37 hit done and here i'm just gonna say oops here do like double curly braces base underscore url and you can use postman as well obviously it's the same so here we'll do slash and to log in we need to go to slash auth slash local and obviously we need to send a post body so here let's select json and we're gonna send we need two things so we need an identifier which in our case is the email so this will be the john email.com and we need obviously the password which i set up as one through six of course make sure to use the credentials that you use to create that user so if we run this that took a while but there we go so we get our response we get a jwt token our user and our users posts without doing anything like it's straight away there for us which is really cool and now we can create a post so i'm going to create i'm actually going to duplicate this and call this create post maybe actually put this in a folder so i'll call this post quickly and then check it there and it will just be create let's be organized and here we just send a post request to slash posts and by the way if you are confused you can just go to the documentation and go to actually concepts is there routing yeah there we go so routing it tells you here for any resource you have where the routes are and then you have by default um where can we see that actually okay maybe it's controllers yeah go to controllers yeah by default we have these uh find one count create update okay okay scrap that that's not the best actually if we go to our settings and then we go to roles here just to check yeah so here if you look at the uh permissions for posts and you click on this it tells us that we need to send a get to this and to create we just send a post request to slash posts in case you get confused you can just come here to see those endpoints all right so let's go back oops go back to insomnia and to create our post we just send those fields so we have what do we have we have a title and here we'll say new post from john for example and for the body i'm just going to say new post from john body and if we send this oh yeah we're going to get 403 so of course that's the intended behavior so we need to change these permissions but not in the public role let's go to the authenticated role and now in the post permissions we need to enable the create so we have the create actually let's enable all and by the way there's a one inconsistency that you have to be aware of if we don't enable find i'll just show you so if we don't enable find and find one and we just enable the rest and we just save on the authenticated and we go back to insomnia and let me take that token again so let's copy that jwt and go to the auth header so here select uh where is it very token and paste that token in and send this request okay of course we get successful for this because i forgot to change the end point anyway so that's the post created so if we duplicate this let's say this is the read so this will be just get without a body so now if i send this we get forbidden and if i disable the token we actually get the data so this i don't know if this behavior is intended but it kind of doesn't make sense because if you're authenticated you should already have access to the public ones but i don't know maybe it serves a purpose but anyway we can get around that by enabling those functions or those actions on the authenticated role as well and then save and it will work as intended so now if we run this with with the token enabled we still get our posts and as you saw we were able to create this post and that was successful now if you notice that here we have a user but it says no it does not have a user now strappy by default does not um associate any models with your created uh content type instance it just creates that content type instance or that record based on the fields that you gave it now this is where we can go and actually customize the code to make this happen now you notice we did like already a bunch of things without writing a single line of code which is brilliant so let's uh i'm going to go where's the terminal so here in the terminal i'm actually going to stop this yes and i'm going to open that with vs code so what was that uh that was yeah this uh my project so code my dash project and hit enter and i'm actually gonna close this we don't need this anymore so you have a bunch of folders here and uh not worry about most of them let's go to this api folder and if you notice we already have a post and a tag folders which were created when we created those content types and inside each of them we have this config which has our routes which we can edit obviously and it has a controller which we'll come back to and it has this model uh post.js and then it has this post.settings which is the attributes of the model and then it has this service file as well as you notice all these files are empty which you might be wondering why and the reason why is that the functionality is behind the scenes and it's actually in the strappy packages it's built behind the scenes and if we want to customize it we simply override this uh any of the methods or or files that we want and what's nice about strap is that in every one of these files we have this link to the documentation so if we click control click this we get thrown into exactly the documentation for this file which in this case is the post controller and here it tells us for example here tells us all the functionality that we have by default the actions and if we want to customize let's say in this example we wanted to customize the create so that it associates the user with the post that was created we simply go let's go to the documentation go here to collection type create and we just copy this async create function and then go back to our code and inside this module exports object we just paste that in and we just update the logic so we want to add the user right there's a middleware by default that's actually passing the user from the authentication token that we added as a header and adds it to our context state and if actually this context uh syntax confuses you a bit this is based on koa don't worry about it too much it's almost very similar to um in many ways to express so to get the user we can actually say const user put it in a variable and this will be inside the context dot state dot user and because this route is only available when we're authenticated we know for a fact that you this user will always be there so now we need to add this user to the data when it's created now there are two places where it's created for multi-part requests which we'll come back to later and for regular requests so we need to add it in both so here where we create by the way we need to change this restaurant to post so select all of them and change it to post because that was an example from the documentation we need to change it to our model which is post in this case so here we will create to data we simply let's make it an object and then spread that data and then add on top of it the user and it's actually our user id you don't give the object itself you just give the reference field so here we say user and that's user dot id and we can actually just remove that and then here's say it's user it's context.state.user.id and then just give it as user there now let's do the same over here so let's make this an object and spread the context.request.body which contains the the title and the body of our post and then do comma and add user and close that object and now if we save this and actually because i stopped that terminal we need to start it again so i'm going to open a terminal here and say npm run dev and oh missing script uh let's check the package json oh yeah by default it has this strappy develop as develop but i'm just actually um oops what is this what did i click i actually launched it with the gui anyway so i'm going to actually uh rename it to dev because that's kind of like what i'm used to not that big of a difference all right so okay it started but i got an exit code so i'm just going to actually uh break out of that and then here say npm run dev all right so our app has started again so now if we go back to insomnia and now if we go back to create here we have our token our bearer token and we do another one so here we'll say another post from john and here i don't know we just say another post body let me add an a here run that okay we get a 500 eternal server error let's check what's happened okay so here we get reference error sanitized entity is not defined let's check our code um so it's this oh okay we probably needed to import these yeah okay we need these import statements at the top my bad so just copy those and paste that there and save and as you save it restarts automatically which is nice so now if we go back to insomnia this time it should work run this and there we go so our post was created and our user was attached to the post cool by the way bear in mind every time you send a post through the api itself it's automatically set as published so you need to edit your settings if you want uh that behavior to be different now if we get our posts we'll get this new post added at the bottom cool and to get just this post we can grab the id and duplicate this i'll call this find one create that and then say slash post slash and paste the id which is full and now we get just that post now to show you a bit more about how you can easily customize your business logic in your strappy app i want to actually create a slug for our posts and not have to fetch our post by id which obviously is a bad practice so we can easily do that we can just go back to our admin panel so to our admin here where we have our content type builder let's go to our post and we can add another field and here let's add so here this unique identifier field because we slugs are usually unique so here but there's already an example here that says slug and we can say slug here and here this is interesting we can attach a field to it and we can say finish and save but now if we actually create a post here let's say another i don't know i'm running out of like names okay let's do an actual post how to make an omelette just crack eggs eggs on a frying pan okay that's enough okay so you see already has a slug here which is nice which is a slug of this title and if we add let's add a user john and some tags cooking maybe also home and save and also publish now we're going to get if we go to our post we're going to get that post and we're going to get that slug attached to it but if we create another one here programmatically i'm just going to add some uh like zs here just to make it different i'm gonna get a post back but with a null slug so that's a bit interesting the slug system does not work through the api it just works through the admin panel but we can customize our code and make it actually generate a slug every time a post is created so i believe there's a guide for that in the documentation so let's go i'm just going to search here a slug yeah create a slug system so here scroll down yeah there we go so here it shows us how to update our model filing give it these lifecycle methods so before create and after on up actually before update as well we create this slug or update it so that's nice let's copy the bookshelf code actually actually they're kind of identical but whatever let's copy this one let's go to our code base go to our explorer and then go to models post and paste those inside of here actually i grabbed the whole thing so just paste this instead of all of that i'll put this at the top and we actually need to install this so open the terminal okay we broke we broke our code but it's fine we'll fix it so let's say npm install and install sluggify and let that install and now every time a post is being created or updated a slug is created from the title let's open our terminal and start our app again so npm run dev i don't know why i'm getting these warnings now after installing slugofy but i'll ignore that for now so let's uh check now our endpoint and now if we create this another one i'm just gonna say another post three and then here's a three body and run this there we go we get our post and we indeed get a slug that's made from the title cool so that's done now one other thing that i want to show you that's really cool that comes with strappy is managing media files so let's say our post by default uh every post has an image that shows at the top of the blog post so to do that we can just go to our content type builder and go to our post and just add another field and add this where is it this media field and let's call this image and just say actually just finish and save and now if we go to our posts and let's say to this three we scroll down here you see image and we can actually just click here and click upload assets and now we can upload any of these images so i'll select this code image for example and say upload one asset and finish and now if we click save there we go we get this image and it's attached to this post and if we go back to insomnia and let's say we want to fetch just that post which is uh i think id of three and we run this actually was it three now it's actually seven so let's go back here let's replace this with seven run this there we go we get this image object and it's this huge object with a lot of details about the image as you see here there are multiple formats of this image and there's a url yeah here so there's this url so we can copy this url and go back to our browser and if you go here and just paste that here after the base url and we hit enter there we go we get this image and it's actually uploaded we can use it in our front end and everything is already implemented so that's an amazing thing that it handles file uploads that easily just out of the box if you go actually to the public folder to uploads you see that we have our image our original image and we have multiple versions of it depending on the screen size which is really nice actually we can it's a nice image optimization for our front-end experience which is another big plus now i'll spare you the rest of the endpoints because it gets a bit repetitive you can go ahead and check out the endpoints for creating uh but we do already did that you can check updating and deleting and by the way right now it's uh you can delete any user's post as long as you're logged in which obviously is not the intended behavior so you can actually go and implement these and make sure that doesn't happen so that's maybe homework for you i guess now one other important thing that i wanted to show you is that uh strappy is highly customizable in terms of uh settings as well so for example if you go to what we have so we have this config folder so if you go to this server you can customize on which port it runs and you can customize on which host so i believe yeah so we have this env.example and you can grab all of this and create an actual dot env which by default is not tracked by git of course and you paste those in let's say i want to change this to 5000 which is where i usually have my servers uh hold running at so if we open our terminal break out of it and run it again it will now run it on 5000. there we go so localhost 5000 and we can also configure so let's see what we have as an extensions yeah extensions user permissions jwt we can configure the actual jwt secret by setting the jwt environment variable in the dot env and here you see it has this auto generated uid as a default which obviously will never match any other person's app which straight away works i guess and you can also add here and expires in because it uses a json web token in the background so let's say if you wanted if you want your tokens to expire in like let's say one hour you just say one h there and that's done and actually right now all of the data is stored in this where is it yeah and this data.db because if you look at the package.json it by default installs sqlite and stores all the data inside the directory here inside of this data.db sqlite db file now of course you can as well customize this so actually let me show you so let's stop this and uh shame that this database.js doesn't have a documentation link they can do that because they already they have a great page here where is it so think no not admin panel is it content api no concepts okay it has to be in guides yes right here so database okay that took some time so here you tells you about how the database by default works and here you can go to sql databases and configure it and of course you can configure it with mongodb so i just want to configure it with postgres just to show you how easily that's that can be done so go to configuration section here as you see this is the database.js that we were editing and to connect to an external database we have to add these fields of course the credentials for the database like host port database username and so on so we can add them here i'm actually just going to duplicate this once so instead of the file name and the client sqlite i'm going to change this client to postgres or actually we can make it come from the environment as well so we have this nice env helper which either takes the env variable from the dot env or has this fallback value so here we can say env give the actual key so this will be in our env file we'll call it db underscore client otherwise it's going to be by default postgres in this example close that and we don't need this file name thing so i'm just going to remove it and maybe duplicate this a couple of a couple of times so we'll have host so i'm going to control d here say host oops host and maybe give this a default value of 127.001 and select this this will be the username i'll leave that the default postgres and ctrl d here select this will be the password maybe let's say secret of course these fallbacks are meant to fail if you don't set the env variables so we'll have the actual database name so here's a database and what else do we need actually we need schema which by default is actually doesn't have a default value but we'll set a default value so what else actually yeah we need a port as well so let's duplicate this and this will be port and by default the default postgres port is 5432 and this last one is the schema which we can just say it's um it's public i'll actually select these and alt and select all of these these need to be uppercase so let's say transform transform to uppercase save and now let's go to our i'm just going to copy one of them go to dot env actually i'm not going to overwrite the client because it's postgresql that's fine i'm going to overwrite the username of course here put your credentials for me it's classed and then we're gonna have a db password which is root and a db uh database which i'm going to create now i'm going to call it strappy underscore starter let me see do we need anything else the default here is fine here is fine the host that's localhost that's okay all right so i think this is enough all right so i'm going to open the terminal having postgresql installed i'm just going to say create db and say strap strappy underscore starter and put my password cool the database is created actually just going to connect to it psql-d strappy underscore starter put my password and if we do backslash d of course we have no relations yet but okay if you open a new terminal and say npm run dev okay we need to install pg for it to be able to interact with the postgres database and now we do npm run dev and there we go it asks us to create an admin again because all of that data is gone of course because we're using a different database now so i'm going to create the admin again admin email.com put a password hit enter and there we go you see our collection types are still here but of course they're empty but the structure is still here it's maintained it's part of the code base if we go to our settings i believe our settings i think they're reset yeah there are settings reset because the settings are stored in the database which is where you want them to be because you don't want to edit code just to say uh change settings all right so i'm just going to enable so this is the public we're going to enable find one find and count for post ignore tags you can do that if you want that was just to demonstrate to you like the admin panel so i'm going to save here and then we go back to roles go to authenticated and enable everything for post and save and now if we go to insomnia actually i'm going to edit the environment and change the base url to localhost 5000 because i changed that in the env now if we run read we should get an empty list okay we'll get 401 okay because the user is not found okay all right we need to actually this will be a good time to show you the register let's duplicate this of course because you can register using the api as well so i'll call this register and this will be slash all slash local slash register and if you want to know more about the auth routes just google strappy users permissions routes and you'll find the answer and here to register we're going to give an email and i'm going to leave that email as is and we need the username and that will be john and that password just once and run this and there we go our user is registered and actually just instantly logged in which is pretty cool so if we take this jwt token and we go to read okay this should actually work okay cool okay what didn't work earlier oh okay my bad it was the authorization system we edited that all right so we have no posts and we can go here and paste that token and create another post or just say again first first post run that cool we get a post a slug attached to that user and if we go to read of course that post is there and now everything is in the database and if we go to our database we do backslash dt we see all those tables created for us you can even check the posts so select star from posts our posts are there that's how easy it is to actually connect it to another database this is just the beginning and this is just the basics of this of course you can extend it to do anything that you want for your app and you can customize anything you can even customize the actual auth routes just you can go here extensions user permissions and you can override those controller actions as well now i love this tool as you can see we did so much if we were to do this without strappy we're just connecting libraries together and creating all this it will take way longer than this but of course we'll have some other advantages that we don't have here everything is is a trade-off guys there's no perfect solution if this matches your app it matches your requirements for your project then by all means use it if not use something else always use the right tool for the job all right so that's it for this one please do make sure to like this video and of course subscribe if you haven't and let me know in the comments if you're excited about strappy if you're actually going to build something with it and maybe if you're interacted with it what you like or what you dislike about it let me know in the comments i read every single comment even though i don't reply to everyone i do try but hey i'm only one person alright thank you for watching and i'll catch you in the next one cheers
Info
Channel: Classsed
Views: 8,110
Rating: undefined out of 5
Keywords: strapi headless cms, strapi tutorial, headless cms nodejs, best headless cms
Id: W1G33Is3SEE
Channel Id: undefined
Length: 34min 28sec (2068 seconds)
Published: Sat Feb 20 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.