اعتبارسنجی پارامترهای رشته کوئری
به لطف تابع کمکی readInt() که در فصل قبل ایجاد کردیم، API ما در حال حاضر باید خطاهای اعتبارسنجی را اگر پارامترهای رشته کوئری page و page_size شامل مقادیر عدد صحیح نباشند، برگرداند. اگر مایلید آن را امتحان کنید:
$ curl "localhost:4000/v1/movies?page=abc&page_size=abc"
{
"error": {
"page": "must be an integer value",
"page_size": "must be an integer value"
}
}
اما هنوز باید برخی بررسیهای اضافی انجام دهیم تا مطمئن شویم مقادیر رشته کوئری که توسط کلاینت ارائه شدهاند، منطقی هستند. به طور خاص، میخواهیم بررسی کنیم که:
- مقدار
pageبین ۱ و ۱۰,۰۰۰,۰۰۰ باشد. - مقدار
page_sizeبین ۱ و ۱۰۰ باشد. - پارامتر
sortشامل یک مقدار شناختهشده و پشتیبانیشده برای جدول فیلمهای ما باشد. به طور خاص، مقادیر"id"،"title"،"year"،"runtime"،"-id"،"-title"،"-year"یا"-runtime"مجاز خواهند بود.
برای رفع این مشکل، بیایید فایل internal/data/filters.go را باز کرده و یک تابع جدید ValidateFilters() ایجاد کنیم که این بررسیها را روی مقادیر انجام میدهد.
ما از همان الگویی که برای تابع ValidateMovie() در ابتدای کار استفاده کردیم، پیروی خواهیم کرد، به این صورت:
package data import ( "greenlight.alexedwards.net/internal/validator" // New import ) // Add a SortSafelist field to hold the supported sort values. type Filters struct { Page int PageSize int Sort string SortSafelist []string } func ValidateFilters(v *validator.Validator, f Filters) { // Check that the page and page_size parameters contain sensible values. v.Check(f.Page > 0, "page", "must be greater than zero") v.Check(f.Page <= 10_000_000, "page", "must be a maximum of 10 million") v.Check(f.PageSize > 0, "page_size", "must be greater than zero") v.Check(f.PageSize <= 100, "page_size", "must be a maximum of 100") // Check that the sort parameter matches a value in the safelist. v.Check(validator.PermittedValue(f.Sort, f.SortSafelist...), "sort", "invalid sort value") }
سپس باید listMoviesHandler خود را به روز کنیم تا مقادیر پشتیبانیشده را در فیلد SortSafelist تنظیم کند و سپس این تابع جدید ValidateFilters() را فراخوانی کنیم.
package main ... func (app *application) listMoviesHandler(w http.ResponseWriter, r *http.Request) { var input struct { Title string Genres []string data.Filters } v := validator.New() qs := r.URL.Query() input.Title = app.readString(qs, "title", "") input.Genres = app.readCSV(qs, "genres", []string{}) input.Filters.Page = app.readInt(qs, "page", 1, v) input.Filters.PageSize = app.readInt(qs, "page_size", 20, v) input.Filters.Sort = app.readString(qs, "sort", "id") // Add the supported sort values for this endpoint to the sort safelist. input.Filters.SortSafelist = []string{"id", "title", "year", "runtime", "-id", "-title", "-year", "-runtime"} // Execute the validation checks on the Filters struct and send a response // containing the errors if necessary. if data.ValidateFilters(v, input.Filters); !v.Valid() { app.failedValidationResponse(w, r, v.Errors) return } fmt.Fprintf(w, "%+v\n", input) }
اگر API را مجدداً راهاندازی کنید و درخواستی با پارامترهای نامعتبر page، page_size و sort ارسال کنید، اکنون باید پاسخ خطا حاوی پیامهای عدم اعتبار مربوطه دریافت کنید. مانند زیر:
$ curl "localhost:4000/v1/movies?page=-1&page_size=-1&sort=foo"
{
"error": {
"page": "must be greater than zero",
"page_size": "must be greater than zero",
"sort": "invalid sort value"
}
}
اگر مایلید، میتوانید آزمایش را بیشتر انجام دهید و مقادیر مختلف رشته کوئری را تا زمانی که مطمئن شوید بررسیهای اعتبارسنجی همگی به درستی کار میکنند، امتحان کنید.