programming

06 How to Used Response Code in Golang

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:

  1. Informational response (100 - 199): usually this is used to inform the response of the status. This is rarely used.
  2. Successful responses (200 - 299) are used for successful responses
  3. Redirects (300 - 399): used to redirect to a specific URL
  4. Client errors (400 - 499): used to inform that there are several incorrect params or requests
  5. 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)
			}
		})
	}
}
comments powered by Disqus