Introduction to Response Codes
Something we also need to know about HTTP is the response code. This is a representation of the response code, where from this code we can see whether a request we sent from the client was successfully processed by the server or failed to be processed by the server. So there are lots of response codes that we can use when creating a website. You can immediately look in more depth at several HTTP Status Codes here https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
There are 5 groups of HTTP Response Status Codes which are explained in the link above, namely:
- Informational response (100 - 199): usually this is used to inform the response of the status. This is rarely used.
- Successful responses (200 - 299) are used for successful responses
- Redirects (300 - 399): used to redirect to a specific URL
- Client errors (400 - 499): used to inform that there are several incorrect params or requests
- Server errors (500 - 599): used to inform that there is a problem with the server process
By default, if we don’t set a response code, it will output code 200, which means success. If we want to change it, we can use the ResponseWriter.WriteHeader(int)
function to provide response code information. All status code data has also been provided by Golang, so if we want to use it we just need to call the variables provided in Golang here https://github.com/golang/go/blob/master/src/net/http/status.go .
Implementation
Now we will try to change the response code returned from our system like the code below.
func ResponseCodeHandler(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
if name == "" {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, "name is empty")
} else {
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "Hello %s", name)
}
}
Next, we will test the function that we have created above by adding a unit test so that we know whether the logic process we created is correct or not.
func TestResponseCodeHandler(t *testing.T) {
type args struct {
name string
}
tests := []struct {
name string
args args
wantResp string
wantCode int
}{
{
name: "sent param name with value",
args: args{
name: "ihsan",
},
wantResp: "Hello ihsan",
wantCode: http.StatusOK,
},
{
name: "does't sent param name",
args: args{
name: "",
},
wantResp: "name is empty",
wantCode: http.StatusBadRequest,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost/say?name=%s", tt.args.name), nil)
recorder := httptest.NewRecorder()
ResponseCodeHandler(recorder, request)
response := recorder.Result()
body, _ := io.ReadAll(response.Body)
bodyString := string(body)
code := response.StatusCode
if !reflect.DeepEqual(bodyString, tt.wantResp) {
t.Errorf("response = %v, want %v", bodyString, tt.wantResp)
}
if !reflect.DeepEqual(code, tt.wantCode) {
t.Errorf("code = %v, want %v", code, tt.wantCode)
}
})
}
}