update readme for new data access patterns
This commit is contained in:
parent
a2c782c54a
commit
c962f05c81
134
README.md
134
README.md
@ -15,7 +15,7 @@ func main() {
|
|||||||
// Initialize sessions
|
// Initialize sessions
|
||||||
sushi.InitSessions("sessions.json")
|
sushi.InitSessions("sessions.json")
|
||||||
|
|
||||||
app.Get("/", func(ctx sushi.Ctx, params []any) {
|
app.Get("/", func(ctx sushi.Ctx) {
|
||||||
ctx.SendHTML("<h1>Hello Sushi!</h1>")
|
ctx.SendHTML("<h1>Hello Sushi!</h1>")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -41,35 +41,86 @@ api.Get("/users", listUsersHandler)
|
|||||||
api.Post("/users", createUserHandler)
|
api.Post("/users", createUserHandler)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters and Queries
|
||||||
|
|
||||||
URL parameters are automatically converted to the appropriate type:
|
Sushi provides a fluent API for accessing URL parameters, query strings, and form data with automatic type conversion:
|
||||||
|
|
||||||
|
### URL Parameters (Named Routes)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Numeric parameters become integers
|
app.Get("/users/:id", func(ctx sushi.Ctx) {
|
||||||
app.Get("/users/:id", func(ctx sushi.Ctx, params []any) {
|
// Get URL parameter with fluent API
|
||||||
userID := params[0].(int) // /users/123 -> 123
|
userID := ctx.Param("id").Int() // /users/123 -> 123
|
||||||
// ...
|
userIDStr := ctx.Param("id").String() // /users/123 -> "123"
|
||||||
|
|
||||||
|
// With defaults
|
||||||
|
limit := ctx.Param("limit").IntDefault(10)
|
||||||
})
|
})
|
||||||
|
|
||||||
// String parameters stay strings
|
app.Get("/users/:id/posts/:slug", func(ctx sushi.Ctx) {
|
||||||
app.Get("/users/:name", func(ctx sushi.Ctx, params []any) {
|
userID := ctx.Param("id").Int()
|
||||||
name := params[0].(string) // /users/john -> "john"
|
slug := ctx.Param("slug").String()
|
||||||
// ...
|
|
||||||
})
|
|
||||||
|
|
||||||
// Mixed types
|
// Check if parameter exists
|
||||||
app.Get("/users/:id/posts/:slug", func(ctx sushi.Ctx, params []any) {
|
if ctx.Param("optional").Exists() {
|
||||||
userID := params[0].(int) // 123
|
// Handle optional parameter
|
||||||
slug := params[1].(string) // "my-post"
|
}
|
||||||
// ...
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Query Parameters
|
||||||
|
|
||||||
|
```go
|
||||||
|
app.Get("/search", func(ctx sushi.Ctx) {
|
||||||
|
// Get query parameters with fluent API
|
||||||
|
query := ctx.Query("q").String() // ?q=hello -> "hello"
|
||||||
|
page := ctx.Query("page").IntDefault(1) // ?page=2 -> 2
|
||||||
|
limit := ctx.Query("limit").IntDefault(20) // Default to 20 if not present
|
||||||
|
sortBy := ctx.Query("sort").StringDefault("name") // Default to "name"
|
||||||
|
|
||||||
|
// Boolean query params
|
||||||
|
includeDeleted := ctx.Query("deleted").Bool() // ?deleted=true -> true
|
||||||
|
|
||||||
|
// Float values
|
||||||
|
minPrice := ctx.Query("min_price").Float() // ?min_price=19.99 -> 19.99
|
||||||
|
|
||||||
|
// Check existence
|
||||||
|
if ctx.Query("filter").Exists() {
|
||||||
|
filter := ctx.Query("filter").String()
|
||||||
|
// Apply filter
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Form Data
|
||||||
|
|
||||||
|
Access form data with the fluent API:
|
||||||
|
|
||||||
|
```go
|
||||||
|
app.Post("/users", func(ctx sushi.Ctx) {
|
||||||
|
// Get form fields with fluent API
|
||||||
|
name := ctx.Input("name").String()
|
||||||
|
email := ctx.Input("email").String()
|
||||||
|
age := ctx.Input("age").IntDefault(0)
|
||||||
|
|
||||||
|
// Check if checkbox is checked
|
||||||
|
agreeToTerms := ctx.Input("terms").Bool() // Checks for "true", "on", "1", "yes"
|
||||||
|
|
||||||
|
// Validate required fields
|
||||||
|
if ctx.Input("email").IsEmpty() {
|
||||||
|
ctx.SendError(400, "Email is required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get array of values (for multiple select, checkboxes)
|
||||||
|
tags := ctx.GetFormArray("tags[]")
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
## Response Helpers
|
## Response Helpers
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func myHandler(ctx sushi.Ctx, params []any) {
|
func myHandler(ctx sushi.Ctx) {
|
||||||
// JSON responses
|
// JSON responses
|
||||||
ctx.SendJSON(map[string]string{"message": "success"})
|
ctx.SendJSON(map[string]string{"message": "success"})
|
||||||
|
|
||||||
@ -87,15 +138,20 @@ func myHandler(ctx sushi.Ctx, params []any) {
|
|||||||
|
|
||||||
// Status only
|
// Status only
|
||||||
ctx.SendStatus(204)
|
ctx.SendStatus(204)
|
||||||
|
|
||||||
|
// File responses
|
||||||
|
ctx.SendFile("/path/to/file.pdf")
|
||||||
|
|
||||||
|
// Raw bytes
|
||||||
|
ctx.SendBytes(imageData, "image/png")
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
## Middleware
|
## Middleware
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Custom middleware
|
// Custom middleware
|
||||||
func loggingMiddleware() sushi.Middleware {
|
func loggingMiddleware() sushi.Middleware {
|
||||||
return func(ctx sushi.Ctx, params []any, next func()) {
|
return func(ctx sushi.Ctx, next func()) {
|
||||||
println("Request:", string(ctx.Method()), string(ctx.Path()))
|
println("Request:", string(ctx.Method()), string(ctx.Path()))
|
||||||
next()
|
next()
|
||||||
println("Status:", ctx.Response.StatusCode())
|
println("Status:", ctx.Response.StatusCode())
|
||||||
@ -111,7 +167,7 @@ admin.Use(auth.RequireAuth("/login"))
|
|||||||
|
|
||||||
## Authentication Workflow
|
## Authentication Workflow
|
||||||
|
|
||||||
### 1. Setup Password Hashing
|
### 1. Password Hashing
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "git.sharkk.net/Sharkk/Sushi/password"
|
import "git.sharkk.net/Sharkk/Sushi/password"
|
||||||
@ -176,9 +232,16 @@ func main() {
|
|||||||
### 4. Login Handler
|
### 4. Login Handler
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func loginHandler(ctx sushi.Ctx, params []any) {
|
func loginHandler(ctx sushi.Ctx) {
|
||||||
email := string(ctx.PostArgs().Peek("email"))
|
// Use fluent API for form data
|
||||||
password := string(ctx.PostArgs().Peek("password"))
|
email := ctx.Input("email").String()
|
||||||
|
password := ctx.Input("password").String()
|
||||||
|
|
||||||
|
// Validate inputs
|
||||||
|
if ctx.Input("email").IsEmpty() || ctx.Input("password").IsEmpty() {
|
||||||
|
ctx.SendError(400, "Email and password are required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Find user by email/username
|
// Find user by email/username
|
||||||
user := findUserByEmail(email)
|
user := findUserByEmail(email)
|
||||||
@ -204,7 +267,7 @@ func loginHandler(ctx sushi.Ctx, params []any) {
|
|||||||
### 5. Logout Handler
|
### 5. Logout Handler
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func logoutHandler(ctx sushi.Ctx, params []any) {
|
func logoutHandler(ctx sushi.Ctx) {
|
||||||
ctx.Logout()
|
ctx.Logout()
|
||||||
ctx.Redirect("/")
|
ctx.Redirect("/")
|
||||||
}
|
}
|
||||||
@ -213,7 +276,7 @@ func logoutHandler(ctx sushi.Ctx, params []any) {
|
|||||||
### 6. Getting Current User
|
### 6. Getting Current User
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func dashboardHandler(ctx sushi.Ctx, params []any) {
|
func dashboardHandler(ctx sushi.Ctx) {
|
||||||
user := ctx.GetCurrentUser().(*User)
|
user := ctx.GetCurrentUser().(*User)
|
||||||
|
|
||||||
html := fmt.Sprintf("<h1>Welcome, %s!</h1>", user.Username)
|
html := fmt.Sprintf("<h1>Welcome, %s!</h1>", user.Username)
|
||||||
@ -230,7 +293,7 @@ import "git.sharkk.net/Sharkk/Sushi/csrf"
|
|||||||
app.Use(csrf.Middleware())
|
app.Use(csrf.Middleware())
|
||||||
|
|
||||||
// In your form template
|
// In your form template
|
||||||
func loginPageHandler(ctx sushi.Ctx, params []any) {
|
func loginPageHandler(ctx sushi.Ctx) {
|
||||||
csrfField := csrf.CSRFHiddenField(ctx)
|
csrfField := csrf.CSRFHiddenField(ctx)
|
||||||
|
|
||||||
html := fmt.Sprintf(`
|
html := fmt.Sprintf(`
|
||||||
@ -266,7 +329,7 @@ app.Get("/assets/*path", sushi.StaticEmbed(files))
|
|||||||
## Sessions
|
## Sessions
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func someHandler(ctx sushi.Ctx, params []any) {
|
func someHandler(ctx sushi.Ctx) {
|
||||||
sess := ctx.GetCurrentSession()
|
sess := ctx.GetCurrentSession()
|
||||||
|
|
||||||
// Set session data
|
// Set session data
|
||||||
@ -357,7 +420,7 @@ func main() {
|
|||||||
app.Listen(":8080")
|
app.Listen(":8080")
|
||||||
}
|
}
|
||||||
|
|
||||||
func homeHandler(ctx sushi.Ctx, params []any) {
|
func homeHandler(ctx sushi.Ctx) {
|
||||||
if ctx.IsAuthenticated() {
|
if ctx.IsAuthenticated() {
|
||||||
ctx.Redirect("/dashboard")
|
ctx.Redirect("/dashboard")
|
||||||
return
|
return
|
||||||
@ -365,7 +428,7 @@ func homeHandler(ctx sushi.Ctx, params []any) {
|
|||||||
ctx.SendHTML(`<a href="/login">Login</a>`)
|
ctx.SendHTML(`<a href="/login">Login</a>`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loginPageHandler(ctx sushi.Ctx, params []any) {
|
func loginPageHandler(ctx sushi.Ctx) {
|
||||||
html := fmt.Sprintf(`
|
html := fmt.Sprintf(`
|
||||||
<form method="POST" action="/login">
|
<form method="POST" action="/login">
|
||||||
%s
|
%s
|
||||||
@ -378,9 +441,10 @@ func loginPageHandler(ctx sushi.Ctx, params []any) {
|
|||||||
ctx.SendHTML(html)
|
ctx.SendHTML(html)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loginHandler(ctx sushi.Ctx, params []any) {
|
func loginHandler(ctx sushi.Ctx) {
|
||||||
email := string(ctx.PostArgs().Peek("email"))
|
// Use fluent API for form data
|
||||||
pass := string(ctx.PostArgs().Peek("password"))
|
email := ctx.Input("email").String()
|
||||||
|
pass := ctx.Input("password").String()
|
||||||
|
|
||||||
user := findUserByEmail(email)
|
user := findUserByEmail(email)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
@ -397,7 +461,7 @@ func loginHandler(ctx sushi.Ctx, params []any) {
|
|||||||
ctx.Redirect("/dashboard")
|
ctx.Redirect("/dashboard")
|
||||||
}
|
}
|
||||||
|
|
||||||
func dashboardHandler(ctx sushi.Ctx, params []any) {
|
func dashboardHandler(ctx sushi.Ctx) {
|
||||||
user := ctx.GetCurrentUser().(*User)
|
user := ctx.GetCurrentUser().(*User)
|
||||||
|
|
||||||
html := fmt.Sprintf(`
|
html := fmt.Sprintf(`
|
||||||
@ -411,7 +475,7 @@ func dashboardHandler(ctx sushi.Ctx, params []any) {
|
|||||||
ctx.SendHTML(html)
|
ctx.SendHTML(html)
|
||||||
}
|
}
|
||||||
|
|
||||||
func logoutHandler(ctx sushi.Ctx, params []any) {
|
func logoutHandler(ctx sushi.Ctx) {
|
||||||
ctx.Logout()
|
ctx.Logout()
|
||||||
ctx.Redirect("/")
|
ctx.Redirect("/")
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user