# Learning to Go: Part 4 - The Search Handler

*Oh hi! This is a multi-part tutorial series, please make sure you reads the posts in order! You can find the list at the bottom of the page.*

Now we’ve got a basic page up and running, in this step we’ll add the Search handler, which will actually deal with requests for searches.

First we’ll need to add `fmt` and `net/url` to our imports section:

```go
import (
    "fmt"
    "html/template"
    "net/http"
    "net/url"
)
```

Next we’ll write our `searchHandler` function. First let’s add the skeleton of the function to `main.go`. You can add this after the `indexHandler` function.

```go
func searchHandler(w http.ResponseWriter, r *http.Request) {
}
```

Just like our `indexHandler`, we define our function with its name and the inputs it will accept. Next, add the following code inside the function:

```go
u, err := url.Parse(r.URL.String())
if err != nil {
	w.WriteHeader(http.StatusInternalServerError)
	w.Write([]byte("Internal server error"))
	return
}
```

The first thing we do here is create a variable called `u` and assign to it the output of this function call: `url.Parse(r.URL.String())`. But what does that do?

Remember that `r` is passed into our function as a pointer to the `http.Request`. So that gives us lots of information about the request itself, and in this case we’re accessing the full URL of the request. We’re also using `Parse` which breaks it down into easier variables for us to access.

If you’ve looked in `index.html` you may have noticed that our search form uses the GET method. This means that our search parameters simply become part of the URL of the request. As they are part of the URL, we can access the search terms just by reading the URL.

But you may have also noticed that we don’t just assign `u` here, we also assign another variable called `err`. Then we immediately check to see if `err` is not `nil`, in which case we write out an internal server error, and quit.

This is a common programming pattern in Go for exception handling. If everything goes according to plan, we have our URL in the `u` variable. But if something bad happens, `err` will not be empty, or `nil`, and we can handle it gracefully.

Next, let’s move on to what we do with `u`:

```go
params := u.Query()
searchKey := params.Get("q")
```

First we grab the parameters of the search by using the `Query()` function on `u`. This function grabs all of the parameters that are part of the URL path, without the website address. We can then access the parameters individually, which we do to get the `searchKey`.

Again, going back to our `index.html`, you’ll see that the text of our search is sent as the value of `q`. So we grab that paramater and assign to it `searchKey`. For now, rather than rendering any different HTML output, we’ll just ouput the value of `searchKey` to the console using `fmt.Println`:

```go
fmt.Println("Search Query is: ", searchKey)
```

You’ll see the output come up in your terminal when you run the the program. That’s all the code we need for our `searchHandler` function.

The last thing to do is add our new `searchHandler` to our HTTP `mux` server. Add this before the `HandleFunc` line for `indexHandler`:

```go
mux.HandleFunc("/search", searchHandler)
```

Now let’s test our search function:

```bash
go run main.go
```

Enter some search terms at [http://localhost:8080](http://localhost:8080/) and observe them in the URL path in your browser. You’ll see a blank web page, but you should see your search terms in your terminal:

```bash
$ go run main.go
Search Query is: enterprise
```

Nicely done! We’ve added a new handler and learnt how to process parameters from an HTTP GET request. Now move on to part 5, where we’ll actually do something with that request.

Here’s the complete code of `main.go` if you need to check yours for errors:

```go
package main

import (
    "fmt"
    "html/template"
    "net/http"
    "net/url"
)

var tpl = template.Must(template.ParseFiles("index.html"))

func indexHandler(w http.ResponseWriter, r *http.Request) {
    tpl.Execute(w, nil)
}

func searchHandler(w http.ResponseWriter, r *http.Request) {
    u, err := url.Parse(r.URL.String())
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        w.Write([]byte("Internal server error"))
        return
    }
    params := u.Query()
    searchKey := params.Get("q")
    fmt.Println("Search Query is: ", searchKey)
}

func main() {
    mux := http.NewServeMux()
    fs := http.FileServer(http.Dir("assets"))
    mux.Handle("/assets/", http.StripPrefix("/assets/", fs))
    mux.HandleFunc("/search", searchHandler)
    mux.HandleFunc("/", indexHandler)
    http.ListenAndServe(":8080", mux)
}
```
