sailsCasts

Learning about sails.js one screencast at a time.

sailsCasts Answers: Ep6 - How Does the Http Request/response Protocol Work With Routes

| Comments

Transcript

Howdy and welcome back. This episode is the first of a three part series. We’ll start with how the http request/response protocol works with routes, controllers, actions and models to deliver a restful json CRUD api. By the end of the second episode you’ll use these concepts to build a restful json CRUD api from scratch. In the third episode we’ll explore how sail’s blueprint: actions and routes can be used to create that same restful json CRUD api automatically for any of your controllers and models.

In lieu of being able to download this episode directly to your brain matrix-style, I’ll instead provide a bird’s eye view of all of the concepts we’ll cover. Nothing is more confusing than trying to learn something new in the abstract. So let’s begin with a tangible scenario for our restful json CRUD api. Our api will be used to access and update information that tracks our sleep patterns including how much we sleep each night and the quality of that sleep.

So, we want our client-side device to be able to make requests to a our api running on a server and for that api to respond to our client-side device’s requests. I’m using the term “client-side device” very loosely here because the device can reside on your lap, your phone, or even your refrigerator. If it can make a request it can use our api regardless of the type of client-side device.

So, what types of requests will we be making to the api? The request will interact with the api to either find, create, update or delete information about our sleep. The api will in turn be listening for our request and using a router, routes, controllers, and utlimately actions to interact with our sleep information in something called a model. The action will then respond to our client-side device with the status of our request and any additional information necessary to fulfill the request.

Now let’s break-down each concept in detail. First let’s strip down this diagram to the basics.

So how do request and responses work? The request and response are part of the http protocol. Don’t let the term protocol throw you. It’s just a set of agreed upon rules that make it possible for different types of devices to communicate together across a network.

So, why are we starting with the http protocol? Well, you’ve got to start somewhere and although we could have started at ohm’s law and worked our way up levels of abstraction to http, this would take an awfully long time and more importantly my knowledge once we go below the level of http drops rapidly to pretty much zero. As a tangent, in case you are a complete nerd like myself and would like to learn more about the very low levels of abstraction, there’s a great MIT course 6.002 available on youtube which introduces the fundamentals of the lumped circuit abstraction. But for our purposes anything below the http protocol we’ll just say consists of turtles all the way down.

Recall that our api will support requests to find, create, update, or delete sleep information.

But how will our api differentiate the requests? That is, how will the api know that we want to find versus create, update versus delete a set of sleep information?

The http protocol provides the means to accomplish this via the use of http verbs – get, post, put, and delete and each of the http verbs line up with the type of request.

Most likely you use http verbs every day. Each time you use your browser to open a web page, that browser is making a get request on your behalf.

As a quick aside you’ll often hear the term CRUD functions when working with a web api. CRUD stands for create, read, update and delete each of which match up nicely to our http verbs and actions.

The verb is the first of three essential parts of our request. The other elements are the path, which relates to our controller, and we’ll talk about in the next session and finally optional parameters which are just additional pieces of information we might want to send in our request.

The important take away here is we can now combine http verbs and paths to convey our intent to the api. By using 'post /sleep' the api knows ahh, create a new instance of sleep and by passing it parameters the api knows that we want to use those parameters as part of the sleep instance. How the api interprets this is the subject of the next section.

Before moving on though, you might be asking, how does my device generate a request. I’ve already said that when you request a web page in a browser you’re making a get request. Also most programming languages have a library associated with http. In javascript, the jquery library uses $.get to make requests.

Let’s take a quick field trip to check out a request in action.

I’ll open a chrome browser which is using a chrome extension called POSTMAN. POSTMAN allows me to make http requests using all of the verbs we were just talking about. Without it, browsers are limited to get requests from the url window or get and post requests from an html form. I’m making the request to a completed version of our sails api, but don’t worry about that for now. I just want to show you an actual request in action.

So I’m going to make a request using the verb get to the path /sleep. And when I send the request via POSTMAN I get back all 5 instances of our model.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[
    {
        "hours_slept": "12",
        "sleep_quality": "great",
        "createdAt": "2014-01-03T00:29:55.921Z",
        "updatedAt": "2014-01-03T00:29:55.921Z",
        "id": 1
    },
    {
        "hours_slept": "8",
        "sleep_quality": "good",
        "createdAt": "2014-01-03T00:30:03.544Z",
        "updatedAt": "2014-01-03T00:30:03.544Z",
        "id": 2
    },
    {
        "hours_slept": "6",
        "sleep_quality": "so-so",
        "createdAt": "2014-01-03T00:30:13.998Z",
        "updatedAt": "2014-01-03T00:30:13.998Z",
        "id": 3
    },
    {
        "hours_slept": "5",
        "sleep_quality": "bad",
        "createdAt": "2014-01-03T00:30:21.294Z",
        "updatedAt": "2014-01-03T00:30:21.294Z",
        "id": 4
    },
    {
        "hours_slept": "3",
        "sleep_quality": "bad",
        "createdAt": "2014-01-03T00:30:25.998Z",
        "updatedAt": "2014-01-03T00:30:25.998Z",
        "id": 5
    }
]

So that’s it, that’s a request.

Now, by making the http request to a server, we’re indicating that some bit of code should be executed on the server as a result of making the request. The chunk of code that is executed is known as an action and these actions can be grouped together into a controller.

But how do we link the request to the controller and action? Well, that’s where routes come in.

Routes are the instructions that tie the request to the controller and ultimately to the action.

So from our earlier example, the route consists of the verb— post, the path— /sleep which forms the request and pairs it with the sleep controller and the create action.

Although not part of the route per se, as we’ve already seen parameters can also be part of the request and these parameters can pass information to the action.

So let’s review, we now understand how the request and response works with the http protocol, that the router uses routes to tie the requests to the controller and action.

So what does the action actually do? The action is where the code resides to find one or more model instances, create a new model instance, update an existing model instance, or delete a model instance.

What is a model? A model is a representation of the attributes that describe the data your api will be managing. Our sleep model consists of hours_slept, and sleep_quality and sails automatically adds an id, createdAt and updatedAt attributes. The sleep model is an object so in addition to model attributes like hours_slept, the sleep model also has methods like find, create, update, and destroy. These are the methods that are called within our actions. Now don’t be confused by the fact that the actions and model methods have the same name, they share the same name because the action name relates to the ultimate model method the action will use. As you’ll see when building the api in the next episode, the actions combine code necessary to complete the request including calls to the model methods.

Having this seperation between the model and the place where your data resides is important because you might want to store your model in a sql database at first but later move it to a mongo database. Or you might be using data that doesn’t come from a database but instead from some other api. That’s really the power of a framework like sails in that we can learn one way of finding, creating, updating and destroying our model, and then let sails worry about how it actually accesses and/or stores it at the level of a database or other data source. In fact, the sails community provides us with different adapters like posgresql and mongo from which we can pick and choose where our data ultimately resides at will.

What is the model versus model instances. Think of the model as the instructions for building something whereas an instance of that model is one of the things you’ve built.

So let’s finish this episode with looking at the response. Depending upon the request, our action is responsible for finding, creating, updating or deleting instances of our model. We’ve learned that the model methods are called by the action. The action then responds to the request with the status of the request along with any model instance or instances associated with the action.

If you’re new to this your head might start to spin a bit but don’t panic in the next episode we’ll use all of this conceptual knowledge to build our own restful json CRUD api.

if you get a chance, follow me on twitter @irlnathan and as always thanks for watching.

Comments