0

我创建了一个 REST API,用于从数据库中获取记录,其中每一行都是关于过去在杂货店购买的信息。

在我的 main.go 文件中,我声明了一个连接到我的数据库的函数,然后创建一个可以获取所有购买的路由。

func HandleRequests() {
    port := os.Getenv("PORT")

    if len(port) == 0 {
        port = "8080"
    }
    db, err = sql.Open("mysql", "<link-to-my-MYSQL-database>")
    if err != nil {
        panic(err.Error())
    }
    defer db.Close()

    router := mux.NewRouter()

    router.HandleFunc("/purchases", getAllPurchases).Methods("GET")

    http.ListenAndServe(":"+port, router)
}

在这里,我的处理程序获取 MYSQL 模式中的所有行并将其作为 JSON 返回。

func getAllPurchases(response http.ResponseWriter, request *http.Request) {
    response.Header().Set("content-type", "application/json")
    var purchases Data

    result, err := db.Query("SELECT Timestamp,PurchaseID,CustomerID  from purchases ORDER BY Timestamp")
    if err != nil {
        panic(err.Error())
    }
    defer result.Close()
    for result.Next() {
        var purchase Purchase
        err := result.Scan(&purchase.Timestamp, &purchase.PurchaseID, &purchase.CustomerID)
        if err != nil {
            panic(err.Error())
        }
        purchases.Data = append(purchases.Data, purchase)
    }
    json.NewEncoder(response).Encode(purchases)
}

这是结构。

type Data struct {
    Data []Request `json:"data"`
}

type Purchase struct {
    Timestamp    string `json:"Timestamp"`
    PurchaseID   int `json:"PurchaseID"`
    CustomerID   int `json:"CustomerID"`
}

时间戳的格式如下:"Timestamp": "2021-01-11T16:25:52.499762+01:00",

所以这很好用,代码成功地能够返回 MySQL 表中的所有行。

我的目标是做同样的事情,但不是获取所有购买,而是创建一个端点,返回两个时间戳之间的所有行。

自然地,SQL 查询会是这样的

SELECT * from Purchases WHERE Timestamp BETWEEN TO_DATE ('2015-05-06T15:39:00', 'YYYY-MM-DD"T"HH24:MI:SS') AND TO_DATE('2015-04-06T15:39:00', 'YYYY-MM-DD"T"HH24:MI:SS');

但我对如何制作端点 url 感到困惑。它会叫什么?我的假设是

/purchases/{timestamp1}{timestamp2}

4

1 回答 1

0

不可能有一个狭隘的精确答案。

至于设计端点,许多方法都适合。
我想说你提出的方法有一个缺陷,因为它不自然地传递两个时间戳,而它们之间没有任何分隔符。

如果我要设计它,我会选择

/endpoint/{from_ts}/{untl_ts}

(即有两个路径组件),或者让端点接受查询参数:

/endpoint?from={from_ts}&to={to_ts}

您还必须在 API 文档中修复时间戳的格式。请考虑制定所需的时区规范或要求所有时间戳都采用 UTC(更好)。这将使您的解决方案永不过时。

至于实际对数据库引擎进行查询,您必须使用准备好的语句(永远不要将从用户获得的字符串嵌入到查询中,而不是Little Bobby Tables)。
基本上,这相当于在查询文本中应该使用参数的地方使用占位符,然后“准备”该查询以获得准备好的语句,然后可以执行和执行允许传递实际参数以供数据库驱动程序发送它们以用于查询的位置参数。你可以从这里开始。

还要确保在尝试使用它们之前验证时间戳,如果其中任何一个无效,则使用 400 HTTP 状态代码使请求失败。
验证是解析包含时间戳的字符串的副产品time.Time,所以我就使用它。

于 2021-02-18T09:49:33.983 回答