Web Programming Basics

Web servers are programs which accept a HTTP Request and they respond back with a HTTP Response.The Go language has http support in it's standard library as net/http.

HTTP was built for transferring plain text, later it allowed multimedia content too. The successor of HTTP protocol is HTTP2, which is binary.

When we type www.github.com on our browser's address bar, the following things happen:

  1. Browser adds either https:// or http:// and a trailing forward slash.
  2. Our request becomes GET / github.com. (This is the HTTP Request)
  3. Browser sends out the HTTP GET request to the IP address of the github.com. Resolving the IP address of a domain name is called DNS resolution.
  4. Github's servers will process the request and send back a response to our IP address.
  5. Our browser will render the HTTP Response.

The HTTP Response contains the status code of the request. Following are the status codes defined in HTTP/1.1:

  • 1xx Informational
  • 2xx Success
  • 3xx Redirection
  • 4xx Client Error
  • 5xx Server Error

Writing a server might sound like very difficult, but it is not. To the core, a server is just like any other program you write. It takes an input, transforms it and gives an output. The input is a HTTP Request, the transformation happens when it reads data from the database and does processing over the HTTP Request, the output is the HTTP Response.

The browser just abstracts the users from sending and receiving the HTTP request/responses. Everything that a browser does can be done programmatically,

HTTP Methods

Two important parts of a HTTP Request are Methods and URL. The URL states what the user wants to do (/logout or /login or /posts), and the Method states the semantics of the request, for instance the user might be sending a Form using the POST method or the user is wanting a list of posts using the GET method.

A short list of HTTP methods: GET, POST, DELETE, PUT.

  1. GET : Used to retrieve the URL, GET / will get the home page.
  2. POST: Used to create data stored on the URL.
  3. PUT: Used to update data on the URL. PUT differs from POST in a crucial way, PUT is idempotent, if you send a PUT request twice, then it won't be duplicated. If you send a POST request twice, then it'll create two resources on the server, thus, POST creates duplicates on two exactly same requests, PUT does not.
  4. DELETE: Used to delete data in the URL.

This is going to be our server design, the Methods and URLs that we are going to support.

// Create a new category.
// POST /categories

// Update an existing category.
// PUT /categories/12

// View the details of a category.
// GET /categories/12   

// Delete an existing category.
// DELETE /categories/12

Think of categories as a document,

  1. POST to create it
  2. GET to fetch it,
  3. PUT to update it,
  4. DELETE to delete it.

Of course, instead of using the DELETE method, we can use the GET method to perform the same task sending a GET /delete/1234, but, we should send a DELETE `/tasks/1234. This comes under API design. PUT and DELETE are used when we are working with AJAX.

GET vs POST

Apart from their functional differences, GET and POST differ in security perspectives. Basically, both are insecure. There is no free lunch in security.

GET transfers data via the URL. POST sends data in the request's body or payload, but that isn't hidden or encrypted by default, but it isn't visible on the URL, it is easily accessible to anyone who knows how to read a HTTP request.

Security is something you build your application around. There isn't much difference between GET and POST when we consider security, both transfer data in plain text GET is just relatively a little less secure since URLs are logged by a proxy server/firewall/browser history and that GET requests can be done by the browser on behalf of the user without confirmation. For protecting data of the webapp, one has to stick to using HTTPS and sanitize any data that comes from the user.

Example

A blog consists of a collection of posts, a post has tags, is written by some author, at some time and has some primary key to uniquely identify it in our database and it has a slug which means the URL.

This is the era of semantic web, thus the new beautiful URLs like, someblog.com/posts/welcome-the-new-year, the slug is the welcome-the-new-year.

When the server gets a HTTP GET request of /posts/welcome-the-new-year, it'll search for URL handlers starting with the list of URL handlers we have given, then it'll find the closest match, in our case it'll be /post/, then it'll call the handler of this URL. A handler is nothing but a function we have written to process a particular URL pattern.

Our / root URL should be at the very bottom of our list. Because while executing, checks are done from top to bottom.

    // sample handler definition
    http.HandleFunc("/post/", ShowPostBySlug)
    http.HandleFunc("/", ShowAllPosts)

Handlers talk to the database, fetch the data and render templates which show up as HTML pages in our browser.

What is a template?

Templates are a way to present data to the user. The server populates the templates and sends the HTML page back to the browser. For a blog, it doesn't make sense to use a separate html page for each post. This is why there is a post template and the server will get all the details like content, title, date published and populate the post template and return it back to the browser.

A web application is basically a way of representing data stored in the database to the end user using HTTP.

Writing a web application:

  1. Understand how data flows and decide the URLs.
  2. Fix the database structure.
  3. Write templates to corresponding to each URL set.
  4. Write functions in Go to handle each URL pattern, called handlers.
  5. Handlers fetch data from the database and populate data in the templates.
Not abusing templates

The logic behind creating templates was to avoid duplication of HTML code. Templates are to be used only for the presentation logic not the business logic. Adding business logic in templates makes it very difficult to maintain the app.

Example:

We are going to build a todo list manager in this book with supports multiple users.

Wrong way: Fetch all tasks in the template and only show those of the current user. i.e. filter the tasks in the template

Correct way: Fetch only the tasks belonging to the current user. i.e. filter the tasks in the handler.

Functionality of our EditTask URL which is /edit/<id>.

file views/addViews.go

//EditTaskFunc is our handler which will handle the /edit/<id> URL
func EditTaskFunc(w http.ResponseWriter, r *http.Request) {
        //Code
        task := db.GetTaskByID(id)
        editTemplate.Execute(w, task)
        //Code
}

file db/tasks.go

func GetTaskByID(id int) types.Context {
        //Code to fetch tasks of the current user
        context := types.Context{Tasks: tasks}
        return context
}

The EditTaskFunc talks to the database with the GetTaskByID function and fetches the tasks for the current user and populates the editTemplate.

Thus we can split an application into views, database, templates and controller(main package).

Static Files

Static files are the CSS/JS/Images which we load into our html templates.

The URL which responds to static files will be /static/.

Execution:

  1. We get a request like /static/<filepath>
  2. We go to the public directory of our application and look for
  3. If we get a file of that path then we serve the file, othewise send a 404 error.

The public folder contains all your static files. We will have a templates folder on the same folder where the public is present.

The reason templates is a separate folder is that it is a separate entity and shouldn't be publicly available using the /static/ URL.

    public
    |   |-- static
    |   |   |-- css
    |   |   |   `-- styles.css
                    ..and more
    |   |   `-- js
    |   |       |-- bootstrap.min.js
    |   |       .... and more
    templates
    |   |-- completed.html
    |   |   ...and more        
Note

The above output is of the tree program.

-Previous section -Next section

results matching ""

    No results matching ""