diff --git a/README.md b/README.md index f280efb..83ba5fa 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,183 @@ This is the second set of code, but it is the third video. Sorry for the confusi The main goal of this Repository is to build upon the previous. I want a much more flexible kind of resource. +# What is Taffy? + +It is a quick and easy way to make REST resources in ColdFusion. + +In our previous videos, we already setup + +dot gitignore +box.json +server.json +and application.cfc + +Are all present and accounted for. There is not anything new going on with these. + +## Let's talk about some new stuff. + +Previously, We had only one endpoint. And that was slash statesandprovinces. For this video I have renamed it to slash statesprovinces. +We didn't need the and. + +# This one is going to have many more endpoints. Lets take a looks + +We have slash statesprovinces. That hasn't changed. It just has GET + +We have slash users and slash users slash id + +Slash users has GET and PUT + +Slash users slash id (or User ID for short) has GET, POST, and DELETE + +Without even looking at the code, I have an idea as to what these are supposed to do. + +Slash users GET should return a list of all users +Slash users PUT should add a users +Slash users slash id GET should return one user +Slash users slash id POST should return update one user +Slash users slash id DELETE should delete one user + +I supposet if slash users had DELETE, that would empty the entire database table. + +# Let's take a look at the beans + +StateProvinces.cfc has not changed, so lets not spend too much time on that. + +## beans/Users.cfc is new + +Line 1: persistent is true, so that tells me it will be a Entity. It also tells me that the database better have a table called dbo.Users + +Line 3: property name="id" and fieldtype="id" OK so it is the primary key. generator equals identity. This means that ORM is expecting the SQL Server will create a number everytime a new Entity is saved. + +Line 5: This is where ORM becomes very different databases. When I pull this Entity, one of its attributes will be another Entity inside of it. It is not going to be returning a foreign key or anything like that. When we have to interact with this Entity, you will see how how it is a little bit different. + +Firstname, lastname, email seem straight forward. + +On line 11: Deleted is a flag. I have worked for a lot of big companies over the years. We don't like deleting data. If you just flag it as deleted, you can recover it later. Just in case. + + +## Moving on to slash resource slash users slash users dot cfc + +Line 1: This is a Taffy resource object. It responds to requests to slash users. The fact that this file is in a subdirectory off of resources does not impact the REST path + + +Line 3: tells me that this is a GET + +Line 5: Give me an array of all User Entitys. Don't filter. Order by id + +Starting at Line 8 or so, I am going to be working this data very differently from how I did stateprovinces. First off, when this system starts, there will be zero users. I don't want my code to crash with zero users. + +More importantly, on line 14, I need to some extra work to get the Stateprovinceid. I cannot just pick it off. I need to do an extra step. If I were to do a `` of User dot getStateProvince(), I would see that it is an Entity. I got to make a function call even deeper to get to its ID field. + +In short, I have to build this result array piece by piece. + +As an aside, there are many reasons you may have to do it this way. What if you don't want to return all the fields from the Entity? What if your Entity does some of its own calculations. You may find that this is the most common approach to building your results. + + + +## Let's look at the PUT function + +Lines 21 through 26: are going to setup the expected parameters. Taffy will look at these and expose them. + +Lines 28 through 32: are for error checking. If you pick an invalid StateProvince, Taffy will return a noData(). noData() is function that is built into Taffy and can come in useful for when nothing needs to be returned. This is different from a blank string or any empty array or struct. Nothing is coming back. + +Line 35: Is where I am goint to create an Entity. By the way, EntityNew() does NOT create row in the database. It has to be saved in order for it to stay. + +Line 39: Is interesting. I am not saving data. I am saving an entire Entity. The very same Entity I found on line 28 + +Moving onto Line 41. The data is now going to get committed to the DB. I hope it passes all the validation rules, or else it with through an error. If, for example, firstname is too long, that can cause the save to fail. There are all kinds of ways to make this more robust. + +Line 42: is interesting. The short story is that it should not be there. If you are using my code as an example, you should comment out this line. + +Let me give the long story on why it is bad. When you are using Entities, you could find yourself using lots and lots of them. When you call EntitySave, Coldfusion will actually put this into a queue to be saved. At the end of the request, it is going to update the database with everything. You could have Insert, Updates, and Deletes all over the place. ColdFusion keeps track of their states. You don't want to pick on the database with all these small requests. ORM takes care of them as a single unit. There is a lot more to talk about on this. I hope to cover that in a future video. + + +So what does ORMFlush() do? It tells ColdFusion to NOT wait until the end of the request. It tells ColdFusion to commit all changes now. This will slow things down. For a single record INSERT, you probably won't notice. But if you dealing with a lot of changes, you almost certainly want to avoid ORMFlush(). Always! + +I don't want to get too far off topic, but here is a reason to use ORMFlush(). If you code base has mixture of traditional SQL queries and Entities, you need to make sure your DB is in a consistent state. I hope to show some examples of this in a future video. + + +### Back to our code. + +Line 44: We are returning a nice struct with a message. Hopefully all this added a User and things will be looking good. + +# Let's move on to users_id.cfc + +I don't really have too much to say on its GET function. + +Line 5: EntityLoadByPK() is different from EntityLoad(). EntityLoadByPK() always return a single Entity. Whereas EntityLoad() by default returns an array. When you have a choice, use EntityLoadByPK(). + +Otherwise GET a single User is just a simpler version of get All Users + +## Let's look at POST + +It is similar to User PUT + +We have to do some error checking to make sure we can load the User before even attempting to save any changes. Once again we return a noData() if we can't find the User. + +Line 34 to 38: is the same StateProvince checking we had before + +Line 40 to 46: We will be doing a proper EntitySave. No ORMFlush in sight. + +Line 49: We are returning a success message. withStatus(201) ? What is that? Taffy allows us to return almost any HTTP status we want. I will leave it up to the viewers of this video to decide if status 201 is appropriate. + + +## Our last HTTP Verb is DELETE. This should be good. + +This isn't too strange. We have seen variations of this kind of code in all the examples. + +On line 64 we are flagging as deleted as opposed to really deleting it. + +# Load database + +Load up the database. I am going to be using a different create script. I am going to be using User.sql. It has Stateprovinces built into it too. + + +# Start up ColdFusion + +- Checking Docker (docker ps -a) +- Start CommandBox, wait for default page to show up +- In CommandBox, make sure veryting is installed +- Start + +- Check out statesprovinces + +- list all users + +- add user + +- add user incorrectly. Lets put in some bad data. + + + +- list all users + +- list single user + +- add user + + + +- update user + +- list single user + +- list all users + + +- add user + +- delete user + +- list single user + + +- list all users + +# Thank you for watching + + + Resources: https://github.com/atuttle/Taffy diff --git a/box.json b/box.json index d676145..842f11e 100644 --- a/box.json +++ b/box.json @@ -7,6 +7,6 @@ "installPaths":{ "taffy":"taffy/", "formutils":"formutils/", - "northamerica":"db_setup" + "northamerica":"db_setup/" } } \ No newline at end of file diff --git a/resources/statesProvinces.cfc b/resources/statesProvinces.cfc index a762d79..4237eff 100644 --- a/resources/statesProvinces.cfc +++ b/resources/statesProvinces.cfc @@ -3,7 +3,7 @@ component extends="taffy.core.resource" taffy_uri="/statesprovinces" { function get(){ return rep(queryToArray( - EntityToQuery(EntityLoad("StatesProvinces", { Country = 'USA' }, "CountrySort, LongName")) + EntityToQuery(EntityLoad("StatesProvinces", {}, "CountrySort, LongName")) )); } diff --git a/video3.md b/video3.md deleted file mode 100644 index 2634cd7..0000000 --- a/video3.md +++ /dev/null @@ -1,176 +0,0 @@ - -# What is Taffy? - -It is a quick and easy way to make REST resources in ColdFusion. - -In our previous videos, we already setup - -dot gitignore -box.json -server.json -and application.cfc - -Are all present and accounted for. There is not anything new going on with these. - -## Let's talk about some new stuff. - -Previously, We had only one endpoint. And that was slash statesandprovinces. For this video I have renamed it to slash statesprovinces. -We didn't need the and. - -# This one is going to have many more endpoints. Lets take a looks - -We have slash statesprovinces. That hasn't changed. It just has GET - -We have slash users and slash users slash id - -Slash users has GET and PUT - -Slash users slash id (or User ID for short) has GET, POST, and DELETE - -Without even looking at the code, I have an idea as to what these are supposed to do. - -Slash users GET should return a list of all users -Slash users PUT should add a users -Slash users slash id GET should return one user -Slash users slash id POST should return update one user -Slash users slash id DELETE should delete one user - -I supposet if slash users had DELETE, that would empty the entire database table. - -# Let's take a look at the beans - -StateProvinces.cfc has not changed, so lets not spend too much time on that. - -## Users.cfc is new - -Line 1: persistent is true, so that tells me it will be a bean. It also tells me that the database better have a table called dbo.Users - -Line 3: property name="id" and fieldtype="id" OK so it is the primary key. generator equals identity. This means that ORM is expecting the SQL Server will create a number everytime a new Entity is saved. - -Line 5: This is where ORM becomes very different databases. When I pull this Entity, one of its attributes will be another Entity inside of it. It is not going to be returning a foreign key or anything like that. When we have to interact with this Entity, you will see how how it is a little bit different. - -Firstname, lastname, email seem straight forward. - -On line 11: Deleted is a flag. I have worked for a lot of big companies over the years. We don't like deleting data. If you just flag it as deleted, you can recover it later. Just in case. - - -## Moving on to slash resource slash users slash users dot cfc - -Line 1: This is a Taffy resource object. It responds to requests to slash users. The fact that this file is in a subdirectory off of resources does not impact the REST path - - -Line 3: tells me that this is a GET - -Line 5: Give me an array of all User Entitys. Don't filter. Order by id - -Starting at Line 8 or so, I am going to be working this data very differently from how I did stateprovinces. First off, when this system starts, there will be zero users. I don't want my code to crash with zero users. - -More importantly, on line 14, I need to some extra work to get the Stateprovinceid. I cannot just pick it off. I need to do an extra step. If I were to do a of User dot getStateProvince(), I would see that it is an Entity. I got to make a function call even deeper to get to its ID field. - -In short, I have to build this result array piece by piece. - -As an aside, there are many reasons you may have to do it this way. What if you don't want to return all the fields from the Entity? What if your Entity does some of its own calculations. You may find that this is the most common approach to building your results. - - - -## Let's look at the PUT function - -Lines 21 through 26: are going to setup the expected parameters. Taffy will look at these and expose them. - -Lines 28 through 32: are for error checking. If you pick an invalid StateProvince, Taffy will return a noData(). noData() is function that is built into Taffy and can come in useful for when nothing needs to be returned. This is different from a blank string or any empty array or struct. Nothing is coming back. - -Line 35: Is where I am goint to create an Entity. By the way, EntityNew() does NOT create row in the database. It has to be saved in order for it to stay. - -Line 39: Is interesting. I am not saving data. I am saving an entire Entity. The very same Entity I found on line 28 - -Moving onto Line 41. The data is now going to get committed to the DB. I hope it passes all the validation rules, or else it with through an error. If, for example, firstname is too long, that can cause the save to fail. There are all kinds of ways to make this more robust. - -Line 42: is interesting. The short story is that it should not be there. If you are using my code as an example, you should comment out this line. - -Let me give the long story on why it is bad. When you are using Entities, you could find yourself using lots and lots of them. When you call EntitySave, Coldfusion will actually put this into a queue to be saved. At the end of the request, it is going to update the database with everything. You could have Insert, Updates, and Deletes all over the place. ColdFusion keeps track of their states. You don't want to pick on the database with all these small requests. ORM takes care of them as a single unit. There is a lot more to talk about on this. I hope to cover that in a future video. - - -So what does ORMFlush() do? It tells ColdFusion to NOT wait until the end of the request. It tells ColdFusion to commit all changes now. This will slow things down. For a single record INSERT, you probably won't notice. But if you dealing with a lot of changes, you almost certainly want to avoid ORMFlush(). Always! - -I don't want to get too far off topic, but here is a reason to use ORMFlush(). If you code base has mixture of traditional SQL queries and Entities, you need to make sure your DB is in a consistent state. I hope to show some examples of this in a future video. - - -### Back to our code. - -Line 44: We are returning a nice struct with a message. Hopefully all this added a User and things will be looking good. - -# Let's move on to users_id.cfc - -I don't really have too much to say on its GET function. - -Line 5: EntityLoadByPK() is different from EntityLoad(). EntityLoadByPK() always return a single Entity. Whereas EntityLoad() by default returns an array. When you have a choice, use EntityLoadByPK(). - -Otherwise GET a single User is just a simpler version of get All Users - -## Let's look at POST - -It is similar to User PUT - -We have to do some error checking to make sure we can load the User before even attempting to save any changes. Once again we return a noData() if we can't find the User. - -Line 34 to 38: is the same StateProvince checking we had before - -Line 40 to 46: We will be doing a proper EntitySave. No ORMFlush in sight. - -Line 49: We are returning a success message. withStatus(201) ? What is that? Taffy allows us to return almost any HTTP status we want. I will leave it up to the viewers of this video to decide if status 201 is appropriate. - - -## Our last HTTP Verb is DELETE. This should be good. - -This isn't too strange. We have seen variations of this kind of code in all the examples. - -On line 64 we are flagging as deleted as opposed to really deleting it. - -# Load database - -Load up the database. I am going to be using a different create script. I am going to be using User.sql. It has Stateprovinces built into it too. - - -# Start up ColdFusion - -- Checking Docker - -- Check out statesprovinces - -- list all users - -- add user - -- add user incorrectly. Lets put in some bad data. - - - -- list all users - -- list single user - -- add user - - - -- update user - -- list single user - -- list all users - - -- add user - -- delete user - -- list single user - - -- list all users - -# Thank you for watching - - - -