Skip to content

Commit

Permalink
Now with Video 2
Browse files Browse the repository at this point in the history
  • Loading branch information
jmohler1970 committed Oct 29, 2018
1 parent a586910 commit 716fced
Show file tree
Hide file tree
Showing 2 changed files with 357 additions and 1 deletion.
168 changes: 167 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,172 @@ and
TBD


Resources:
# What is Taffy and what does it have to do with ColdFusion? Hi, my name is James Mohler and I am going to talk to you today about Taffy by attuttle.

Taffy is a really easy quick way to make REST web services. These services can be consumed by just about anything.

Sometime just querying a db and returning JSON is tough. And then you factor in the fact that REST not only uses GET and POST, it also uses PUT, PATCH, and DELETE

# Let's do a quick history lession.

In the beginning..., circa 1998. Javascript existed but it was hard to use. It was hard to program. The DOM (Document Object Model) like we know it today did not exist. Netscape and Microsoft each had their own versions of Javascript. ColdFusion really helped out in this space. <cfform> was able to create all kinds of form validation That was a killer feature. You didn't have to do a form submit followed by server side validation. Much of this functionality could be pushed to the browser. You should still do server side validation, just case.

In 2003, the situation was a little better. ColdFusion had Flash Forms, which could do all kinds sophisticated client side form. The idea of the DOM was also taking hold.

In 2008, some BIG Javascript libraries came into place. I was introduced to YUI and it had all kinds of smart widgets. jQuery and jQuery UI came out around this time. And that provided the foundation for some very powerful client side functionality.

By the time you get to 2013, client side libraries are getting bigger and bigger and cover more and more functionality. Twitter Bootstrap, jQuery, and AngularJS are all big and are all covering different parts making browsers do all kinds of things.

So where does that leave us today? It leaves with having to deliver a lot JSON to some very sophisticated Javascript powered frontends. In some ways the Webserver's job similier, in other ways it is much more demanding.

#And this is where Taffy comes in

I want to get data out of my database and deliver JSON. Let's take a look at the Taffy Dashboard. The Taffy Dashboard allows us to look at all the Taffy-powered rest services on our ColdFusion server.

This particular endpoint has a single resource called statesProvinces and it responses only to a GET. This is a good starting point, let's watch it in action. It returns back an array of structs, each with four keys.

#Let's dive into some code, and see what makes this tick.

Our first file is dot .gitignore. I am hiding some directories and that I don't want to be a part of my release. When I later check in my code, these won't be a part of it.

Next we have box.json. Commandbox uses track dependencies.

The first dependency is "taffy". That is our main topic of discussion. It is going to reach out to Github and pull everything from the latest release

Next we have "formutils". I did a video a while back on that one. It allows forms to be submitted to ColdFusion as an array and struct. We won't be using it very much on the demo, but it is there anyway.

Last we have a github repository called "NorthAmerica". I have all my DB scripts in there. We will be needed them later.

The next part box.json, is the InstallPaths. It works exactly how it sounds.

OK let's move on to our next set of files.

# index.cfm and Application.cfc are now up

index.cfm is easy to talk about. It is blank. When I first saw this it reminded me a lot of how FW/1.

Now let's look at application.cfc. This is where all the work is done, so I am going to take this real slow. If you haven't already, you should download this project, so that you can follow along in your favorite text editor.

Line 2: The extends is how we are going to bring in all of the functionality into the entire application. Taffy changes how the page lifecycle work. You can't mix plain ColdFusion pages with Taffy AND you don't want to do that anyway. A Taffy REST webservice does not have to be in the root of your site. It can be off in a subdirectory

Line 4: Name is not to interesting. Just keep it unique
Line 5 and 6: We are setting up application variable support; we will not be setting up session variable support. If you think you need session variables, you are doing something wrong.

Lines 8 through 10: We are going to be powering our stuff by a database. There is no requirement that you use ColdFusion's ORM, but I like its scalability and clean code

Lines 13 and 14: These are as close to configuration as we are going to get in this file. I wouldn't change it unless there was business need to do so.

#Let's look at the rest of application.cfc#

Line 15: is a normal onApplicationStart() functionality

Line 17: brings in formutils. Formutils is a service. It has no per-request variables. So I can keep it attached to the application scope.

Line 19: This is where some Taffy magic happens.

Line 23: onTaffyRequest() is specific to the Taffy framework. Think of it like onRequestStart() on a normal page. On this presentation we won't be doing much with it. On future videos I hope to show what it is good for.

Line 25: It looks this is where formutils does its work

Let's step back a second. As a developer, what did we really have to worry about?

We have to connect to a database
We have to make sure that application wide variables are setup right. Formutils is not requirement
We have to make sure that requests in general are handled.

We just don't have to do all that much to make this work.

# Let's look at some beans and resources.

I am going to use bean, ORM, Entity all as the same thing. For purposes of this, we don't need to make any unneeded distinctions.

On the right is our Entity. ColdFusion makes this really simple

Line 1: as soon as you set persistent="true", you have got yourself an entity. ColdFusion is going to try to find a table that is similar to the name of the file. In this case, statesProvinces.cfc should be backed by dbo.stateProvinces.

Line 3: This says there is column called id, and it is a primary key.
Line 4: is a plain field
Line 5: does not allow inserts or updates. I have looked ahead in my code. This is a calculated field. If we tried to insert or update it, it would through an error
Line 6: is a plain field

ColdFusion's ORM is very powerful. When I start up this website, it will query the database to find out more about the db table that powers this cfc. This keeps me from writing select, insert, and delete statements over and over again.

# Let's look at /resources/statesProvinces.cfc

I like keeping resources with the same name as the bean. And the bean should have the same name as the backing table. All of them are plural. That is not a requirement, I just do it for my sanity.

Line 1: One of those extends again. It kind of hard to see the rest of Line 1. Let me get a better view of that.

# Hmmm. taffy_uri

taffy_uri is where the router is defined. That might seem like a strange place to put the router. But it makes a lot of sense. If a new end point is needed, all we have to do is drop a .cfc with an appropriate taffy_uri. A couple of notes here.

1. statesprovinces is in the slash resources subdirectory. I can make the slash resources have ANY kind of structure I want. I can move statesProvinces into an even deeper subdirectory and it would not make any difference.
2. Don't look in Adobe ColdFusion documentation for taffy_uri. It is not there. This is a custom attribute. All ColdFusion knows is that it is there. Taffy knows what to do with it. In our case it will define the endpoint.
3. You might have noticed that there is no output="false" anywhere. It is not needed.

Let's get back to some code

Line 3: a function called get that takes no parameters. There can only be five functions in a Taffy object, GET, POST, PUT, PATCH, and DELETE. If you create a function that does not have those names, they should probably be private.

I am going to read some lines out of order. Please bear with with

On Lines 8 and 9: I want to load all rows from the db table

##

If wanted only USA, it would look like this. The first parameter is for the bean, the second is for what is equivalent to a where clause

# Let's go back to getting all the rows

Line 10 is the sort order.

EntityLoad returns and array of objects, or an empty array if nothing matches. On line 7, I am going to use the built-in function, EntityToQuery. This will build a query based on the array of objects. Here is where a subtile bug can come in. If the EntityLoad returned an empty array, EntityToQuery will crash because it has no idea what name any potential columns.

On Line 6, we have a Taffy function called queryToArray. That seems strange. It looks almost as if we are undoing what we just did. EntityLoad returned an array. queryToArray seems like it should return an array. Isn't it the same? No it is not. EntityLoad return an array of objects. Those objects had data, member functions and anything else we ever thought of adding to the bean. queryToArray returns a very clean array of structs. It is almost exactly want we want to return.

Line 5 says return rep. rep is a Taffy function. rep is short for "RepresentationOf" and that will make the exact structure we want to return. It will be escaped, quoted and anything else we need. Every function you write should have return rep()

# We need to get this Taffy REST service going

Server.json has all the information for Commandbox to get ColdFusion running

# Let's start this

Start Commandbox by typing box

One of the beautiful things about Commandbox is I can bring up ColdFusion environment without having to do a full install.

I already have the latest version ColdFusion 2018 cached, so when I type start, it will be quick. If it takes longer for you that, is OK.

Let's type start and off we go.

Not only does Commandbox start ColdFusion, it also brings up the default page on the default browser.

...And we get a beautiful crash. Can't find taffy.core.api

# Why did we get a crash?

We started ColdFusion, but we did not get all that Github stuff. Let's stop the server

And install the stuff from github

And Start again. By the way, my starts are going slow because I have BOINC running in the background. The CPUs are about 90% right now.

Tada. Taffy Dashboard is up.

Let's run our webservice. It just crashed! What is this about?

Well there are a couple of things wrong. I haven't setup the database. Commandbox did a fresh install of ColdFusion. There are no datasources defined.

This video is already getting kind of long. So the next video is going to cover getting the database running and getting ColdFusion to use that database.

Thank you for watching

Happy Coding!


# Resources:

https://github.com/atuttle/Taffy

Expand All @@ -21,3 +186,4 @@ https://stackoverflow.com/questions/tagged/taffy

https://github.com/jmohler1970/Taffy_video


190 changes: 190 additions & 0 deletions video2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# This video picks up where the last one ended.

Let's do a quick recap of what have done done so far.

We have the Commandbox's box.json and server.json ready. We have done and install of the Github repositories We need. I can see

* Taffy
* Formutils
* And the database setup

dot gitignore is setup to ignore these external libraries.

application.cfc has everything has extends component. There is OnApplicationStart(). There is onTaffyRequest().

We have a bean called statesProvinces dot cfc that will be exposed via a Taffy resource file.

We started up our Taffy site and the Taffy Dashboard came up.

As soon as we try to run it we get an error because we did not have a database or a database connection.

Everything is just as we left it.





# Let's get our database running.

We need to use Commandbox to shutdown our website. Let's use the

docker ps -a to

find out how SQL Server is doing. It looks like it needs to be started. Let's type

Docker start sql_server_demo

And we are up. Before I used Docker, I used to run SQL Server in a Windows VM on my Mac. That would take a couple of minutes to get going. If Windows needed to install an update, and it always did, that would take a few minutes. After the update were installed, my VM software wanted to delete an old snapshot and make a new one. It could take a while before SQL Server was running. With Docker it is really fast.

# I downloaded the create scripts as a part of my demo

I can use VS Code to look at the dot .sql files. It will do the syntax highlighting and make nice icons for each of the file types, but it is difficult to run this code. Yes it could be done in the terminal, but what I really want is a full GUI take care of the DB.

#

If I were on Windows, I would be using SQL Server Management Studio; but on my Mac I am using Microsoft Azure Data Studio. Let's talk about the good things and the not so good things about Azure Data Studio.

First the good

1. It exists. It works on Windows, MacOS, and Linux. It is everywhere
2. It looks and behaves a lot like VS Code. It even has github integration which is something Managment Studio does not have
3. It shows databases in a similar format to Management Studio
4. Like VS Code, it is themeable!

The result is, it is instantly familiar to work With

Now the not so good.

1. It's name is confusing. Yes you can do Azure with it, but more importantly you can do ANY SQL server with it.
2. The icons might look like Management Studio, but as as you right click on one, it has almost none of the options.
3. Because it has almost none of the options, you have to know how to script everything OR have a Windows box handy and have it create the scripts.

The verdict?

If you would have told me five years ago that SQL Server was going to happy run on MacOS, I would never have believed you. Now I can do all my development in the environment I want. All the skills I learn apply equality to Windows too.

# Now that I have been talking about how wonderful Azure Data Studio is, let make it do something

Start it up

Connect to the Server

Let's open up the folder. It takes a second to load

Let's open up NorthAmerica dot sql

Even though I opened up the file, it still wants me to connect to a server

The run button is enabled, but let's examine this file before just running it.

The beginning part of the code is going to setup the files that the database will be using.

Line 6 and 8 have the data and log file respectively. If you come from a Windows background, those paths might look really strange. Those are the Linux paths that are inside of Docker. If you were to navigate MacOS file system, you wouldn't find these file. It is outside the scope of this presentation to go over how all that works.

# Let's go to the next section
We are making some logins. In no way are these use name and passwords setup idea. I am sure there are DBs out there that are cringing over this. This is not meant for a production system.

# Now we have our table

* ID will become our primary key. It has two characters always
* Country is 15 charactors long
* CountrySort is a calculated field. It is not persisted so it won't even take up any space
* LongName is long
* We add a default value for Country

Nothing particularly complicated. I have to admit I scripted this on a Windows VM and copy pasted it over. Now that I have this handy, I can add and edit to it as necessary

# Let's look at the next part of the create script

Wow, what is going on with 146 to 149? Data_compression = Page ?

What is that about? I am going to cover that in detail in another video. The short version of why I do this is to lower the storage requirements

Country is going to have a lot of repeated data. Way back when I was in college, they would say that this is a place where the data can be normalized and split into two tables. Namely a Countries table and a statesProvinces table.

I don't want to do all that work. So by used a compressed table, SQL Server can deal with redunancy and I can happy interact with one table rather than two.

# I don't know about you, but I am ready to run this.

# It is almost a perfect run. The error happened because I ran this earlier today, and I forgot to delete out the Login. The error basically says it can't create it because it already exists


Let's select some data. This right click does work, so I am going to be using it.

Tada!

Let's do an order by

Let's look at the fields. Things are looking good.

Hmmm. I see my two letter state/province codes. The country. The sort and the long name. Getting SQL Server for Linux to run on a Mac inside of Docker is an achievement on its own. It took me a good day to get all that running before I made this video. If it takes you a while, don't be fustrated it can be done.


# Let's get back to Taffy. I want to serve some data

Back to Commandbox.

Type in start

The default page loads and crashes... The datasource "NorthAmerica" cannot be found.

Way up on the menubar is an icon for ColdFusion. I want to go to the Administrator.

Log into the Adminstrator. BTW, the secret password is "commandbox". Make sure to change that on production systems.

Go to the data Sources

# And let's pause for a second.

Do we have to do anything special? The answer is NOOOOOO. It just works.

The datasource has been successfully created.

# Let's watch Taffy do its thing

Ladies and Gentlemen, we have successfully pulled the rabbit out of the hat.

I think I am going to leave this up on the screen for a while.

In order to get the stateprovince info on the screen, we had to do the following.

* We brought up a ColdFusion server
* That uses the Taffy REST framework to handle the request.
* The request made it to a CFC that used ORM to query a database table.
* That database table is running on SQL Server for Linux.
* SQL Server is running inside of Docker which is actually running on MacOS, not Linux
* When the data was returned from SQL Server, it was put into an array of Entities.
* Later that was converted to a query, then an array again, and finally into a JSON resentation.
* Taffy lastly made sure that the JSON was correct and that response headers were populated.


This is the foundation to build larger REST applications. Thank you for watching. If you have any questions, leave them in the comments below.


Until next time.

Happy Coding!


# Resources:

https://github.com/atuttle/Taffy

http://taffy.io/

https://stackoverflow.com/questions/tagged/taffy

https://github.com/jmohler1970/Taffy_video

VS Code

Azure Data Studio

Docker

MS SQL for Linux [sic]





0 comments on commit 716fced

Please sign in to comment.