5.7 کتابخانه http سمت سرور پیشرفته

5.7 کتابخانه http سمت سرور پیشرفته

در قسمت قبل با استفاده از کتابخانه net/http یک api ساده ایجاد کردیم.

در این قسمت به پیاده سازی یک سرور http برای مدیریت لیست TODO های خود میپردازیم و از چهار متد GET, POST, DELET and PATCH استفاده میکنیم.

در این پروژه از دیتابیس استفاده نمیشود. روش ذخیره سازی اطلاعات درون متغییر هاست دلیل استفاده نکردن از یک دیتابیس تمرکز این قسمت روی کتابخانه و پروتکل http است.

در ادامه به ایجاد سرور خود میپردازیم.

 1package main
 2
 3import (
 4	"encoding/json"
 5	"fmt"
 6  "log"
 7	"net/http"
 8)
 9
10// todo struct  with json tags
11type Todo struct {
12	ID     int    `json:"id"`
13	Title  string `json:"title"`
14	Status bool   `json:"status"`
15}
16
17// just work as a DB for us!
18var todos []Todo
19
20// get all the items in the Todo list and write it. GET
21func getTodos(w http.ResponseWriter, r *http.Request) {
22	w.Header().Set("Content-Type", "application/json")
23	json.NewEncoder(w).Encode(todos)
24}
25
26// append a new data in array. POST
27func addTodo(w http.ResponseWriter, r *http.Request) {
28	w.Header().Set("Content-Type", "application/json")
29
30	var todo Todo
31	json.NewDecoder(r.Body).Decode(&todo)
32
33 // NOTE: this isn't a good way to set ids in production!
34	todo.ID = len(todos) + 1
35	todos = append(todos, todo)
36
37	json.NewEncoder(w).Encode(todo)
38}
39
40// change the todo status. PATCH
41func updateTodo(w http.ResponseWriter, r *http.Request) {
42	w.Header().Set("Content-Type", "application/json")
43
44	var todo Todo
45	json.NewDecoder(r.Body).Decode(&todo)
46
47	for i, t := range todos {
48		if t.ID == todo.ID {
49			todos[i].Status = todo.Status
50			json.NewEncoder(w).Encode(todos[i])
51			return
52		}
53	}
54
55	w.WriteHeader(http.StatusNotFound)
56	json.NewEncoder(w).Encode(map[string]string{"message": "TODO not found"})
57}
58
59// remove the TODO from array. DELETE
60func deleteTodo(w http.ResponseWriter, r *http.Request) {
61	w.Header().Set("Content-Type", "application/json")
62
63	var todo Todo
64	json.NewDecoder(r.Body).Decode(&todo)
65
66	for i, t := range todos {
67		if t.ID == todo.ID {
68			todos = append(todos[:i], todos[i+1:]...)
69			json.NewEncoder(w).Encode(map[string]string{"message": "TODO deleted"})
70			return
71		}
72	}
73
74	w.WriteHeader(http.StatusNotFound)
75	json.NewEncoder(w).Encode(map[string]string{"message": "TODO not found"})
76}
77
78
79func main() {
80  // set routes
81	http.HandleFunc("/todos", getTodos)
82	http.HandleFunc("/todos/add", addTodo)
83	http.HandleFunc("/todos/update", updateTodo)
84	http.HandleFunc("/todos/delete", deleteTodo)
85
86  // start server
87	fmt.Println("Server starting at port 8080")
88	log.Fatal(http.ListenAndServe(":8080", nil))
89}

بعد از اتمام نوشتن سرور با استفاده از یک کلاینت http مثل postman سرور خود را به روش زیر تست میکنیم:

نکته: شما می توانید کلاینت خود را خودتان با استفاده از اموزش کلاینت http در قسمت های دیگر بنویسید!

add todo #

endpoint: localhost:8080/todos/add

method:POST

request:

1{
2    "title":"todo1 test"
3}

response:

1{
2    "id": 1,
3    "title": "todo1 test",
4    "status": false
5}

get todo’s #

endpoint: localhost:8080/todos

method:GET

request:

response:

1[
2    {
3        "id": 1,
4        "title": "todo1 test",
5        "status": false
6    },
7  //...
8]

update todo #

endpoint: localhost:8080/todos/update

method:PATCH

request:

1{
2    "id":1,
3    "status":true
4}

response:

1{
2    "id": 1,
3    "title": "todo1 test",
4    "status": true
5}

delete todo #

endpoint: localhost:8080/todos/delete

method:DELETE

request:

1{
2    "id":1
3}

response:

1{
2    "message": "TODO deleted"
3}