在上一篇文章中,我们解决了分页将大型 API 响应分解为可管理的块的问题。但是,如果您曾经想让用户控制数据的排序方式或过滤特定结果,那么您就可以进行下一步:排序并且过滤。
让我们深入研究并通过添加这些功能使我们的 API 变得更加强大。
如果您尚未完成之前的教程,请点击此处。
单独分页并不总是足够的。想象一下,用户搜索最新的项目或仅搜索在特定时间范围内创建的项目。排序和过滤让用户:
- 排序: 选择结果的顺序(例如最新到最旧)
- 过滤器: 将结果缩小到他们需要的范围(例如今天创建的项目)
通过将分页与排序和过滤相结合,我们创建了一个更加用户友好的 API。
我们将基于上一篇博客中的项目表进行构建。回顾一下,这是该计划:
CREATE TABLE items ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW() );
排序就是对结果进行排序。我们将允许用户按名称或created_at列以升序或降序排序。
用户将传递两个查询参数:
示例网址:
/items?page=1&limit=10&sort=created_at&order=desc
我们将动态修改 SQL 查询以包括排序:
// Extract sort and order query parameters sort := r.URL.Query().Get("sort") order := r.URL.Query().Get("order") // Validate the sort column validSortColumns := map[string]bool{"name": true, "created_at": true} if !validSortColumns[sort] { sort = "created_at" // Default sort column } // Validate the sort order if order != "asc" && order != "desc" { order = "asc" // Default sort order } // Modify the SQL query query := fmt.Sprintf("SELECT id, name, created_at FROM items ORDER BY %s %s LIMIT OFFSET ", sort, order) rows, err := db.Query(query, limit, offset) if err != nil { http.Error(w, "Failed to fetch items", http.StatusInternalServerError) return }
过滤让用户可以优化他们的搜索。例如,我们可以按日期范围过滤项目或名称中包含特定关键字的项目。
我们将支持两个过滤器:
示例网址:
/items?page=1&limit=10&name=Item&created_after=2025-01-10 20:38:57.832777
我们将添加 WHERE 条件来处理这些过滤器:
CREATE TABLE items ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW() );
/items?page=1&limit=10&sort=created_at&order=desc
// Extract sort and order query parameters sort := r.URL.Query().Get("sort") order := r.URL.Query().Get("order") // Validate the sort column validSortColumns := map[string]bool{"name": true, "created_at": true} if !validSortColumns[sort] { sort = "created_at" // Default sort column } // Validate the sort order if order != "asc" && order != "desc" { order = "asc" // Default sort order } // Modify the SQL query query := fmt.Sprintf("SELECT id, name, created_at FROM items ORDER BY %s %s LIMIT OFFSET ", sort, order) rows, err := db.Query(query, limit, offset) if err != nil { http.Error(w, "Failed to fetch items", http.StatusInternalServerError) return }
/items?page=1&limit=10&name=Item&created_after=2025-01-10 20:38:57.832777
不验证用户输入:允许任意列或无效的排序顺序可能会使您的数据库遭受 SQL 注入。始终验证输入。
您可以在此处找到本教程的完整代码存储库
通过分页、排序和过滤,您的 API 现在更加用户友好和灵活。对于更高级的功能,请考虑添加:
请继续关注下一篇文章,我们将探索这些先进技术!
要获取有关 Golang 概念、项目等的更多信息并随时了解教程的最新动态,请在 Twitter 和 GitHub 上关注 Siddhesh。
在那之前继续学习,继续建设 ??
以上是将分页提升到新的水平:Go API 中的排序和过滤的详细内容。更多信息请关注PHP中文网其他相关文章!