Форк vweb с моделированием и проверкой данных.
Это доказательство концепции.
mkdir modules
cd modules
git clone https://github.com/intangere/tea.git
Вероятно, применимо все обычное использование Vweb.
Это всего лишь тонкая оболочка поверх Vweb, которая предоставляет достаточно возможностей для изменения сигнатур маршрутов.
В example.v есть множество примеров.
Простой полный пример выглядит следующим образом:
Давайте создадим маршрут /login
, который принимает модель пользователя.
Сначала импортируйте чай и объявите переменную вашего приложения как таковую:
import tea
struct App {
tea . Context
pub mut:
validators tea . Validators < App >
}
Определите свою модель user
:
struct User {
username string
password string
}
Определите функцию для проверки правильности модели user
:
fn ( user User ) is_valid () bool {
username := user . username . strip_margin ()
password := user . password . strip_margin ()
return username . len > 3 &&
password . len > 8
}
Определите свой маршрут /login
:
['/ login '; post ]
fn ( mut app App ) login ( user User ) tea. Result {
// posted user parameters will be available in user after being validated
println ('U sername : ' + user . username + ' Password : ' + user . password )
app . json ('{" status ":" testing "}')
}
Определите свою основную функцию:
fn main () {
mut app := App {}
}
Теперь в этой основной функции вы можете создать свой валидатор user
данных.
(Вы также можете определить это как именованную функцию)
login_validator := fn ( mut app App ) {
model := tea . decode_model < User > ( app . req . data )
if ! model . is_valid () {
app. validation_error ('u sername or password too short ')
return
}
app . login ( model )
}
Валидатор данных должен распаковать какие-то данные (в данном случае тело json запроса), проверить их и в зависимости от результата вернуть ошибку проверки или передать проверенную модель(и) на маршрут.
Теперь приложению необходимо знать о валидаторе и о том, по какому маршруту его запускать. Итак, после объявления валидатора вам необходимо добавить его в app.validators
:
app . validators . validators ['/ login '] = login_validator
Затем просто запустите приложение, как если бы вы использовали Vweb:
tea . run ( & app , 8080 )
/user/:user_id
с другими параметрами, параметр URL-адреса user_id
должен находиться после других параметров. т.е. // this will not compile (with or without a validator defined. However it does require one)
['/ user / : user_id ']
fn ( mut app App ) user ( user_id string , user User ) {
}
// this will compile with or without a validator
['/ user / : user_id ']
fn ( mut app App ) user ( user_id string ) {
}
// this will compile with a validator
['/ user / : user_id ']
fn ( mut app App ) user ( user_id int ) {
}
// this is how it has to be defined and will compile (requires a validator defined for /user/:user_id)
['/ user / : user_id ']
fn ( mut app App ) user ( user User , user_id string ) {
}
tea.decode_model<T>(string)
принимает строку json в качестве входных данных и декодирует ее в структуруapp.url_params
предоставляет параметры URL-пути, если они применимы, в виде map[string]string
:user_id
в качестве параметра, но все равно получают к нему доступ.tea.from_map<T>(map[string]string)
можно использовать для того, чтобы взять app.query и превратить его в структуру со строковыми полями.Всякий раз, когда отражение во время компиляции в V более полное, должно быть возможно нечто подобное, что скроет большую часть внутреннего устройства:
import tea
struct App {
tea . Context
pub mut:
validators tea . Validators < App >
}
['/ login '; post ]
fn ( mut app App ) login ( user User ) tea. Result {
// posted user parameters will be available in user after being validated
println ('U sername : ' + user . username + ' Password : ' + user . password )
app . json ('{" status ":" testing "}')
}
['/ login '; validator ]
fn ( mut app App ) login_validator () User {
model := tea . decode_model < User > ( app . req . data )
if ! model . is_valid () {
app. validation_error ('u sername or password too short ')
return
}
return model
}
fn main () {
mut app := App {}
tea . run ( & app , 8080 )
}