1
0
mirror of https://github.com/gofiber/fiber.git synced 2025-02-21 07:52:53 +00:00

Merge pull request #3 from gofiber/master

Accumulative update @ 07 Mar 2020
This commit is contained in:
Vic Shóstak 2020-03-07 17:01:39 +03:00 committed by GitHub
commit 778953db3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 2639 additions and 922 deletions

104
.github/README.md vendored
View File

@ -33,6 +33,9 @@
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
</a>
<br><br>
<a href="https://github.com/gofiber/fiber/releases">
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
@ -60,7 +63,7 @@
</a>
</p>
<p align="center">
<b>Fiber</b> is an <a href="https://github.com/expressjs/express">Express</a> inspired <b>web framework</b> build on top of <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, the <b>fastest</b> HTTP engine for <a href="https://golang.org/doc/">Go</a>. Designed to <b>ease</b> things up for <b>fast</b> development with <b>zero memory allocation</b> and <b>performance</b> in mind.
<b>Fiber</b> is an <a href="https://github.com/expressjs/express">Express</a> inspired <b>web framework</b> built on top of <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, the <b>fastest</b> HTTP engine for <a href="https://golang.org/doc/">Go</a>. Designed to <b>ease</b> things up for <b>fast</b> development with <b>zero memory allocation</b> and <b>performance</b> in mind.
</p>
## ⚡️ Quickstart
@ -109,16 +112,16 @@ These tests are performed by [TechEmpower](https://github.com/TechEmpower/Framew
- [API endpoints](https://fiber.wiki/context)
- Middleware & [Next](https://fiber.wiki/context#next) support
- [Rapid](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) server-side programming
- Available in 9 other languages
- Available in 10 other languages
- And much more, [explore Fiber](https://fiber.wiki/)
## 💡 Philosophy
New gophers that make the switch from [Node.js](https://nodejs.org/en/about/) to [Go](https://golang.org/doc/) are dealing with a learning curve before they can start building their web applications or microservices. Fiber, as a **web framework**, was created with the idea of **minimalism** and follow **UNIX way**, so that new gophers can quickly enter the world of Go with a warm and trusted welcome.
New gophers that make the switch from [Node.js](https://nodejs.org/en/about/) to [Go](https://golang.org/doc/) are dealing with a learning curve before they can start building their web applications or microservices. Fiber, as a **web framework**, was created with the idea of **minimalism** and follows the **UNIX way**, so that new gophers can quickly enter the world of Go with a warm and trusted welcome.
Fiber is **inspired** by Express, the most popular web framework on the Internet. We combined the **ease** of Express and **raw performance** of Go. If you have ever implemented a web application on Node.js (_using Express or similar_), then many methods and principles will seem **very common** to you.
Fiber is **inspired** by Express, the most popular web framework on the Internet. We combined the **ease** of Express and **raw performance** of Go. If you have ever implemented a web application in Node.js (_using Express or similar_), then many methods and principles will seem **very common** to you.
We **listen** to our users in [issues](https://github.com/gofiber/fiber/issues) (_and all over the Internet_) to create a **fast**, **flexible** and **friendly** Go web framework for **any** tasks, **deadlines** and developer **skills**! Just like Express does in the JavaScript world.
We **listen** to our users in [issues](https://github.com/gofiber/fiber/issues) (_and all over the Internet_) to create a **fast**, **flexible** and **friendly** Go web framework for **any** task, **deadline** and developer **skill**! Just like Express does in the JavaScript world.
## 👀 Examples
@ -153,12 +156,12 @@ func main() {
```
### Serve static files
https://fiber.wiki/application#static
```go
func main() {
app := fiber.New()
app.Static("/public")
app.Static("/", "/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
@ -174,7 +177,8 @@ func main() {
```
### Middleware & Next
https://fiber.wiki/routing#middleware
https://fiber.wiki/context#next
```go
func main() {
app := fiber.New()
@ -205,9 +209,10 @@ func main() {
<summary>📚 Show more code examples</summary>
### Template engines
https://fiber.wiki/application#settings
https://fiber.wiki/context#render
Already supports:
Supported engines:
- [html](https://golang.org/pkg/html/template/)
- [amber](https://github.com/eknkc/amber)
- [handlebars](https://github.com/aymerick/raymond)
@ -241,7 +246,7 @@ func main() {
```
### Grouping routes into chains
https://fiber.wiki/application#group
```go
func main() {
app := fiber.New()
@ -263,8 +268,8 @@ func main() {
}
```
### Built-in logger
### Middleware logger
https://fiber.wiki/middleware#logger
```go
import (
"github.com/gofiber/fiber"
@ -273,7 +278,7 @@ import (
func main() {
app := fiber.New()
// If you want to change default Logger config
loggerConfig := middleware.LoggerConfig{
Format: "${time} - ${method} ${path}\n",
@ -288,6 +293,7 @@ func main() {
```
### Cross-Origin Resource Sharing (CORS)
https://fiber.wiki/middleware#cors
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
@ -311,7 +317,7 @@ func main() {
}
```
Check CORS by passing any domain in `Origin` header:
Check CORS by passing any domain in `Origin` header:
```bash
curl -H "Origin: http://example.com" --verbose http://localhost:3000
@ -343,20 +349,27 @@ func main() {
```
### JSON Response
https://fiber.wiki/context#json
```go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
app := fiber.New()
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// Serialize JSON
app.Get("/json", func(c *fiber.Ctx) {
app.Get("/user", func(c *fiber.Ctx) {
c.JSON(&User{"John", 20})
// => {"name":"John", "age":20}
// {"name":"John", "age":20}
})
app.Get("/json", func(c *fiber.Ctx) {
c.JSON(&fiber.Map{
"success": true,
"message": "Hi John!",
})
// {"success":true, "message":"Hi John!"}
})
app.Listen(3000)
@ -364,14 +377,12 @@ func main() {
```
### WebSocket support
https://fiber.wiki/application#websocket
```go
func main() {
app := fiber.New()
app.WebSocket("/ws/:name", func(c *fiber.Conn) {
log.Println(c.Params("name"))
app.WebSocket("/ws", func(c *fiber.Conn) {
for {
mt, msg, err := c.ReadMessage()
if err != nil {
@ -389,26 +400,33 @@ func main() {
}
})
// Listen on ws://localhost:3000/ws/john
// Listen on ws://localhost:3000/ws
app.Listen(3000)
}
```
### Recover from `panic`
### Recover middleware
https://fiber.wiki/middleware#recover
```go
package main
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
log.Println(err) // "Something went wrong!"
c.SendStatus(500) // Internal Server Error
})))
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
})
app.Recover(func(c *fiber.Ctx) {
c.Status(500).Send(c.Error())
// => 500 "Something went wrong!"
})
app.Listen(3000)
}
```
@ -437,6 +455,12 @@ If you want to say **thank you** and/or support the active development of `Fiber
<table>
<tr>
<td align="center">
<a href="https://github.com/gofiber/fiber">
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
<sub><b>JustDave</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bihe">
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
@ -471,3 +495,11 @@ If you want to say **thank you** and/or support the active development of `Fiber
## ⚠️ License
`Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE).
[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/0)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/0)
[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/1)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/1)
[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/2)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/2)
[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/3)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/3)
[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/4)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/4)
[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/5)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/5)
[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/6)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/6)

251
.github/README_de.md vendored
View File

@ -33,6 +33,9 @@
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
</a>
<br><br>
<a href="https://github.com/gofiber/fiber/releases">
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
@ -122,27 +125,6 @@ Fiber ist **inspiriert** von Expressjs, dem beliebtesten Web-Framework im Intern
Nachfolgend sind einige der gängigen Beispiele aufgeführt. Wenn du weitere Codebeispiele sehen möchten, besuche bitte unser ["Recipes Repository"](https://github.com/gofiber/recipes) oder besuche unsere [API Dokumentation](https://fiber.wiki).
### Serve static files
```go
func main() {
app := fiber.New()
app.Static("/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Routing
```go
@ -171,8 +153,30 @@ func main() {
}
```
### Middleware & Next
### Serve static files
https://fiber.wiki/application#static
```go
func main() {
app := fiber.New()
app.Static("/", "/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Middleware & Next
https://fiber.wiki/routing#middleware
https://fiber.wiki/context#next
```go
func main() {
app := fiber.New()
@ -200,7 +204,122 @@ func main() {
```
<details>
<summary>📜 Show more code examples</summary>
<summary>📚 Show more code examples</summary>
### Template engines
https://fiber.wiki/application#settings
https://fiber.wiki/context#render
Supported engines:
- [html](https://golang.org/pkg/html/template/)
- [amber](https://github.com/eknkc/amber)
- [handlebars](https://github.com/aymerick/raymond)
- [mustache](https://github.com/cbroglie/mustache)
- [pug](https://github.com/Joker/jade)
```go
func main() {
// You can setup template engine before initiation app:
app := fiber.New(&fiber.Settings{
TemplateEngine: "mustache",
TemplateFolder: "./views",
TemplateExtension: ".tmpl",
})
// OR after initiation app at any convenient location:
app.Settings.TemplateEngine = "mustache"
app.Settings.TemplateFolder = "./views"
app.Settings.TemplateExtension = ".tmpl"
// And now, you can call template `./views/home.tmpl` like this:
app.Get("/", func(c *fiber.Ctx) {
c.Render("home", fiber.Map{
"title": "Homepage",
"year": 1999,
})
})
// ...
}
```
### Grouping routes into chains
https://fiber.wiki/application#group
```go
func main() {
app := fiber.New()
// Root API route
api := app.Group("/api", cors()) // /api
// API v1 routes
v1 := api.Group("/v1", mysql()) // /api/v1
v1.Get("/list", handler) // /api/v1/list
v1.Get("/user", handler) // /api/v1/user
// API v2 routes
v2 := api.Group("/v2", mongodb()) // /api/v2
v2.Get("/list", handler) // /api/v2/list
v2.Get("/user", handler) // /api/v2/user
// ...
}
```
### Middleware logger
https://fiber.wiki/middleware#logger
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// If you want to change default Logger config
loggerConfig := middleware.LoggerConfig{
Format: "${time} - ${method} ${path}\n",
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
}
// Middleware for Logger with config
app.Use(middleware.Logger(loggerConfig))
// ...
}
```
### Cross-Origin Resource Sharing (CORS)
https://fiber.wiki/middleware#cors
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// Connect CORS for each route as middleware
app.Use(middleware.CORS())
app.Get("/", func(c *fiber.Ctx) {
c.Send("CORS is enabled!")
})
app.Listen(3000)
}
```
Check CORS by passing any domain in `Origin` header:
```bash
curl -H "Origin: http://example.com" --verbose http://localhost:3000
```
### Custom 404 response
@ -209,9 +328,11 @@ func main() {
app := fiber.New()
app.Static("/public")
app.Get("/demo", func(c *fiber.Ctx) {
c.Send("This is a demo!")
})
app.Post("/register", func(c *fiber.Ctx) {
c.Send("Welcome!")
})
@ -226,40 +347,82 @@ func main() {
```
### JSON Response
https://fiber.wiki/context#json
```go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
app := fiber.New()
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// Serialize JSON
app.Get("/json", func(c *fiber.Ctx) {
app.Get("/user", func(c *fiber.Ctx) {
c.JSON(&User{"John", 20})
// => {"name":"John", "age":20}
// {"name":"John", "age":20}
})
app.Get("/json", func(c *fiber.Ctx) {
c.JSON(&fiber.Map{
"success": true,
"message": "Hi John!",
})
// {"success":true, "message":"Hi John!"}
})
app.Listen(3000)
}
```
### Recover from panic
### WebSocket support
https://fiber.wiki/application#websocket
```go
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
app.WebSocket("/ws", func(c *fiber.Conn) {
for {
mt, msg, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recovery: %s", msg)
err = c.WriteMessage(mt, msg)
if err != nil {
log.Println("write:", err)
break
}
}
})
app.Recover(func(c *fiber.Ctx) {
c.Status(500).Send(c.Error())
// => 500 "Something went wrong!"
// Listen on ws://localhost:3000/ws
app.Listen(3000)
}
```
### Recover middleware
https://fiber.wiki/middleware#recover
```go
package main
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
log.Println(err) // "Something went wrong!"
c.SendStatus(500) // Internal Server Error
})))
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
})
app.Listen(3000)
@ -287,6 +450,12 @@ Falls du **danke** sagen möchtest und/oder aktiv die Entwicklung von `fiber` f
</a>
<table>
<tr>
<td align="center">
<a href="https://github.com/gofiber/fiber">
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
<sub><b>JustDave</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bihe">
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
@ -296,7 +465,7 @@ Falls du **danke** sagen möchtest und/oder aktiv die Entwicklung von `fiber` f
<td align="center">
<a href="https://github.com/koddr">
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
<sub><b>koddr</b></sub>
<sub><b>Vic&nbsp;Shóstak</b></sub>
</a>
</td>
<td align="center">

253
.github/README_es.md vendored
View File

@ -33,6 +33,9 @@
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
</a>
<br><br>
<a href="https://github.com/gofiber/fiber/releases">
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
@ -88,7 +91,7 @@ En primer lugar, [descargue](https://golang.org/dl/) e instale Go. Se requiere `
La instalación se realiza con el comando [`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) :
```bash
go get github.com/gofiber/fiber
go get github.com/gofiber/fiber/...
```
## 🤖 Puntos de referencia
@ -122,27 +125,6 @@ Fiber está **inspirado** en Expressjs, el framework web más popular en Interne
A continuación se enumeran algunos de los ejemplos comunes. Si desea ver más ejemplos de código, visite nuestro [repositorio de Recetas](https://github.com/gofiber/recipes) o nuestra [documentación de API](https://fiber.wiki) .
### Serve static files
```go
func main() {
app := fiber.New()
app.Static("/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Routing
```go
@ -171,8 +153,30 @@ func main() {
}
```
### Middleware & Next
### Serve static files
https://fiber.wiki/application#static
```go
func main() {
app := fiber.New()
app.Static("/", "/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Middleware & Next
https://fiber.wiki/routing#middleware
https://fiber.wiki/context#next
```go
func main() {
app := fiber.New()
@ -200,7 +204,122 @@ func main() {
```
<details>
<summary>📜 Show more code examples</summary>
<summary>📚 Show more code examples</summary>
### Template engines
https://fiber.wiki/application#settings
https://fiber.wiki/context#render
Supported engines:
- [html](https://golang.org/pkg/html/template/)
- [amber](https://github.com/eknkc/amber)
- [handlebars](https://github.com/aymerick/raymond)
- [mustache](https://github.com/cbroglie/mustache)
- [pug](https://github.com/Joker/jade)
```go
func main() {
// You can setup template engine before initiation app:
app := fiber.New(&fiber.Settings{
TemplateEngine: "mustache",
TemplateFolder: "./views",
TemplateExtension: ".tmpl",
})
// OR after initiation app at any convenient location:
app.Settings.TemplateEngine = "mustache"
app.Settings.TemplateFolder = "./views"
app.Settings.TemplateExtension = ".tmpl"
// And now, you can call template `./views/home.tmpl` like this:
app.Get("/", func(c *fiber.Ctx) {
c.Render("home", fiber.Map{
"title": "Homepage",
"year": 1999,
})
})
// ...
}
```
### Grouping routes into chains
https://fiber.wiki/application#group
```go
func main() {
app := fiber.New()
// Root API route
api := app.Group("/api", cors()) // /api
// API v1 routes
v1 := api.Group("/v1", mysql()) // /api/v1
v1.Get("/list", handler) // /api/v1/list
v1.Get("/user", handler) // /api/v1/user
// API v2 routes
v2 := api.Group("/v2", mongodb()) // /api/v2
v2.Get("/list", handler) // /api/v2/list
v2.Get("/user", handler) // /api/v2/user
// ...
}
```
### Middleware logger
https://fiber.wiki/middleware#logger
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// If you want to change default Logger config
loggerConfig := middleware.LoggerConfig{
Format: "${time} - ${method} ${path}\n",
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
}
// Middleware for Logger with config
app.Use(middleware.Logger(loggerConfig))
// ...
}
```
### Cross-Origin Resource Sharing (CORS)
https://fiber.wiki/middleware#cors
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// Connect CORS for each route as middleware
app.Use(middleware.CORS())
app.Get("/", func(c *fiber.Ctx) {
c.Send("CORS is enabled!")
})
app.Listen(3000)
}
```
Check CORS by passing any domain in `Origin` header:
```bash
curl -H "Origin: http://example.com" --verbose http://localhost:3000
```
### Custom 404 response
@ -209,9 +328,11 @@ func main() {
app := fiber.New()
app.Static("/public")
app.Get("/demo", func(c *fiber.Ctx) {
c.Send("This is a demo!")
})
app.Post("/register", func(c *fiber.Ctx) {
c.Send("Welcome!")
})
@ -226,40 +347,82 @@ func main() {
```
### JSON Response
https://fiber.wiki/context#json
```go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
app := fiber.New()
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// Serialize JSON
app.Get("/json", func(c *fiber.Ctx) {
app.Get("/user", func(c *fiber.Ctx) {
c.JSON(&User{"John", 20})
// => {"name":"John", "age":20}
// {"name":"John", "age":20}
})
app.Get("/json", func(c *fiber.Ctx) {
c.JSON(&fiber.Map{
"success": true,
"message": "Hi John!",
})
// {"success":true, "message":"Hi John!"}
})
app.Listen(3000)
}
```
### Recover from panic
### WebSocket support
https://fiber.wiki/application#websocket
```go
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
app.WebSocket("/ws", func(c *fiber.Conn) {
for {
mt, msg, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recovery: %s", msg)
err = c.WriteMessage(mt, msg)
if err != nil {
log.Println("write:", err)
break
}
}
})
app.Recover(func(c *fiber.Ctx) {
c.Status(500).Send(c.Error())
// => 500 "Something went wrong!"
// Listen on ws://localhost:3000/ws
app.Listen(3000)
}
```
### Recover middleware
https://fiber.wiki/middleware#recover
```go
package main
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
log.Println(err) // "Something went wrong!"
c.SendStatus(500) // Internal Server Error
})))
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
})
app.Listen(3000)
@ -287,6 +450,12 @@ Si quiere **agradecer** y/o apoyar el desarrollo activo de la `Fiber`:
</a>
<table>
<tr>
<td align="center">
<a href="https://github.com/gofiber/fiber">
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
<sub><b>JustDave</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bihe">
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
@ -296,7 +465,7 @@ Si quiere **agradecer** y/o apoyar el desarrollo activo de la `Fiber`:
<td align="center">
<a href="https://github.com/koddr">
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
<sub><b>koddr</b></sub>
<sub><b>Vic&nbsp;Shóstak</b></sub>
</a>
</td>
<td align="center">

251
.github/README_fr.md vendored
View File

@ -33,6 +33,9 @@
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
</a>
<br><br>
<a href="https://github.com/gofiber/fiber/releases">
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
@ -122,27 +125,6 @@ Fiber est **inspiré** par Express, le framework web le plus populaire d'Interne
Ci-dessous quelques exemples courants. Si vous voulez voir plus d'exemples, rendez-vous sur notre ["Recipes repository"](https://github.com/gofiber/recipes) ou visitez notre [documentation API](https://fiber.wiki).
### Serve static files
```go
func main() {
app := fiber.New()
app.Static("/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Routing
```go
@ -171,8 +153,30 @@ func main() {
}
```
### Middleware & Next
### Serve static files
https://fiber.wiki/application#static
```go
func main() {
app := fiber.New()
app.Static("/", "/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Middleware & Next
https://fiber.wiki/routing#middleware
https://fiber.wiki/context#next
```go
func main() {
app := fiber.New()
@ -200,7 +204,122 @@ func main() {
```
<details>
<summary>📜 Voir plus d'exemples de code</summary>
<summary>📚 Show more code examples</summary>
### Template engines
https://fiber.wiki/application#settings
https://fiber.wiki/context#render
Supported engines:
- [html](https://golang.org/pkg/html/template/)
- [amber](https://github.com/eknkc/amber)
- [handlebars](https://github.com/aymerick/raymond)
- [mustache](https://github.com/cbroglie/mustache)
- [pug](https://github.com/Joker/jade)
```go
func main() {
// You can setup template engine before initiation app:
app := fiber.New(&fiber.Settings{
TemplateEngine: "mustache",
TemplateFolder: "./views",
TemplateExtension: ".tmpl",
})
// OR after initiation app at any convenient location:
app.Settings.TemplateEngine = "mustache"
app.Settings.TemplateFolder = "./views"
app.Settings.TemplateExtension = ".tmpl"
// And now, you can call template `./views/home.tmpl` like this:
app.Get("/", func(c *fiber.Ctx) {
c.Render("home", fiber.Map{
"title": "Homepage",
"year": 1999,
})
})
// ...
}
```
### Grouping routes into chains
https://fiber.wiki/application#group
```go
func main() {
app := fiber.New()
// Root API route
api := app.Group("/api", cors()) // /api
// API v1 routes
v1 := api.Group("/v1", mysql()) // /api/v1
v1.Get("/list", handler) // /api/v1/list
v1.Get("/user", handler) // /api/v1/user
// API v2 routes
v2 := api.Group("/v2", mongodb()) // /api/v2
v2.Get("/list", handler) // /api/v2/list
v2.Get("/user", handler) // /api/v2/user
// ...
}
```
### Middleware logger
https://fiber.wiki/middleware#logger
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// If you want to change default Logger config
loggerConfig := middleware.LoggerConfig{
Format: "${time} - ${method} ${path}\n",
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
}
// Middleware for Logger with config
app.Use(middleware.Logger(loggerConfig))
// ...
}
```
### Cross-Origin Resource Sharing (CORS)
https://fiber.wiki/middleware#cors
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// Connect CORS for each route as middleware
app.Use(middleware.CORS())
app.Get("/", func(c *fiber.Ctx) {
c.Send("CORS is enabled!")
})
app.Listen(3000)
}
```
Check CORS by passing any domain in `Origin` header:
```bash
curl -H "Origin: http://example.com" --verbose http://localhost:3000
```
### Custom 404 response
@ -209,9 +328,11 @@ func main() {
app := fiber.New()
app.Static("/public")
app.Get("/demo", func(c *fiber.Ctx) {
c.Send("This is a demo!")
})
app.Post("/register", func(c *fiber.Ctx) {
c.Send("Welcome!")
})
@ -226,40 +347,82 @@ func main() {
```
### JSON Response
https://fiber.wiki/context#json
```go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
app := fiber.New()
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// Serialize JSON
app.Get("/json", func(c *fiber.Ctx) {
app.Get("/user", func(c *fiber.Ctx) {
c.JSON(&User{"John", 20})
// => {"name":"John", "age":20}
// {"name":"John", "age":20}
})
app.Get("/json", func(c *fiber.Ctx) {
c.JSON(&fiber.Map{
"success": true,
"message": "Hi John!",
})
// {"success":true, "message":"Hi John!"}
})
app.Listen(3000)
}
```
### Recover from panic
### WebSocket support
https://fiber.wiki/application#websocket
```go
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
app.WebSocket("/ws", func(c *fiber.Conn) {
for {
mt, msg, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recovery: %s", msg)
err = c.WriteMessage(mt, msg)
if err != nil {
log.Println("write:", err)
break
}
}
})
app.Recover(func(c *fiber.Ctx) {
c.Status(500).Send(c.Error())
// => 500 "Something went wrong!"
// Listen on ws://localhost:3000/ws
app.Listen(3000)
}
```
### Recover middleware
https://fiber.wiki/middleware#recover
```go
package main
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
log.Println(err) // "Something went wrong!"
c.SendStatus(500) // Internal Server Error
})))
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
})
app.Listen(3000)
@ -287,6 +450,12 @@ Si vous voulez nous remercier et/ou soutenir le développement actif de `Fiber`:
</a>
<table>
<tr>
<td align="center">
<a href="https://github.com/gofiber/fiber">
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
<sub><b>JustDave</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bihe">
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
@ -296,7 +465,7 @@ Si vous voulez nous remercier et/ou soutenir le développement actif de `Fiber`:
<td align="center">
<a href="https://github.com/koddr">
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
<sub><b>koddr</b></sub>
<sub><b>Vic&nbsp;Shóstak</b></sub>
</a>
</td>
<td align="center">

499
.github/README_id.md vendored Normal file
View File

@ -0,0 +1,499 @@
<p align="center">
<a href="https://fiber.wiki">
<img alt="Fiber" height="125" src="https://github.com/gofiber/docs/blob/master/static/fiber_v2_logo.svg">
</a>
<br>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ru.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/pt.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/de.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
</a>
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
</a> -->
<br><br>
<a href="https://github.com/gofiber/fiber/releases">
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
</a>
<a href="https://fiber.wiki">
<img src="https://img.shields.io/badge/api-documentation-blue?style=flat-square">
</a>
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
<img src="https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square">
</a>
<a href="#">
<img src="https://img.shields.io/badge/goreport-A%2B-brightgreen?style=flat-square">
</a>
<a href="https://gocover.io/github.com/gofiber/fiber">
<img src="https://img.shields.io/badge/coverage-91%25-brightgreen?style=flat-square">
</a>
<a href="https://travis-ci.org/gofiber/fiber">
<img src="https://img.shields.io/travis/gofiber/fiber/master.svg?label=linux&style=flat-square">
</a>
<a href="https://travis-ci.org/gofiber/fiber">
<img src="https://img.shields.io/travis/gofiber/fiber/master.svg?label=windows&style=flat-square">
</a>
<a href="https://travis-ci.org/gofiber/fiber">
<img src="https://img.shields.io/travis/gofiber/fiber/master.svg?label=osx&style=flat-square">
</a>
</p>
<p align="center">
<b>Fiber</b> adalah <b>web framework</b> yang terinspirasi dari <a href="https://github.com/expressjs/express">Express</a> yang berbasiskan <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, HTTP engine paling <b>cepat</b> untuk <a href="https://golang.org/doc/">Go</a>. Dirancang untuk <b>mempermudah</b>, <b>mempercepat</b> pengembangan aplikasi dengan <b>alokasi memori nol-nya</b> serta <b>kinerja</b> yang selalu diperhatikan.
</p>
## ⚡️ Cara Mulai
```go
package main
import "github.com/gofiber/fiber"
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) {
c.Send("Hello, World!")
})
app.Listen(3000)
}
```
## ⚙️ Instalasi
Pertama, [unduh](https://golang.org/dl/) dan instal Go di komputer anda. Versi `1.11` atau yang lebih tinggi diperlukan.
Instalasi dilakukkan dengan perintah [`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them):
```bash
go get -u github.com/gofiber/fiber/...
```
## 🤖 Pengukuran Kinerja
Pengukuran ini dilakukan oleh [TechEmpower](https://github.com/TechEmpower/FrameworkBenchmarks) dan [Go Web](https://github.com/smallnest/go-web-framework-benchmark). Apabila anda ingin melihat hasil lengkapnya, silahkan kunjungi halaman [Wiki](https://fiber.wiki/benchmarks) kami.
<p float="left" align="middle">
<img src="https://github.com/gofiber/docs/blob/master/.gitbook/assets//benchmark-pipeline.png" width="49%">
<img src="https://github.com/gofiber/docs/blob/master/.gitbook/assets//benchmark_alloc.png" width="49%">
</p>
## 🎯 Fitur
- Sistem [Routing](https://fiber.wiki/routing) yang solid
- Serve [file statis](https://fiber.wiki/application#static)
- [Kinerja](https://fiber.wiki/benchmarks) ekstrim
- [Penggunaan memori](https://fiber.wiki/benchmarks) yang kecil
- Cocok untuk [API](https://fiber.wiki/context)
- Mendukung Middleware & [Next](https://fiber.wiki/context#next) seperti Express
- Kembangkan aplikasi dengan [Cepat](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497)
- Tersedia di 10 bahasa lainnya
- Dan masih banyak lagi, [kunjungi Fiber](https://fiber.wiki/)
## 💡 Filosofi
Bagi yang baru yang beralih dari [Node.js](https://nodejs.org/en/about/) ke [Go](https://golang.org/doc/) terkadang perlu waktu yang cukup lama sebelum mereka mampu membuat aplikasi web dengan Go. Fiber, sebagai **web framework** dirancang secara **minimalis** dan mengikuti filosofi dari **UNIX**, sehingga pengguna baru dengan cepat memasuki dunia Go dengan sambutan yang hangat dan dapat diandalkan.
Fiber terinspirasi dari Express, salah satu web framework paling terkenal di Internet. Kami menggabungkan **kemudahan** dari Express dan **kinerja luar biasa** dari Go. Apabila anda pernah membuat aplikasi dengan Node.js (_dengan Express atau yang lainnya_), maka banyak metode dan prinsip yang akan terasa **sangat umum** bagi anda.
Kami **mendengarkan** para pengguna di [GitHub Issues](https://github.com/gofiber/fiber/issues) (_dan berbagai platform lainnya_) untuk menciptakan web framework yang **cepat**, **fleksibel** dan **bersahabat** untuk berbagai macam keperluan, **tenggat waktu** dan **keahlian** para pengguna! Sama halnya seperti yang dilakukkan Express di dunia JavaScript.
## 👀 Contoh
Dibawah ini terdapat beberapa contoh penggunaan. Jika anda ingin contoh lainnya, silahkan kunjungi [Gudang resep](https://github.com/gofiber/recipes) atau kunjungi [Dokumentasi API](https://fiber.wiki) kami.
### Routing
```go
func main() {
app := fiber.New()
// GET /john
app.Get("/:name", func(c *fiber.Ctx) {
fmt.Printf("Hello %s!", c.Params("name"))
// => Hello john!
})
// GET /john
app.Get("/:name/:age?", func(c *fiber.Ctx) {
fmt.Printf("Name: %s, Age: %s", c.Params("name"), c.Params("age"))
// => Name: john, Age:
})
// GET /api/register
app.Get("/api*", func(c *fiber.Ctx) {
fmt.Printf("/api%s", c.Params("*"))
// => /api/register
})
app.Listen(3000)
}
```
### Menyajikan file statis
https://fiber.wiki/application#static
```go
func main() {
app := fiber.New()
app.Static("/", "/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Middleware & Next
https://fiber.wiki/routing#middleware
https://fiber.wiki/context#next
```go
func main() {
app := fiber.New()
// Match any route
app.Use(func(c *fiber.Ctx) {
fmt.Println("First middleware")
c.Next()
})
// Match all routes starting with /api
app.Use("/api", func(c *fiber.Ctx) {
fmt.Println("Second middleware")
c.Next()
})
// POST /api/register
app.Post("/api/register", func(c *fiber.Ctx) {
fmt.Println("Last middleware")
c.Send("Hello, World!")
})
app.Listen(3000)
}
```
<details>
<summary>📚 Perlihatkan contoh lainnya</summary>
### Template engines
https://fiber.wiki/application#settings
https://fiber.wiki/context#render
Mendukung:
- [html](https://golang.org/pkg/html/template/)
- [amber](https://github.com/eknkc/amber)
- [handlebars](https://github.com/aymerick/raymond)
- [mustache](https://github.com/cbroglie/mustache)
- [pug](https://github.com/Joker/jade)
```go
func main() {
// You can setup template engine before initiation app:
app := fiber.New(&fiber.Settings{
TemplateEngine: "mustache",
TemplateFolder: "./views",
TemplateExtension: ".tmpl",
})
// OR after initiation app at any convenient location:
app.Settings.TemplateEngine = "mustache"
app.Settings.TemplateFolder = "./views"
app.Settings.TemplateExtension = ".tmpl"
// And now, you can call template `./views/home.tmpl` like this:
app.Get("/", func(c *fiber.Ctx) {
c.Render("home", fiber.Map{
"title": "Homepage",
"year": 1999,
})
})
// ...
}
```
### Pengelompokan routes
https://fiber.wiki/application#group
```go
func main() {
app := fiber.New()
// Root API route
api := app.Group("/api", cors()) // /api
// API v1 routes
v1 := api.Group("/v1", mysql()) // /api/v1
v1.Get("/list", handler) // /api/v1/list
v1.Get("/user", handler) // /api/v1/user
// API v2 routes
v2 := api.Group("/v2", mongodb()) // /api/v2
v2.Get("/list", handler) // /api/v2/list
v2.Get("/user", handler) // /api/v2/user
// ...
}
```
### Middleware logger
https://fiber.wiki/middleware#logger
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// If you want to change default Logger config
loggerConfig := middleware.LoggerConfig{
Format: "${time} - ${method} ${path}\n",
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
}
// Middleware for Logger with config
app.Use(middleware.Logger(loggerConfig))
// ...
}
```
### Cross-Origin Resource Sharing (CORS)
https://fiber.wiki/middleware#cors
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) adalah mekanisme yang menggunakan HTTP headers tambahan untuk memberitahu browser bahwa aplikasi/data kita hanya bisa diakses dari sumber (origin) tertentu, atau bisa juga diakses dari sumber berbeda. Aplikasi web memproses cross-origin HTTP request ketika request-nya berasal dari sumber berbeda (domain, protokol dan port).
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// Connect CORS for each route as middleware
app.Use(middleware.CORS())
app.Get("/", func(c *fiber.Ctx) {
c.Send("CORS is enabled!")
})
app.Listen(3000)
}
```
Setelah diaktifkan, bisa dicoba dengan cara memberi sumber/domain berbeda di header `Origin`:
```bash
curl -H "Origin: http://example.com" --verbose http://localhost:3000
```
### Respon 404
```go
func main() {
app := fiber.New()
app.Static("/public")
app.Get("/demo", func(c *fiber.Ctx) {
c.Send("This is a demo!")
})
app.Post("/register", func(c *fiber.Ctx) {
c.Send("Welcome!")
})
// Last middleware to match anything
app.Use(func(c *fiber.Ctx) {
c.SendStatus(404) // => 404 "Not Found"
})
app.Listen(3000)
}
```
### Respon JSON
https://fiber.wiki/context#json
```go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
app := fiber.New()
app.Get("/user", func(c *fiber.Ctx) {
c.JSON(&User{"John", 20})
// {"name":"John", "age":20}
})
app.Get("/json", func(c *fiber.Ctx) {
c.JSON(&fiber.Map{
"success": true,
"message": "Hi John!",
})
// {"success":true, "message":"Hi John!"}
})
app.Listen(3000)
}
```
### Dukungan WebSocket
https://fiber.wiki/application#websocket
```go
func main() {
app := fiber.New()
app.WebSocket("/ws", func(c *fiber.Conn) {
for {
mt, msg, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recovery: %s", msg)
err = c.WriteMessage(mt, msg)
if err != nil {
log.Println("write:", err)
break
}
}
})
// Listen on ws://localhost:3000/ws
app.Listen(3000)
}
```
### Recover middleware
https://fiber.wiki/middleware#recover
```go
package main
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
log.Println(err) // "Something went wrong!"
c.SendStatus(500) // Internal Server Error
})))
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
})
app.Listen(3000)
}
```
</details>
## 💬 Media
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) (_by [Vic Shóstak](https://github.com/koddr), 03 Feb 2020_)
- [Fiber release v1.7 is out now! 🎉 What's new and is he still fast, flexible and friendly?](https://dev.to/koddr/fiber-v2-is-out-now-what-s-new-and-is-he-still-fast-flexible-and-friendly-3ipf) (_by [Vic Shóstak](https://github.com/koddr), 21 Feb 2020_)
## 👍 Berkontribusi
Apabila anda ingin mengucapkan **terima kasih** dan/atau mendukung pengembangan `Fiber`:
1. Berikan bintang atau [GitHub Star](https://github.com/gofiber/fiber/stargazers) ke proyek ini.
2. Bagikan [di Twitter anda](https://twitter.com/intent/tweet?text=%F0%9F%9A%80%20Fiber%20%E2%80%94%20is%20an%20Express.js%20inspired%20web%20framework%20build%20on%20Fasthttp%20for%20%23Go%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
3. Buat ulasan atau tutorial di [Medium](https://medium.com/), [Dev.to](https://dev.to/) atau blog pribadi anda.
4. Bantu kami menerjemahkan `README` ini ke bahasa lainnya.
## ☕ Para Pendukung
<a href="https://www.buymeacoffee.com/fenny" target="_blank">
<img src="https://github.com/gofiber/docs/blob/master/static/buy-morning-coffee-3x.gif" alt="Buy Me A Coffee" height="100" >
</a>
<table>
<tr>
<td align="center">
<a href="https://github.com/gofiber/fiber">
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
<sub><b>JustDave</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bihe">
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
<sub><b>HenrikBinggl</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/koddr">
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
<sub><b>Vic&nbsp;Shóstak</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/MarvinJWendt">
<img src="https://avatars1.githubusercontent.com/u/31022056?s=460&v=4" width="100px"></br>
<sub><b>MarvinJWendt</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/toishy">
<img src="https://avatars1.githubusercontent.com/u/31921460?s=460&v=4" width="100px"></br>
<sub><b>ToishY</b></sub>
</a>
</td>
</tr>
</table>
## ⭐️ Bintang
<a href="https://starchart.cc/gofiber/fiber" rel="nofollow"><img src="https://starchart.cc/gofiber/fiber.svg" alt="Stars over time" style="max-width:100%;"></a>
## ⚠️ Lisensi
`Fiber` adalah perangkat lunak gratis dengan sumber terbuka berlisensi [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE).
[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/0)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/0)[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/1)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/1)[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/2)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/2)[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/3)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/3)[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/4)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/4)[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/5)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/5)[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/6)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/6)[![](https://sourcerer.io/fame/Fenny/gofiber/fiber/images/7)](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/7)

252
.github/README_ja.md vendored
View File

@ -33,6 +33,9 @@
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
</a>
<br><br>
<a href="https://github.com/gofiber/fiber/releases">
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
@ -126,27 +129,6 @@ Fiberは人気の高いWebフレームワークであるExpressjsに**インス
以下に一般的な例をいくつか示します。他のコード例をご覧になりたい場合は、 [Recipesリポジトリ](https://github.com/gofiber/recipes)または[APIドキュメント](https://fiber.wiki)にアクセスしてください。
### Serve static files
```go
func main() {
app := fiber.New()
app.Static("/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Routing
```go
@ -175,8 +157,30 @@ func main() {
}
```
### Middleware & Next
### Serve static files
https://fiber.wiki/application#static
```go
func main() {
app := fiber.New()
app.Static("/", "/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Middleware & Next
https://fiber.wiki/routing#middleware
https://fiber.wiki/context#next
```go
func main() {
app := fiber.New()
@ -204,7 +208,122 @@ func main() {
```
<details>
<summary>📜 Show more code examples</summary>
<summary>📚 Show more code examples</summary>
### Template engines
https://fiber.wiki/application#settings
https://fiber.wiki/context#render
Supported engines:
- [html](https://golang.org/pkg/html/template/)
- [amber](https://github.com/eknkc/amber)
- [handlebars](https://github.com/aymerick/raymond)
- [mustache](https://github.com/cbroglie/mustache)
- [pug](https://github.com/Joker/jade)
```go
func main() {
// You can setup template engine before initiation app:
app := fiber.New(&fiber.Settings{
TemplateEngine: "mustache",
TemplateFolder: "./views",
TemplateExtension: ".tmpl",
})
// OR after initiation app at any convenient location:
app.Settings.TemplateEngine = "mustache"
app.Settings.TemplateFolder = "./views"
app.Settings.TemplateExtension = ".tmpl"
// And now, you can call template `./views/home.tmpl` like this:
app.Get("/", func(c *fiber.Ctx) {
c.Render("home", fiber.Map{
"title": "Homepage",
"year": 1999,
})
})
// ...
}
```
### Grouping routes into chains
https://fiber.wiki/application#group
```go
func main() {
app := fiber.New()
// Root API route
api := app.Group("/api", cors()) // /api
// API v1 routes
v1 := api.Group("/v1", mysql()) // /api/v1
v1.Get("/list", handler) // /api/v1/list
v1.Get("/user", handler) // /api/v1/user
// API v2 routes
v2 := api.Group("/v2", mongodb()) // /api/v2
v2.Get("/list", handler) // /api/v2/list
v2.Get("/user", handler) // /api/v2/user
// ...
}
```
### Middleware logger
https://fiber.wiki/middleware#logger
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// If you want to change default Logger config
loggerConfig := middleware.LoggerConfig{
Format: "${time} - ${method} ${path}\n",
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
}
// Middleware for Logger with config
app.Use(middleware.Logger(loggerConfig))
// ...
}
```
### Cross-Origin Resource Sharing (CORS)
https://fiber.wiki/middleware#cors
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// Connect CORS for each route as middleware
app.Use(middleware.CORS())
app.Get("/", func(c *fiber.Ctx) {
c.Send("CORS is enabled!")
})
app.Listen(3000)
}
```
Check CORS by passing any domain in `Origin` header:
```bash
curl -H "Origin: http://example.com" --verbose http://localhost:3000
```
### Custom 404 response
@ -213,9 +332,11 @@ func main() {
app := fiber.New()
app.Static("/public")
app.Get("/demo", func(c *fiber.Ctx) {
c.Send("This is a demo!")
})
app.Post("/register", func(c *fiber.Ctx) {
c.Send("Welcome!")
})
@ -230,46 +351,89 @@ func main() {
```
### JSON Response
https://fiber.wiki/context#json
```go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
app := fiber.New()
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// Serialize JSON
app.Get("/json", func(c *fiber.Ctx) {
app.Get("/user", func(c *fiber.Ctx) {
c.JSON(&User{"John", 20})
// => {"name":"John", "age":20}
// {"name":"John", "age":20}
})
app.Get("/json", func(c *fiber.Ctx) {
c.JSON(&fiber.Map{
"success": true,
"message": "Hi John!",
})
// {"success":true, "message":"Hi John!"}
})
app.Listen(3000)
}
```
### Recover from panic
### WebSocket support
https://fiber.wiki/application#websocket
```go
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
app.WebSocket("/ws", func(c *fiber.Conn) {
for {
mt, msg, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recovery: %s", msg)
err = c.WriteMessage(mt, msg)
if err != nil {
log.Println("write:", err)
break
}
}
})
app.Recover(func(c *fiber.Ctx) {
c.Status(500).Send(c.Error())
// => 500 "Something went wrong!"
// Listen on ws://localhost:3000/ws
app.Listen(3000)
}
```
### Recover middleware
https://fiber.wiki/middleware#recover
```go
package main
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
log.Println(err) // "Something went wrong!"
c.SendStatus(500) // Internal Server Error
})))
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
})
app.Listen(3000)
}
```
</details>
## 💬 メディア
- [ファイバーへようこそ— Go with❤で記述されたExpress.jsスタイルのWebフレームワーク](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) *[ヴィック・ショースタク](https://github.com/koddr) 、2020年2月3日*
@ -292,6 +456,12 @@ func main() {
</a>
<table>
<tr>
<td align="center">
<a href="https://github.com/gofiber/fiber">
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
<sub><b>JustDave</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bihe">
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
@ -301,7 +471,7 @@ func main() {
<td align="center">
<a href="https://github.com/koddr">
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
<sub><b>koddr</b></sub>
<sub><b>Vic&nbsp;Shóstak</b></sub>
</a>
</td>
<td align="center">

251
.github/README_ko.md vendored
View File

@ -33,6 +33,9 @@
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
</a>
<br><br>
<a href="https://github.com/gofiber/fiber/releases">
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
@ -122,27 +125,6 @@ Fiber는 인터넷에서 가장 인기있는 웹 프레임워크인 Express에
다음은 일반적인 예제들 입니다. 더 많은 코드 예제를 보고 싶다면, [Recipes 저장소](https://github.com/gofiber/recipes) 또는 [API 문서](https://fiber.wiki)를 방문하세요.
### Serve static files
```go
func main() {
app := fiber.New()
app.Static("/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "./public/index.html")
// => http://localhost:3000/anything/returns/the/index/file
app.Listen(3000)
}
```
### Routing
```go
@ -171,8 +153,30 @@ func main() {
}
```
### Middleware & Next
### Serve static files
https://fiber.wiki/application#static
```go
func main() {
app := fiber.New()
app.Static("/", "/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Middleware & Next
https://fiber.wiki/routing#middleware
https://fiber.wiki/context#next
```go
func main() {
app := fiber.New()
@ -200,7 +204,122 @@ func main() {
```
<details>
<summary>📜 Show more code examples</summary>
<summary>📚 Show more code examples</summary>
### Template engines
https://fiber.wiki/application#settings
https://fiber.wiki/context#render
Supported engines:
- [html](https://golang.org/pkg/html/template/)
- [amber](https://github.com/eknkc/amber)
- [handlebars](https://github.com/aymerick/raymond)
- [mustache](https://github.com/cbroglie/mustache)
- [pug](https://github.com/Joker/jade)
```go
func main() {
// You can setup template engine before initiation app:
app := fiber.New(&fiber.Settings{
TemplateEngine: "mustache",
TemplateFolder: "./views",
TemplateExtension: ".tmpl",
})
// OR after initiation app at any convenient location:
app.Settings.TemplateEngine = "mustache"
app.Settings.TemplateFolder = "./views"
app.Settings.TemplateExtension = ".tmpl"
// And now, you can call template `./views/home.tmpl` like this:
app.Get("/", func(c *fiber.Ctx) {
c.Render("home", fiber.Map{
"title": "Homepage",
"year": 1999,
})
})
// ...
}
```
### Grouping routes into chains
https://fiber.wiki/application#group
```go
func main() {
app := fiber.New()
// Root API route
api := app.Group("/api", cors()) // /api
// API v1 routes
v1 := api.Group("/v1", mysql()) // /api/v1
v1.Get("/list", handler) // /api/v1/list
v1.Get("/user", handler) // /api/v1/user
// API v2 routes
v2 := api.Group("/v2", mongodb()) // /api/v2
v2.Get("/list", handler) // /api/v2/list
v2.Get("/user", handler) // /api/v2/user
// ...
}
```
### Middleware logger
https://fiber.wiki/middleware#logger
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// If you want to change default Logger config
loggerConfig := middleware.LoggerConfig{
Format: "${time} - ${method} ${path}\n",
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
}
// Middleware for Logger with config
app.Use(middleware.Logger(loggerConfig))
// ...
}
```
### Cross-Origin Resource Sharing (CORS)
https://fiber.wiki/middleware#cors
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// Connect CORS for each route as middleware
app.Use(middleware.CORS())
app.Get("/", func(c *fiber.Ctx) {
c.Send("CORS is enabled!")
})
app.Listen(3000)
}
```
Check CORS by passing any domain in `Origin` header:
```bash
curl -H "Origin: http://example.com" --verbose http://localhost:3000
```
### Custom 404 response
@ -209,9 +328,11 @@ func main() {
app := fiber.New()
app.Static("/public")
app.Get("/demo", func(c *fiber.Ctx) {
c.Send("This is a demo!")
})
app.Post("/register", func(c *fiber.Ctx) {
c.Send("Welcome!")
})
@ -226,40 +347,82 @@ func main() {
```
### JSON Response
https://fiber.wiki/context#json
```go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
app := fiber.New()
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// Serialize JSON
app.Get("/json", func(c *fiber.Ctx) {
app.Get("/user", func(c *fiber.Ctx) {
c.JSON(&User{"John", 20})
// => {"name":"John", "age":20}
// {"name":"John", "age":20}
})
app.Get("/json", func(c *fiber.Ctx) {
c.JSON(&fiber.Map{
"success": true,
"message": "Hi John!",
})
// {"success":true, "message":"Hi John!"}
})
app.Listen(3000)
}
```
### Recover from panic
### WebSocket support
https://fiber.wiki/application#websocket
```go
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
app.WebSocket("/ws", func(c *fiber.Conn) {
for {
mt, msg, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recovery: %s", msg)
err = c.WriteMessage(mt, msg)
if err != nil {
log.Println("write:", err)
break
}
}
})
app.Recover(func(c *fiber.Ctx) {
c.Status(500).Send(c.Error())
// => 500 "Something went wrong!"
// Listen on ws://localhost:3000/ws
app.Listen(3000)
}
```
### Recover middleware
https://fiber.wiki/middleware#recover
```go
package main
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
log.Println(err) // "Something went wrong!"
c.SendStatus(500) // Internal Server Error
})))
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
})
app.Listen(3000)
@ -287,6 +450,12 @@ func main() {
</a>
<table>
<tr>
<td align="center">
<a href="https://github.com/gofiber/fiber">
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
<sub><b>JustDave</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bihe">
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
@ -296,7 +465,7 @@ func main() {
<td align="center">
<a href="https://github.com/koddr">
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
<sub><b>koddr</b></sub>
<sub><b>Vic&nbsp;Shóstak</b></sub>
</a>
</td>
<td align="center">

251
.github/README_pt.md vendored
View File

@ -33,6 +33,9 @@
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
</a>
<br><br>
<a href="https://github.com/gofiber/fiber/releases">
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
@ -122,27 +125,6 @@ O Fiber é **inspirado** no Express, o framework web mais popular da Internet. C
Listados abaixo estão alguns exemplos comuns. Se você quiser ver mais exemplos de código, visite nosso [repositório de receitas](https://github.com/gofiber/recipes) ou a [documentação da API](https://fiber.wiki).
### Serve static files
```go
func main() {
app := fiber.New()
app.Static("/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Routing
```go
@ -171,8 +153,30 @@ func main() {
}
```
### Middleware & Next
### Serve static files
https://fiber.wiki/application#static
```go
func main() {
app := fiber.New()
app.Static("/", "/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Listen(3000)
}
```
### Middleware & Next
https://fiber.wiki/routing#middleware
https://fiber.wiki/context#next
```go
func main() {
app := fiber.New()
@ -200,7 +204,122 @@ func main() {
```
<details>
<summary>📜 Show more code examples</summary>
<summary>📚 Show more code examples</summary>
### Template engines
https://fiber.wiki/application#settings
https://fiber.wiki/context#render
Supported engines:
- [html](https://golang.org/pkg/html/template/)
- [amber](https://github.com/eknkc/amber)
- [handlebars](https://github.com/aymerick/raymond)
- [mustache](https://github.com/cbroglie/mustache)
- [pug](https://github.com/Joker/jade)
```go
func main() {
// You can setup template engine before initiation app:
app := fiber.New(&fiber.Settings{
TemplateEngine: "mustache",
TemplateFolder: "./views",
TemplateExtension: ".tmpl",
})
// OR after initiation app at any convenient location:
app.Settings.TemplateEngine = "mustache"
app.Settings.TemplateFolder = "./views"
app.Settings.TemplateExtension = ".tmpl"
// And now, you can call template `./views/home.tmpl` like this:
app.Get("/", func(c *fiber.Ctx) {
c.Render("home", fiber.Map{
"title": "Homepage",
"year": 1999,
})
})
// ...
}
```
### Grouping routes into chains
https://fiber.wiki/application#group
```go
func main() {
app := fiber.New()
// Root API route
api := app.Group("/api", cors()) // /api
// API v1 routes
v1 := api.Group("/v1", mysql()) // /api/v1
v1.Get("/list", handler) // /api/v1/list
v1.Get("/user", handler) // /api/v1/user
// API v2 routes
v2 := api.Group("/v2", mongodb()) // /api/v2
v2.Get("/list", handler) // /api/v2/list
v2.Get("/user", handler) // /api/v2/user
// ...
}
```
### Middleware logger
https://fiber.wiki/middleware#logger
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// If you want to change default Logger config
loggerConfig := middleware.LoggerConfig{
Format: "${time} - ${method} ${path}\n",
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
}
// Middleware for Logger with config
app.Use(middleware.Logger(loggerConfig))
// ...
}
```
### Cross-Origin Resource Sharing (CORS)
https://fiber.wiki/middleware#cors
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// Connect CORS for each route as middleware
app.Use(middleware.CORS())
app.Get("/", func(c *fiber.Ctx) {
c.Send("CORS is enabled!")
})
app.Listen(3000)
}
```
Check CORS by passing any domain in `Origin` header:
```bash
curl -H "Origin: http://example.com" --verbose http://localhost:3000
```
### Custom 404 response
@ -209,9 +328,11 @@ func main() {
app := fiber.New()
app.Static("/public")
app.Get("/demo", func(c *fiber.Ctx) {
c.Send("This is a demo!")
})
app.Post("/register", func(c *fiber.Ctx) {
c.Send("Welcome!")
})
@ -226,40 +347,82 @@ func main() {
```
### JSON Response
https://fiber.wiki/context#json
```go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
app := fiber.New()
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// Serialize JSON
app.Get("/json", func(c *fiber.Ctx) {
app.Get("/user", func(c *fiber.Ctx) {
c.JSON(&User{"John", 20})
// => {"name":"John", "age":20}
// {"name":"John", "age":20}
})
app.Get("/json", func(c *fiber.Ctx) {
c.JSON(&fiber.Map{
"success": true,
"message": "Hi John!",
})
// {"success":true, "message":"Hi John!"}
})
app.Listen(3000)
}
```
### Recover from panic
### WebSocket support
https://fiber.wiki/application#websocket
```go
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
app.WebSocket("/ws", func(c *fiber.Conn) {
for {
mt, msg, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recovery: %s", msg)
err = c.WriteMessage(mt, msg)
if err != nil {
log.Println("write:", err)
break
}
}
})
app.Recover(func(c *fiber.Ctx) {
c.Status(500).Send(c.Error())
// => 500 "Something went wrong!"
// Listen on ws://localhost:3000/ws
app.Listen(3000)
}
```
### Recover middleware
https://fiber.wiki/middleware#recover
```go
package main
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
log.Println(err) // "Something went wrong!"
c.SendStatus(500) // Internal Server Error
})))
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
})
app.Listen(3000)
@ -287,6 +450,12 @@ Se você quer **agradecer** e/ou apoiar o desenvolvimento ativo do `Fiber`:
</a>
<table>
<tr>
<td align="center">
<a href="https://github.com/gofiber/fiber">
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
<sub><b>JustDave</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bihe">
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
@ -296,7 +465,7 @@ Se você quer **agradecer** e/ou apoiar o desenvolvimento ativo do `Fiber`:
<td align="center">
<a href="https://github.com/koddr">
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
<sub><b>koddr</b></sub>
<sub><b>Vic&nbsp;Shóstak</b></sub>
</a>
</td>
<td align="center">

View File

@ -33,6 +33,9 @@
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
</a>
<br><br>
<a href="https://github.com/gofiber/fiber/releases">
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
@ -438,6 +441,12 @@ func main() {
</a>
<table>
<tr>
<td align="center">
<a href="https://github.com/gofiber/fiber">
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
<sub><b>JustDave</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bihe">
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>

223
.github/README_tr.md vendored
View File

@ -30,6 +30,9 @@
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
</a>
<br><br>
<a href="https://github.com/gofiber/fiber/releases">
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
@ -119,7 +122,7 @@ Fiber internet üzerinde en popüler olan Express web çatısından **esinlenmi
Aşağıda yaygın örneklerden bazıları listelenmiştir. Daha fazla kod örneği görmek için, lütfen [Kod depomuzu](https://github.com/gofiber/recipes) veya [API dökümantasyonunu](https://fiber.wiki) ziyaret ediniz.
### Rotalar
### Routing
```go
func main() {
@ -147,13 +150,13 @@ func main() {
}
```
### Statik dosya yönetimi
### Serve static files
https://fiber.wiki/application#static
```go
func main() {
app := fiber.New()
app.Static("/public")
app.Static("/", "/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
@ -168,8 +171,9 @@ func main() {
}
```
### Ara Katman & Sonraki
### Middleware & Next
https://fiber.wiki/routing#middleware
https://fiber.wiki/context#next
```go
func main() {
app := fiber.New()
@ -197,18 +201,135 @@ func main() {
```
<details>
<summary>📚 Daha fazla kod örneği görüntüle</summary>
<summary>📚 Show more code examples</summary>
### Özel 404 Cevabı
### Template engines
https://fiber.wiki/application#settings
https://fiber.wiki/context#render
Supported engines:
- [html](https://golang.org/pkg/html/template/)
- [amber](https://github.com/eknkc/amber)
- [handlebars](https://github.com/aymerick/raymond)
- [mustache](https://github.com/cbroglie/mustache)
- [pug](https://github.com/Joker/jade)
```go
func main() {
// You can setup template engine before initiation app:
app := fiber.New(&fiber.Settings{
TemplateEngine: "mustache",
TemplateFolder: "./views",
TemplateExtension: ".tmpl",
})
// OR after initiation app at any convenient location:
app.Settings.TemplateEngine = "mustache"
app.Settings.TemplateFolder = "./views"
app.Settings.TemplateExtension = ".tmpl"
// And now, you can call template `./views/home.tmpl` like this:
app.Get("/", func(c *fiber.Ctx) {
c.Render("home", fiber.Map{
"title": "Homepage",
"year": 1999,
})
})
// ...
}
```
### Grouping routes into chains
https://fiber.wiki/application#group
```go
func main() {
app := fiber.New()
// Root API route
api := app.Group("/api", cors()) // /api
// API v1 routes
v1 := api.Group("/v1", mysql()) // /api/v1
v1.Get("/list", handler) // /api/v1/list
v1.Get("/user", handler) // /api/v1/user
// API v2 routes
v2 := api.Group("/v2", mongodb()) // /api/v2
v2.Get("/list", handler) // /api/v2/list
v2.Get("/user", handler) // /api/v2/user
// ...
}
```
### Middleware logger
https://fiber.wiki/middleware#logger
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// If you want to change default Logger config
loggerConfig := middleware.LoggerConfig{
Format: "${time} - ${method} ${path}\n",
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
}
// Middleware for Logger with config
app.Use(middleware.Logger(loggerConfig))
// ...
}
```
### Cross-Origin Resource Sharing (CORS)
https://fiber.wiki/middleware#cors
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// Connect CORS for each route as middleware
app.Use(middleware.CORS())
app.Get("/", func(c *fiber.Ctx) {
c.Send("CORS is enabled!")
})
app.Listen(3000)
}
```
Check CORS by passing any domain in `Origin` header:
```bash
curl -H "Origin: http://example.com" --verbose http://localhost:3000
```
### Custom 404 response
```go
func main() {
app := fiber.New()
app.Static("/public")
app.Get("/demo", func(c *fiber.Ctx) {
c.Send("This is a demo!")
})
app.Post("/register", func(c *fiber.Ctx) {
c.Send("Welcome!")
})
@ -222,41 +343,83 @@ func main() {
}
```
### JSON Cevabı
### JSON Response
https://fiber.wiki/context#json
```go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
app := fiber.New()
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// Serialize JSON
app.Get("/json", func(c *fiber.Ctx) {
app.Get("/user", func(c *fiber.Ctx) {
c.JSON(&User{"John", 20})
// => {"name":"John", "age":20}
// {"name":"John", "age":20}
})
app.Get("/json", func(c *fiber.Ctx) {
c.JSON(&fiber.Map{
"success": true,
"message": "Hi John!",
})
// {"success":true, "message":"Hi John!"}
})
app.Listen(3000)
}
```
### Panikten Kurtarma
### WebSocket support
https://fiber.wiki/application#websocket
```go
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
app.WebSocket("/ws", func(c *fiber.Conn) {
for {
mt, msg, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recovery: %s", msg)
err = c.WriteMessage(mt, msg)
if err != nil {
log.Println("write:", err)
break
}
}
})
app.Recover(func(c *fiber.Ctx) {
c.Status(500).Send(c.Error())
// => 500 "Something went wrong!"
// Listen on ws://localhost:3000/ws
app.Listen(3000)
}
```
### Recover middleware
https://fiber.wiki/middleware#recover
```go
package main
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
log.Println(err) // "Something went wrong!"
c.SendStatus(500) // Internal Server Error
})))
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
})
app.Listen(3000)
@ -286,6 +449,12 @@ Eğer **teşekkür etmek** ve/veya `Fiber` ın aktif geliştirilmesini destekle
<table>
<tr>
<td align="center">
<a href="https://github.com/gofiber/fiber">
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
<sub><b>JustDave</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bihe">
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
@ -295,7 +464,7 @@ Eğer **teşekkür etmek** ve/veya `Fiber` ın aktif geliştirilmesini destekle
<td align="center">
<a href="https://github.com/koddr">
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
<sub><b>Vic Shóstak</b></sub>
<sub><b>Vic&nbsp;Shóstak</b></sub>
</a>
</td>
<td align="center">

View File

@ -30,6 +30,9 @@
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
</a>
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
</a>
<br><br>
<a href="https://github.com/gofiber/fiber/releases">
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
@ -118,7 +121,7 @@ Fiber **受** Internet上最流行的Web框架Expressjs的**启发** 。我们
下面列出了一些常见示例。如果您想查看更多代码示例,请访问我们的[Recipes存储库](https://github.com/gofiber/recipes)或访问我们的[API文档](https://fiber.wiki) 。
### 路由
### Routing
```go
func main() {
@ -146,13 +149,13 @@ func main() {
}
```
### 静态文件
### Serve static files
https://fiber.wiki/application#static
```go
func main() {
app := fiber.New()
app.Static("/public")
app.Static("/", "/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
@ -167,8 +170,9 @@ func main() {
}
```
### 中间件
### Middleware & Next
https://fiber.wiki/routing#middleware
https://fiber.wiki/context#next
```go
func main() {
app := fiber.New()
@ -196,12 +200,13 @@ func main() {
```
<details>
<summary>📚 显示更多代码示例</summary>
<summary>📚 Show more code examples</summary>
### 模板引擎
已经支持的:
### Template engines
https://fiber.wiki/application#settings
https://fiber.wiki/context#render
Supported engines:
- [html](https://golang.org/pkg/html/template/)
- [amber](https://github.com/eknkc/amber)
- [handlebars](https://github.com/aymerick/raymond)
@ -234,8 +239,8 @@ func main() {
}
```
### 组路由
### Grouping routes into chains
https://fiber.wiki/application#group
```go
func main() {
app := fiber.New()
@ -257,16 +262,73 @@ func main() {
}
```
### 自定义 404 响应
### Middleware logger
https://fiber.wiki/middleware#logger
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// If you want to change default Logger config
loggerConfig := middleware.LoggerConfig{
Format: "${time} - ${method} ${path}\n",
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
}
// Middleware for Logger with config
app.Use(middleware.Logger(loggerConfig))
// ...
}
```
### Cross-Origin Resource Sharing (CORS)
https://fiber.wiki/middleware#cors
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
```go
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
// Connect CORS for each route as middleware
app.Use(middleware.CORS())
app.Get("/", func(c *fiber.Ctx) {
c.Send("CORS is enabled!")
})
app.Listen(3000)
}
```
Check CORS by passing any domain in `Origin` header:
```bash
curl -H "Origin: http://example.com" --verbose http://localhost:3000
```
### Custom 404 response
```go
func main() {
app := fiber.New()
app.Static("/public")
app.Get("/demo", func(c *fiber.Ctx) {
c.Send("This is a demo!")
})
app.Post("/register", func(c *fiber.Ctx) {
c.Send("Welcome!")
})
@ -280,36 +342,41 @@ func main() {
}
```
### JSON
### JSON Response
https://fiber.wiki/context#json
```go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
app := fiber.New()
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// Serialize JSON
app.Get("/json", func(c *fiber.Ctx) {
app.Get("/user", func(c *fiber.Ctx) {
c.JSON(&User{"John", 20})
// => {"name":"John", "age":20}
// {"name":"John", "age":20}
})
app.Get("/json", func(c *fiber.Ctx) {
c.JSON(&fiber.Map{
"success": true,
"message": "Hi John!",
})
// {"success":true, "message":"Hi John!"}
})
app.Listen(3000)
}
```
### WebSocket
### WebSocket support
https://fiber.wiki/application#websocket
```go
func main() {
app := fiber.New()
app.WebSocket("/ws/:name", func(c *fiber.Conn) {
log.Println(c.Params("name"))
app.WebSocket("/ws", func(c *fiber.Conn) {
for {
mt, msg, err := c.ReadMessage()
if err != nil {
@ -327,26 +394,33 @@ func main() {
}
})
// Listen on ws://localhost:3000/ws/john
// Listen on ws://localhost:3000/ws
app.Listen(3000)
}
```
### 从 panic 中恢复
### Recover middleware
https://fiber.wiki/middleware#recover
```go
package main
import (
"github.com/gofiber/fiber"
"github.com/gofiber/fiber/middleware"
)
func main() {
app := fiber.New()
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
log.Println(err) // "Something went wrong!"
c.SendStatus(500) // Internal Server Error
})))
app.Get("/", func(c *fiber.Ctx) {
panic("Something went wrong!")
})
app.Recover(func(c *fiber.Ctx) {
c.Status(500).Send(c.Error())
// => 500 "Something went wrong!"
})
app.Listen(3000)
}
```
@ -374,6 +448,12 @@ func main() {
</a>
<table>
<tr>
<td align="center">
<a href="https://github.com/gofiber/fiber">
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
<sub><b>JustDave</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bihe">
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
@ -383,7 +463,7 @@ func main() {
<td align="center">
<a href="https://github.com/koddr">
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
<sub><b>koddr</b></sub>
<sub><b>Vic&nbsp;Shóstak</b></sub>
</a>
</td>
<td align="center">

170
app.go
View File

@ -6,6 +6,7 @@ package fiber
import (
"bufio"
"crypto/tls"
"flag"
"fmt"
"io/ioutil"
@ -25,26 +26,26 @@ import (
)
// Version of Fiber
const Version = "1.8.0"
const Version = "1.8.2"
type (
// App denotes the Fiber application.
App struct {
server *fasthttp.Server
routes []*Route
child bool
recover func(*Ctx)
Settings *Settings
server *fasthttp.Server // Fasthttp server settings
routes []*Route // Route stack
child bool // If current process is a child ( for prefork )
recover func(*Ctx) // Deprecated, use middleware.Recover
Settings *Settings // Fiber settings
}
// Map defines a generic map of type `map[string]interface{}`.
Map map[string]interface{}
// Settings is a struct holding the server settings
Settings struct {
// fiber settings
// This will spawn multiple Go processes listening on the same port
Prefork bool `default:"false"`
// Enable strict routing. When enabled, the router treats "/foo" and "/foo/" as different. Otherwise, the router treats "/foo" and "/foo/" as the same.
// Enable strict routing. When enabled, the router treats "/foo" and "/foo/" as different.
StrictRouting bool `default:"false"`
// Enable case sensitivity. When enabled, "/Foo" and "/foo" are different routes. When disabled, "/Foo" and "/foo" are treated the same.
// Enable case sensitivity. When enabled, "/Foo" and "/foo" are different routes.
CaseSensitive bool `default:"false"`
// Enables the "Server: value" HTTP header.
ServerHeader string `default:""`
@ -52,28 +53,13 @@ type (
Immutable bool `default:"false"`
// Enables GZip / Deflate compression for all responses
Compression bool `default:"false"`
// CompressionLevel int `default:"1"`
// fasthttp settings
// GETOnly bool `default:"false"`
// IdleTimeout time.Duration `default:"0"`
// Concurrency int `default:"256 * 1024"`
// ReadTimeout time.Duration `default:"0"`
// WriteTimeout time.Duration `default:"0"`
// TCPKeepalive bool `default:"false"`
// MaxConnsPerIP int `default:"0"`
// ReadBufferSize int `default:"4096"`
// WriteBufferSize int `default:"4096"`
// ConcurrencySleep time.Duration `default:"0"`
// DisableKeepAlive bool `default:"false"`
// ReduceMemoryUsage bool `default:"false"`
// MaxRequestsPerConn int `default:"0"`
// TCPKeepalivePeriod time.Duration `default:"0"`
// Max body size that the server accepts
BodyLimit int `default:"4 * 1024 * 1024"`
// NoHeaderNormalizing bool `default:"false"`
// NoDefaultContentType bool `default:"false"`
// template settings
TemplateFolder string `default:""`
TemplateEngine string `default:""`
// Folder containing template files
TemplateFolder string `default:""`
// Template engine: html, amber, handlebars , mustache or pug
TemplateEngine string `default:""`
// Extension for the template files
TemplateExtension string `default:""`
}
)
@ -84,61 +70,45 @@ func init() {
}
// New : https://fiber.wiki/application#new
func New(settings ...*Settings) (app *App) {
var prefork bool
var child bool
for _, arg := range os.Args[1:] {
if arg == "-prefork" {
func New(settings ...*Settings) *App {
var prefork, child bool
// Loop trought args without using flag.Parse()
for i := range os.Args[1:] {
if os.Args[i] == "-prefork" {
prefork = true
} else if arg == "-child" {
} else if os.Args[i] == "-child" {
child = true
}
}
app = &App{
// Create default app
app := &App{
child: child,
Settings: &Settings{
Prefork: prefork,
BodyLimit: 4 * 1024 * 1024,
},
}
// If settings exist, set some defaults
if len(settings) > 0 {
opt := settings[0]
if !opt.Prefork {
opt.Prefork = prefork
if !settings[0].Prefork { // Default to -prefork flag if false
settings[0].Prefork = prefork
}
if opt.Immutable {
getString = func(b []byte) string {
return string(b)
}
if settings[0].BodyLimit == 0 { // Default MaxRequestBodySize
settings[0].BodyLimit = 4 * 1024 * 1024
}
// if opt.Concurrency == 0 {
// opt.Concurrency = 256 * 1024
// }
// if opt.ReadBufferSize == 0 {
// opt.ReadBufferSize = 4096
// }
// if opt.WriteBufferSize == 0 {
// opt.WriteBufferSize = 4096
// }
if opt.BodyLimit == 0 {
opt.BodyLimit = 4 * 1024 * 1024
if settings[0].Immutable { // Replace unsafe conversion funcs
getString = func(b []byte) string { return string(b) }
getBytes = func(s string) []byte { return []byte(s) }
}
// if opt.CompressionLevel == 0 {
// opt.CompressionLevel = 1
// }
app.Settings = opt
return
app.Settings = settings[0] // Set custom settings
}
app.Settings = &Settings{
Prefork: prefork,
// Concurrency: 256 * 1024,
// ReadBufferSize: 4096,
// WriteBufferSize: 4096,
BodyLimit: 4 * 1024 * 1024,
}
return
return app
}
// Group : https://fiber.wiki/application#group
func (app *App) Group(prefix string, handlers ...func(*Ctx)) *Group {
if len(handlers) > 0 {
app.registerMethod("USE", prefix, "", handlers...)
app.registerMethod("USE", prefix, handlers...)
}
return &Group{
prefix: prefix,
@ -147,8 +117,8 @@ func (app *App) Group(prefix string, handlers ...func(*Ctx)) *Group {
}
// Static : https://fiber.wiki/application#static
func (app *App) Static(args ...string) *App {
app.registerStatic("/", args...)
func (app *App) Static(prefix, root string) *App {
app.registerStatic(prefix, root)
return app
}
@ -166,83 +136,84 @@ func (app *App) Use(args ...interface{}) *App {
log.Fatalf("Invalid handler: %v", reflect.TypeOf(arg))
}
}
app.registerMethod("USE", "", path, handlers...)
app.registerMethod("USE", path, handlers...)
return app
}
// Connect : https://fiber.wiki/application#http-methods
func (app *App) Connect(path string, handlers ...func(*Ctx)) *App {
app.registerMethod(http.MethodConnect, "", path, handlers...)
app.registerMethod(http.MethodConnect, path, handlers...)
return app
}
// Put : https://fiber.wiki/application#http-methods
func (app *App) Put(path string, handlers ...func(*Ctx)) *App {
app.registerMethod(http.MethodPut, "", path, handlers...)
app.registerMethod(http.MethodPut, path, handlers...)
return app
}
// Post : https://fiber.wiki/application#http-methods
func (app *App) Post(path string, handlers ...func(*Ctx)) *App {
app.registerMethod(http.MethodPost, "", path, handlers...)
app.registerMethod(http.MethodPost, path, handlers...)
return app
}
// Delete : https://fiber.wiki/application#http-methods
func (app *App) Delete(path string, handlers ...func(*Ctx)) *App {
app.registerMethod(http.MethodDelete, "", path, handlers...)
app.registerMethod(http.MethodDelete, path, handlers...)
return app
}
// Head : https://fiber.wiki/application#http-methods
func (app *App) Head(path string, handlers ...func(*Ctx)) *App {
app.registerMethod(http.MethodHead, "", path, handlers...)
app.registerMethod(http.MethodHead, path, handlers...)
return app
}
// Patch : https://fiber.wiki/application#http-methods
func (app *App) Patch(path string, handlers ...func(*Ctx)) *App {
app.registerMethod(http.MethodPatch, "", path, handlers...)
app.registerMethod(http.MethodPatch, path, handlers...)
return app
}
// Options : https://fiber.wiki/application#http-methods
func (app *App) Options(path string, handlers ...func(*Ctx)) *App {
app.registerMethod(http.MethodOptions, "", path, handlers...)
app.registerMethod(http.MethodOptions, path, handlers...)
return app
}
// Trace : https://fiber.wiki/application#http-methods
func (app *App) Trace(path string, handlers ...func(*Ctx)) *App {
app.registerMethod(http.MethodTrace, "", path, handlers...)
app.registerMethod(http.MethodTrace, path, handlers...)
return app
}
// Get : https://fiber.wiki/application#http-methods
func (app *App) Get(path string, handlers ...func(*Ctx)) *App {
app.registerMethod(http.MethodGet, "", path, handlers...)
app.registerMethod(http.MethodGet, path, handlers...)
return app
}
// All : https://fiber.wiki/application#http-methods
func (app *App) All(path string, handlers ...func(*Ctx)) *App {
app.registerMethod("ALL", "", path, handlers...)
app.registerMethod("ALL", path, handlers...)
return app
}
// WebSocket : https://fiber.wiki/application#websocket
func (app *App) WebSocket(path string, handler func(*Conn)) *App {
app.registerWebSocket(http.MethodGet, "", path, handler)
func (app *App) WebSocket(path string, handle func(*Conn)) *App {
app.registerWebSocket(http.MethodGet, path, handle)
return app
}
// Recover : https://fiber.wiki/application#recover
func (app *App) Recover(handler func(*Ctx)) {
log.Println("Warning: Recover(handler) is deprecated since v1.8.2, please use middleware.Recover(handler, error) instead.")
app.recover = handler
}
// Listen : https://fiber.wiki/application#listen
func (app *App) Listen(address interface{}, tls ...string) error {
func (app *App) Listen(address interface{}, tlsconfig ...*tls.Config) error {
addr, ok := address.(string)
if !ok {
port, ok := address.(int)
@ -273,9 +244,9 @@ func (app *App) Listen(address interface{}, tls ...string) error {
}
}
// enable TLS/HTTPS
if len(tls) > 1 {
return app.server.ServeTLS(ln, tls[0], tls[1])
// TLS config
if len(tlsconfig) > 0 {
ln = tls.NewListener(ln, tlsconfig[0])
}
return app.server.Serve(ln)
}
@ -387,26 +358,11 @@ func (dl *disableLogger) Printf(format string, args ...interface{}) {
func (app *App) newServer() *fasthttp.Server {
return &fasthttp.Server{
Handler: app.handler,
Name: app.Settings.ServerHeader,
// Concurrency: app.Settings.Concurrency,
// SleepWhenConcurrencyLimitsExceeded: app.Settings.ConcurrencySleep,
// DisableKeepalive: app.Settings.DisableKeepAlive,
// ReadBufferSize: app.Settings.ReadBufferSize,
// WriteBufferSize: app.Settings.WriteBufferSize,
// ReadTimeout: app.Settings.ReadTimeout,
// WriteTimeout: app.Settings.WriteTimeout,
// IdleTimeout: app.Settings.IdleTimeout,
// MaxConnsPerIP: app.Settings.MaxConnsPerIP,
// MaxRequestsPerConn: app.Settings.MaxRequestsPerConn,
// TCPKeepalive: app.Settings.TCPKeepalive,
// TCPKeepalivePeriod: app.Settings.TCPKeepalivePeriod,
MaxRequestBodySize: app.Settings.BodyLimit,
// ReduceMemoryUsage: app.Settings.ReduceMemoryUsage,
// GetOnly: app.Settings.GETOnly,
// DisableHeaderNamesNormalizing: app.Settings.NoHeaderNormalizing,
Handler: app.handler,
Name: app.Settings.ServerHeader,
MaxRequestBodySize: app.Settings.BodyLimit,
NoDefaultServerHeader: app.Settings.ServerHeader == "",
// NoDefaultContentType: app.Settings.NoDefaultContentType,
Logger: &disableLogger{},
LogAllErrors: false,
ErrorHandler: func(ctx *fasthttp.RequestCtx, err error) {

View File

@ -70,10 +70,9 @@ func Test_Static(t *testing.T) {
app := New()
grp := app.Group("/v1")
grp.Static("/v2", ".travis.yml")
app.Static("/yesyes*", ".github/FUNDING.yml")
app.Static("./.github")
app.Static("/*", ".github/FUNDING.yml")
app.Static("/john", "./.github")
req, _ := http.NewRequest("GET", "/stale.yml", nil)
req, _ := http.NewRequest("GET", "/john/stale.yml", nil)
resp, err := app.Test(req)
if err != nil {
t.Fatalf(`%s: %s`, t.Name(), err)

View File

@ -28,17 +28,19 @@ import (
// It has methods for the request query string, parameters, body, HTTP headers and so on.
// For more information please visit our documentation: https://fiber.wiki/context
type Ctx struct {
app *App
route *Route
next bool
error error
params *[]string
values []string
compress bool
Fasthttp *fasthttp.RequestCtx
app *App // Reference to *App
route *Route // Reference to *Route
index int // Index of the current stack
matched bool // If the context found a match in stack
method string // HTTP method
path string // HTTP path
values []string // Route parameter values
compress bool // If the response needs to be compressed
Fasthttp *fasthttp.RequestCtx // Reference to *fasthttp.RequestCtx
err error // Contains error if catched
}
// Range info of range header
// Range struct
type Range struct {
Type string
Ranges []struct {
@ -47,6 +49,17 @@ type Range struct {
}
}
// Cookie struct
type Cookie struct {
Name string
Value string
Path string
Domain string
Expires time.Time
Secure bool
HTTPOnly bool
}
// Ctx pool
var poolCtx = sync.Pool{
New: func() interface{} {
@ -55,20 +68,23 @@ var poolCtx = sync.Pool{
}
// Acquire Ctx from pool
func acquireCtx() *Ctx {
func acquireCtx(fctx *fasthttp.RequestCtx) *Ctx {
ctx := poolCtx.Get().(*Ctx)
ctx.index = -1
ctx.path = getString(fctx.URI().Path())
ctx.method = getString(fctx.Request.Header.Method())
ctx.Fasthttp = fctx
return ctx
}
// Return Ctx to pool
func releaseCtx(ctx *Ctx) {
ctx.route = nil
ctx.next = false
ctx.error = nil
ctx.params = nil
ctx.values = nil
ctx.compress = false
ctx.matched = false
ctx.Fasthttp = nil
ctx.err = nil
poolCtx.Put(ctx)
}
@ -97,17 +113,6 @@ func releaseConn(conn *Conn) {
poolConn.Put(conn)
}
// Cookie : struct
type Cookie struct {
Name string
Value string
Path string
Domain string
Expires time.Time
Secure bool
HTTPOnly bool
}
// Accepts : https://fiber.wiki/context#accepts
func (ctx *Ctx) Accepts(offers ...string) (offer string) {
if len(offers) == 0 {
@ -358,7 +363,7 @@ func (ctx *Ctx) Download(file string, name ...string) {
// Error returns err that is passed via Next(err)
func (ctx *Ctx) Error() error {
return ctx.error
return ctx.err
}
// Format : https://fiber.wiki/context#format
@ -522,12 +527,11 @@ func (ctx *Ctx) MultipartForm() (*multipart.Form, error) {
// Next : https://fiber.wiki/context#next
func (ctx *Ctx) Next(err ...error) {
ctx.route = nil
ctx.next = true
ctx.params = nil
ctx.values = nil
if len(err) > 0 {
ctx.error = err[0]
ctx.err = err[0]
}
ctx.app.nextRoute(ctx)
}
// OriginalURL : https://fiber.wiki/context#originalurl
@ -537,11 +541,11 @@ func (ctx *Ctx) OriginalURL() string {
// Params : https://fiber.wiki/context#params
func (ctx *Ctx) Params(key string) (value string) {
if ctx.params == nil {
if ctx.route.Params == nil {
return
}
for i := 0; i < len(*ctx.params); i++ {
if (*ctx.params)[i] == key {
for i := 0; i < len(ctx.route.Params); i++ {
if (ctx.route.Params)[i] == key {
return ctx.values[i]
}
}
@ -725,7 +729,7 @@ func (ctx *Ctx) SendStatus(status int) {
ctx.Fasthttp.Response.SetStatusCode(status)
// Only set status body when there is no response body
if len(ctx.Fasthttp.Response.Body()) == 0 {
ctx.Fasthttp.Response.SetBodyString(getStatus(status))
ctx.Fasthttp.Response.SetBodyString(statusMessages[status])
}
}

View File

@ -8,7 +8,6 @@ import (
"log"
"net/http"
"reflect"
"strings"
)
// Group ...
@ -19,19 +18,9 @@ type Group struct {
// Group : https://fiber.wiki/application#group
func (grp *Group) Group(prefix string, handlers ...func(*Ctx)) *Group {
if len(prefix) > 0 && prefix[0] != '/' && prefix[0] != '*' {
prefix = "/" + prefix
}
// When grouping, always remove single slash
if len(grp.prefix) > 0 && prefix == "/" {
prefix = ""
}
// Prepent group prefix if exist
prefix = grp.prefix + prefix
// Clean path by removing double "//" => "/"
prefix = strings.Replace(prefix, "//", "/", -1)
prefix = groupPaths(grp.prefix, prefix)
if len(handlers) > 0 {
grp.app.registerMethod("USE", prefix, "", handlers...)
grp.app.registerMethod("USE", prefix, handlers...)
}
return &Group{
prefix: prefix,
@ -40,8 +29,9 @@ func (grp *Group) Group(prefix string, handlers ...func(*Ctx)) *Group {
}
// Static : https://fiber.wiki/application#static
func (grp *Group) Static(args ...string) *Group {
grp.app.registerStatic(grp.prefix, args...)
func (grp *Group) Static(prefix, root string) *Group {
prefix = groupPaths(grp.prefix, prefix)
grp.app.registerStatic(prefix, root)
return grp
}
@ -56,80 +46,93 @@ func (grp *Group) Use(args ...interface{}) *Group {
case func(*Ctx):
handlers = append(handlers, arg)
default:
log.Fatalf("Invalid handlerrrr: %v", reflect.TypeOf(arg))
log.Fatalf("Invalid handler: %v", reflect.TypeOf(arg))
}
}
grp.app.registerMethod("USE", grp.prefix, path, handlers...)
path = groupPaths(grp.prefix, path)
grp.app.registerMethod("USE", path, handlers...)
return grp
}
// Connect : https://fiber.wiki/application#http-methods
func (grp *Group) Connect(path string, handlers ...func(*Ctx)) *Group {
grp.app.registerMethod(http.MethodConnect, grp.prefix, path, handlers...)
path = groupPaths(grp.prefix, path)
grp.app.registerMethod(http.MethodConnect, path, handlers...)
return grp
}
// Put : https://fiber.wiki/application#http-methods
func (grp *Group) Put(path string, handlers ...func(*Ctx)) *Group {
grp.app.registerMethod(http.MethodPut, grp.prefix, path, handlers...)
path = groupPaths(grp.prefix, path)
grp.app.registerMethod(http.MethodPut, path, handlers...)
return grp
}
// Post : https://fiber.wiki/application#http-methods
func (grp *Group) Post(path string, handlers ...func(*Ctx)) *Group {
grp.app.registerMethod(http.MethodPost, grp.prefix, path, handlers...)
path = groupPaths(grp.prefix, path)
grp.app.registerMethod(http.MethodPost, path, handlers...)
return grp
}
// Delete : https://fiber.wiki/application#http-methods
func (grp *Group) Delete(path string, handlers ...func(*Ctx)) *Group {
grp.app.registerMethod(http.MethodDelete, grp.prefix, path, handlers...)
path = groupPaths(grp.prefix, path)
grp.app.registerMethod(http.MethodDelete, path, handlers...)
return grp
}
// Head : https://fiber.wiki/application#http-methods
func (grp *Group) Head(path string, handlers ...func(*Ctx)) *Group {
grp.app.registerMethod(http.MethodHead, grp.prefix, path, handlers...)
path = groupPaths(grp.prefix, path)
grp.app.registerMethod(http.MethodHead, path, handlers...)
return grp
}
// Patch : https://fiber.wiki/application#http-methods
func (grp *Group) Patch(path string, handlers ...func(*Ctx)) *Group {
grp.app.registerMethod(http.MethodPatch, grp.prefix, path, handlers...)
path = groupPaths(grp.prefix, path)
grp.app.registerMethod(http.MethodPatch, path, handlers...)
return grp
}
// Options : https://fiber.wiki/application#http-methods
func (grp *Group) Options(path string, handlers ...func(*Ctx)) *Group {
grp.app.registerMethod(http.MethodOptions, grp.prefix, path, handlers...)
path = groupPaths(grp.prefix, path)
grp.app.registerMethod(http.MethodOptions, path, handlers...)
return grp
}
// Trace : https://fiber.wiki/application#http-methods
func (grp *Group) Trace(path string, handlers ...func(*Ctx)) *Group {
grp.app.registerMethod(http.MethodTrace, grp.prefix, path, handlers...)
path = groupPaths(grp.prefix, path)
grp.app.registerMethod(http.MethodTrace, path, handlers...)
return grp
}
// Get : https://fiber.wiki/application#http-methods
func (grp *Group) Get(path string, handlers ...func(*Ctx)) *Group {
grp.app.registerMethod(http.MethodGet, grp.prefix, path, handlers...)
path = groupPaths(grp.prefix, path)
grp.app.registerMethod(http.MethodGet, path, handlers...)
return grp
}
// All : https://fiber.wiki/application#http-methods
func (grp *Group) All(path string, handlers ...func(*Ctx)) *Group {
grp.app.registerMethod("ALL", grp.prefix, path, handlers...)
path = groupPaths(grp.prefix, path)
grp.app.registerMethod("ALL", path, handlers...)
return grp
}
// WebSocket : https://fiber.wiki/application#websocket
func (grp *Group) WebSocket(path string, handler func(*Conn)) *Group {
grp.app.registerWebSocket(http.MethodGet, grp.prefix, path, handler)
func (grp *Group) WebSocket(path string, handle func(*Conn)) *Group {
path = groupPaths(grp.prefix, path)
grp.app.registerWebSocket(http.MethodGet, path, handle)
return grp
}
// Recover : https://fiber.wiki/application#recover
func (grp *Group) Recover(handler func(*Ctx)) {
log.Println("Warning: Recover(handler) is deprecated since v1.8.2, please use middleware.Recover(handler, error) instead.")
grp.app.recover = handler
}

View File

@ -49,8 +49,8 @@ var HelmetConfigDefault = HelmetConfig{
XFrameOptions: "SAMEORIGIN",
}
// Secure ...
func Secure(config ...HelmetConfig) func(*fiber.Ctx) {
// Helmet ...
func Helmet(config ...HelmetConfig) func(*fiber.Ctx) {
// Init config
var cfg HelmetConfig
if len(config) > 0 {

View File

@ -5,6 +5,7 @@ import (
"fmt"
"io"
"os"
"strconv"
"strings"
"sync"
"time"
@ -34,7 +35,7 @@ type LoggerConfig struct {
// LoggerConfigDefault is the defaul Logger middleware config.
var LoggerConfigDefault = LoggerConfig{
Skip: nil,
Format: "${time} - ${ip} - ${method} ${path}\t${ua}\n",
Format: "${time} ${method} ${path} - ${ip} - ${status} - ${latency}ms\n",
TimeFormat: "15:04:05",
Output: os.Stderr,
}
@ -81,6 +82,11 @@ func Logger(config ...LoggerConfig) func(*fiber.Ctx) {
c.Next()
return
}
start := time.Now()
// handle request
c.Next()
// build log
stop := time.Now()
buf := pool.Get().(*bytes.Buffer)
buf.Reset()
defer pool.Put(buf)
@ -104,6 +110,10 @@ func Logger(config ...LoggerConfig) func(*fiber.Ctx) {
return buf.WriteString(c.OriginalURL())
case "ua":
return buf.WriteString(c.Get(fiber.HeaderUserAgent))
case "latency":
return buf.WriteString(stop.Sub(start).String())
case "status":
return buf.WriteString(strconv.Itoa(c.Fasthttp.Response.StatusCode()))
default:
switch {
case strings.HasPrefix(tag, "header:"):
@ -124,6 +134,5 @@ func Logger(config ...LoggerConfig) func(*fiber.Ctx) {
if _, err := cfg.Output.Write(buf.Bytes()); err != nil {
fmt.Println(err)
}
c.Next()
}
}

33
middleware/recover.go Normal file
View File

@ -0,0 +1,33 @@
package middleware
import (
"fmt"
"log"
"github.com/gofiber/fiber"
)
// Recover ...
func Recover(handle ...func(*fiber.Ctx, error)) func(*fiber.Ctx) {
h := func(c *fiber.Ctx, err error) {
log.Println(err)
c.SendStatus(500)
}
// Init custom error handler if exist
if len(handle) > 0 {
h = handle[0]
}
// Return middleware handle
return func(c *fiber.Ctx) {
defer func() {
if r := recover(); r != nil {
err, ok := r.(error)
if !ok {
err = fmt.Errorf("%v", r)
}
h(c, err)
}
}()
c.Next()
}
}

682
router.go
View File

@ -5,8 +5,8 @@
package fiber
import (
"fmt"
"log"
"os"
"path/filepath"
"regexp"
"strings"
@ -17,403 +17,311 @@ import (
// Route struct
type Route struct {
// HTTP method in uppercase, can be a * for "Use" & "All" routes
Method string
// Stores the original path
Path string
// Prefix is for ending wildcards or middleware
Prefix string
// Stores regex for complex paths
Regex *regexp.Regexp
// Stores params keys for :params / :optional? / *
Params []string
// Handler for context
HandlerCtx func(*Ctx)
// Handler for websockets
HandlerConn func(*Conn)
isMiddleware bool // is middleware route
isWebSocket bool // is websocket route
isStar bool // path == '*'
isSlash bool // path == '/'
isRegex bool // needs regex parsing
Method string // http method
Path string // orginal path
Params []string // path params
Regexp *regexp.Regexp // regexp matcher
HandleCtx func(*Ctx) // ctx handler
HandleConn func(*Conn) // conn handler
}
func (app *App) registerStatic(grpPrefix string, args ...string) {
var prefix = "/"
var root = "./"
// enable / disable gzipping somewhere?
// todo v2.0.0
gzip := true
if len(args) == 1 {
root = args[0]
}
if len(args) == 2 {
prefix = args[0]
root = args[1]
}
// A non wildcard path must start with a '/'
if prefix != "*" && len(prefix) > 0 && prefix[0] != '/' {
prefix = "/" + prefix
}
// Prepend group prefix
if len(grpPrefix) > 0 {
// `/v1`+`/` => `/v1`+``
if prefix == "/" {
prefix = grpPrefix
} else {
prefix = grpPrefix + prefix
}
// Remove duplicate slashes `//`
prefix = strings.Replace(prefix, "//", "/", -1)
}
// Empty or '/*' path equals "match anything"
// TODO fix * for paths with grpprefix
if prefix == "/*" {
prefix = "*"
}
// Lets get all files from root
files, _, err := getFiles(root)
if err != nil {
log.Fatal("Static: ", err)
}
// ./static/compiled => static/compiled
mount := filepath.Clean(root)
if !app.Settings.CaseSensitive {
prefix = strings.ToLower(prefix)
}
if !app.Settings.StrictRouting && len(prefix) > 1 {
prefix = strings.TrimRight(prefix, "/")
}
// Loop over all files
for _, file := range files {
// Ignore the .gzipped files by fasthttp
if strings.Contains(file, ".fasthttp.gz") {
continue
}
// Time to create a fake path for the route match
// static/index.html => /index.html
path := filepath.Join(prefix, strings.Replace(file, mount, "", 1))
// for windows: static\index.html => /index.html
path = filepath.ToSlash(path)
// Store file path to use in ctx handler
filePath := file
if len(prefix) > 1 && strings.Contains(prefix, "*") {
app.routes = append(app.routes, &Route{
Method: "GET",
Path: path,
Prefix: strings.Split(prefix, "*")[0],
HandlerCtx: func(c *Ctx) {
c.SendFile(filePath, gzip)
},
})
return
}
// If the file is an index.html, bind the prefix to index.html directly
if filepath.Base(filePath) == "index.html" || filepath.Base(filePath) == "index.htm" {
app.routes = append(app.routes, &Route{
Method: "GET",
Path: prefix,
HandlerCtx: func(c *Ctx) {
c.SendFile(filePath, gzip)
},
})
}
if !app.Settings.CaseSensitive {
path = strings.ToLower(path)
}
if !app.Settings.StrictRouting && len(prefix) > 1 {
path = strings.TrimRight(path, "/")
}
// Add the route + SendFile(filepath) to routes
app.routes = append(app.routes, &Route{
Method: "GET",
Path: path,
HandlerCtx: func(c *Ctx) {
c.SendFile(filePath, gzip)
},
})
}
}
func (app *App) registerWebSocket(method, group, path string, handler func(*Conn)) {
if len(path) > 0 && path[0] != '/' {
path = "/" + path
}
if len(group) > 0 {
// `/v1`+`/` => `/v1`+``
if path == "/" {
path = group
} else {
path = group + path
}
// Remove duplicate slashes `//`
path = strings.Replace(path, "//", "/", -1)
}
// Routes are case insensitive by default
if !app.Settings.CaseSensitive {
path = strings.ToLower(path)
}
if !app.Settings.StrictRouting && len(path) > 1 {
path = strings.TrimRight(path, "/")
}
// Get ':param' & ':optional?' & '*' from path
params := getParams(path)
if len(params) > 0 {
log.Fatal("WebSocket routes do not support path parameters: `:param, :optional?, *`")
}
app.routes = append(app.routes, &Route{
Method: method, Path: path, HandlerConn: handler,
})
}
func (app *App) registerMethod(method, group, path string, handlers ...func(*Ctx)) {
// No special paths for websockets
if len(handlers) == 0 {
log.Fatalf("Missing handler in route")
}
// Set variables
var prefix string
var middleware = method == "USE"
// A non wildcard path must start with a '/'
if path != "*" && len(path) > 0 && path[0] != '/' {
path = "/" + path
}
// Prepend group prefix
if len(group) > 0 {
// `/v1`+`/` => `/v1`+``
if path == "/" {
path = group
} else {
path = group + path
}
// Remove duplicate slashes `//`
path = strings.Replace(path, "//", "/", -1)
}
// Empty or '/*' path equals "match anything"
// TODO fix * for paths with grpprefix
if path == "/*" || (middleware && path == "") {
path = "*"
}
if method == "ALL" || middleware {
method = "*"
}
// Routes are case insensitive by default
if !app.Settings.CaseSensitive {
path = strings.ToLower(path)
}
if !app.Settings.StrictRouting && len(path) > 1 {
path = strings.TrimRight(path, "/")
}
// If the route can match anything
if path == "*" {
for i := range handlers {
app.routes = append(app.routes, &Route{
Method: method, Path: path, HandlerCtx: handlers[i],
})
}
return
}
// Get ':param' & ':optional?' & '*' from path
params := getParams(path)
// Enable prefix for midware
if len(params) == 0 && middleware {
prefix = path
}
// If path has no params (simple path)
if len(params) == 0 {
for i := range handlers {
app.routes = append(app.routes, &Route{
Method: method, Path: path, Prefix: prefix, HandlerCtx: handlers[i],
})
}
return
}
// If path only contains 1 wildcard, we can create a prefix
// If its a middleware, we also create a prefix
if len(params) == 1 && params[0] == "*" {
prefix = strings.Split(path, "*")[0]
for i := range handlers {
app.routes = append(app.routes, &Route{
Method: method, Path: path, Prefix: prefix,
Params: params, HandlerCtx: handlers[i],
})
}
return
}
// We have an :param or :optional? and need to compile a regex struct
regex, err := getRegex(path)
if err != nil {
log.Fatal("Router: Invalid path pattern: " + path)
}
// Add route with regex
for i := range handlers {
app.routes = append(app.routes, &Route{
Method: method, Path: path, Regex: regex,
Params: params, HandlerCtx: handlers[i],
})
}
}
func (app *App) handler(fctx *fasthttp.RequestCtx) {
// Use this boolean to perform 404 not found at the end
var match = false
// get custom context from sync pool
ctx := acquireCtx()
defer releaseCtx(ctx)
ctx.app = app
ctx.compress = app.Settings.Compression
ctx.Fasthttp = fctx
// get path and method
path := ctx.Path()
if !app.Settings.CaseSensitive {
path = strings.ToLower(path)
}
if !app.Settings.StrictRouting && len(path) > 1 {
path = strings.TrimRight(path, "/")
}
method := ctx.Method()
// enable recovery
if app.recover != nil {
defer func() {
if r := recover(); r != nil {
err, ok := r.(error)
if !ok {
err = fmt.Errorf("%v", r)
}
ctx.error = err
app.recover(ctx)
func (app *App) nextRoute(ctx *Ctx) {
lenr := len(app.routes) - 1
for ctx.index < lenr {
ctx.index++
route := app.routes[ctx.index]
match, values := route.matchRoute(ctx.method, ctx.path)
if match {
ctx.route = route
if !ctx.matched {
ctx.matched = true
}
}()
}
// loop trough routes
for _, route := range app.routes {
// Skip route if method does not match
if route.Method != "*" && route.Method != method {
continue
}
// Set route pointer if user wants to call .Route()
ctx.route = route
// wilcard or exact same path
// TODO v2: enable or disable case insensitive match
if route.Path == "*" || route.Path == path {
// if * always set the path to the wildcard parameter
if route.Path == "*" {
ctx.params = &[]string{"*"}
ctx.values = []string{path}
if len(values) > 0 {
ctx.values = values
}
// ctx.Fasthttp.Request.Header.ConnectionUpgrade()
// Websocket request
if route.HandlerConn != nil && websocket.FastHTTPIsWebSocketUpgrade(fctx) {
// Try to upgrade
err := socketUpgrade.Upgrade(ctx.Fasthttp, func(fconn *websocket.Conn) {
if route.isWebSocket {
if err := websocketUpgrader.Upgrade(ctx.Fasthttp, func(fconn *websocket.Conn) {
conn := acquireConn(fconn)
defer releaseConn(conn)
route.HandlerConn(conn)
})
// Upgrading failed
if err != nil {
log.Fatalf("Failed to upgrade websocket connection")
route.HandleConn(conn)
}); err != nil { // Upgrading failed
ctx.SendStatus(400)
}
return
}
// No handler for HTTP nor websocket
if route.HandlerCtx == nil {
continue
}
// Match found, 404 not needed
match = true
route.HandlerCtx(ctx)
// if next is not set, leave loop and release ctx
if !ctx.next {
break
} else {
// reset match to false
match = false
route.HandleCtx(ctx)
}
// set next to false for next iteration
ctx.next = false
// continue to go to the next route
continue
return
}
if route.Prefix != "" && strings.HasPrefix(path, route.Prefix) {
ctx.route = route
if strings.Contains(route.Path, "*") {
ctx.params = &[]string{"*"}
// ctx.values = matches[0][1:len(matches[0])]
// parse query source
ctx.values = []string{strings.Replace(path, route.Prefix, "", 1)}
}
// No handler for HTTP nor websocket
if route.HandlerCtx == nil {
continue
}
// Match found, 404 not needed
match = true
route.HandlerCtx(ctx)
// if next is not set, leave loop and release ctx
if !ctx.next {
break
} else {
// reset match to false
match = false
}
// set next to false for next iteration
ctx.next = false
// continue to go to the next route
continue
}
// Skip route if regex does not exist
if route.Regex == nil {
continue
}
// Skip route if regex does not match
if !route.Regex.MatchString(path) {
continue
}
// If we have parameters, lets find the matches
if len(route.Params) > 0 {
matches := route.Regex.FindAllStringSubmatch(path, -1)
// If we have matches, add params and values to context
if len(matches) > 0 && len(matches[0]) > 1 {
ctx.params = &route.Params
ctx.values = matches[0][1:len(matches[0])]
}
}
// No handler for HTTP nor websocket
if route.HandlerCtx == nil {
continue
}
// Match found, 404 not needed
match = true
route.HandlerCtx(ctx)
// if next is not set, leave loop and release ctx
if !ctx.next {
break
} else {
// reset match to false
match = false
}
// set next to false for next iteration
ctx.next = false
}
// Do we need to compress?
if ctx.compress {
compressDefaultCompression(fctx)
// switch app.Settings.CompressionLevel {
// case 2:
// compressBestSpeed(fctx)
// case 3:
// compressBestCompression(fctx)
// case 4:
// compressHuffmanOnly(fctx)
// default: // 1
// compressDefaultCompression(fctx)
// }
}
// No match, send default 404 Not Found
if !match {
if !ctx.matched {
ctx.SendStatus(404)
}
}
func (r *Route) matchRoute(method, path string) (match bool, values []string) {
// is route middleware? matches all http methods
if r.isMiddleware {
// '*' or '/' means its a valid match
if r.isStar || r.isSlash {
return true, nil
}
// if midware path starts with req.path
if strings.HasPrefix(path, r.Path) {
return true, nil
}
// middlewares dont support regex so bye!
return false, nil
}
// non-middleware route, http method must match!
// the wildcard method is for .All() method
if r.Method != method && r.Method[0] != '*' {
return false, nil
}
// '*' means we match anything
if r.isStar {
return true, nil
}
// simple '/' bool, so you avoid unnecessary comparison for long paths
if r.isSlash && path == "/" {
return true, nil
}
// does this route need regex matching?
if r.isRegex {
// req.path match regex pattern
if r.Regexp.MatchString(path) {
// do we have parameters
if len(r.Params) > 0 {
// get values for parameters
matches := r.Regexp.FindAllStringSubmatch(path, -1)
// did we get the values?
if len(matches) > 0 && len(matches[0]) > 1 {
values = matches[0][1:len(matches[0])]
return true, values
}
return false, nil
}
return true, nil
}
return false, nil
}
// last thing to do is to check for a simple path match
if r.Path == path {
return true, nil
}
// Nothing match
return false, nil
}
func (app *App) handler(fctx *fasthttp.RequestCtx) {
// get fiber context from sync pool
ctx := acquireCtx(fctx)
defer releaseCtx(ctx)
// attach app poiner and compress settings
ctx.app = app
ctx.compress = app.Settings.Compression
// Case sensitive routing
if !app.Settings.CaseSensitive {
ctx.path = strings.ToLower(ctx.path)
}
// Strict routing
if !app.Settings.StrictRouting && len(ctx.path) > 1 {
ctx.path = strings.TrimRight(ctx.path, "/")
}
app.nextRoute(ctx)
if ctx.compress {
compressResponse(fctx)
}
}
func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) {
// Route requires atleast one handler
if len(handlers) == 0 {
log.Fatalf("Missing handler in route")
}
// Cannot have an empty path
if path == "" {
path = "/"
}
// Path always start with a '/' or '*'
if path[0] != '/' && path[0] != '*' {
path = "/" + path
}
// Case sensitive routing, all to lowercase
if !app.Settings.CaseSensitive {
path = strings.ToLower(path)
}
// Strict routing, remove last `/`
if !app.Settings.StrictRouting && len(path) > 1 {
path = strings.TrimRight(path, "/")
}
// Set route booleans
var isMiddleware = method == "USE"
// Middleware / All allows all HTTP methods
if isMiddleware || method == "ALL" {
method = "*"
}
var isStar = path == "*" || path == "/*"
// Middleware containing only a `/` equals wildcard
if isMiddleware && path == "/" {
isStar = true
}
var isSlash = path == "/"
var isRegex = false
// Route properties
var Params = getParams(path)
var Regexp *regexp.Regexp
// Params requires regex pattern
if len(Params) > 0 {
regex, err := getRegex(path)
if err != nil {
log.Fatal("Router: Invalid path pattern: " + path)
}
isRegex = true
Regexp = regex
}
for i := range handlers {
app.routes = append(app.routes, &Route{
isMiddleware: isMiddleware,
isStar: isStar,
isSlash: isSlash,
isRegex: isRegex,
Method: method,
Path: path,
Params: Params,
Regexp: Regexp,
HandleCtx: handlers[i],
})
}
}
func (app *App) registerWebSocket(method, path string, handle func(*Conn)) {
// Cannot have an empty path
if path == "" {
path = "/"
}
// Path always start with a '/' or '*'
if path[0] != '/' && path[0] != '*' {
path = "/" + path
}
// Case sensitive routing, all to lowercase
if !app.Settings.CaseSensitive {
path = strings.ToLower(path)
}
// Strict routing, remove last `/`
if !app.Settings.StrictRouting && len(path) > 1 {
path = strings.TrimRight(path, "/")
}
var isWebSocket = true
var isStar = path == "*" || path == "/*"
var isSlash = path == "/"
var isRegex = false
// Route properties
var Params = getParams(path)
var Regexp *regexp.Regexp
// Params requires regex pattern
if len(Params) > 0 {
regex, err := getRegex(path)
if err != nil {
log.Fatal("Router: Invalid path pattern: " + path)
}
isRegex = true
Regexp = regex
}
app.routes = append(app.routes, &Route{
isWebSocket: isWebSocket,
isStar: isStar,
isSlash: isSlash,
isRegex: isRegex,
Method: method,
Path: path,
Params: Params,
Regexp: Regexp,
HandleConn: handle,
})
}
func (app *App) registerStatic(prefix, root string) {
// Cannot have an empty prefix
if prefix == "" {
prefix = "/"
}
// prefix always start with a '/' or '*'
if prefix[0] != '/' && prefix[0] != '*' {
prefix = "/" + prefix
}
// Case sensitive routing, all to lowercase
if !app.Settings.CaseSensitive {
prefix = strings.ToLower(prefix)
}
var isStar = prefix == "*" || prefix == "/*"
files := map[string]string{}
// Clean root path
root = filepath.Clean(root)
// Check if root exist and is accessible
if _, err := os.Stat(root); err != nil {
log.Fatalf("%s", err)
}
// Store path url and file paths in map
if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
url := "*"
if !isStar {
// /css/style.css: static/css/style.css
url = filepath.Join(prefix, strings.Replace(path, root, "", 1))
}
// \static\css: /static/css
url = filepath.ToSlash(url)
files[url] = path
if filepath.Base(path) == "index.html" {
files[url] = path
}
}
return err
}); err != nil {
log.Fatalf("%s", err)
}
compress := app.Settings.Compression
app.routes = append(app.routes, &Route{
isMiddleware: true,
isStar: isStar,
Method: "*",
Path: prefix,
HandleCtx: func(c *Ctx) {
// Only allow GET & HEAD methods
if c.method == "GET" || c.method == "HEAD" {
path := "*"
if !isStar {
path = c.path
}
file := files[path]
if file != "" {
c.SendFile(file, compress)
return
}
}
c.matched = false
c.Next()
},
})
}

View File

@ -20,13 +20,9 @@ import (
fasthttp "github.com/valyala/fasthttp"
)
var compressDefaultCompression = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressDefaultCompression)
// var compressBestSpeed = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressBestSpeed)
// var compressBestCompression = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressBestCompression)
// var compressHuffmanOnly = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressHuffmanOnly)
var schemaDecoder = schema.NewDecoder()
var socketUpgrade = websocket.FastHTTPUpgrader{
var compressResponse = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressDefaultCompression)
var websocketUpgrader = websocket.FastHTTPUpgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(fctx *fasthttp.RequestCtx) bool {
@ -34,6 +30,15 @@ var socketUpgrade = websocket.FastHTTPUpgrader{
},
}
func groupPaths(prefix, path string) string {
if path == "/" {
path = ""
}
path = prefix + path
path = strings.Replace(path, "//", "/", -1)
return path
}
func getParams(path string) (params []string) {
if len(path) < 1 {
return
@ -108,10 +113,6 @@ func getType(ext string) (mime string) {
return mime
}
func getStatus(status int) (msg string) {
return statusMessage[status]
}
// #nosec G103
// getString converts byte slice to a string without memory allocation.
// See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ .
@ -122,7 +123,7 @@ var getString = func(b []byte) string {
// #nosec G103
// getBytes converts string to a byte slice without memory allocation.
// See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ .
func getBytes(s string) (b []byte) {
var getBytes = func(s string) (b []byte) {
return *(*[]byte)(unsafe.Pointer(&s))
}
@ -162,8 +163,8 @@ const (
MIMEOctetStream = "application/octet-stream"
)
// HTTP status codes
var statusMessage = map[int]string{
// HTTP status codes with messages
var statusMessages = map[int]string{
100: "Continue",
101: "Switching Protocols",
102: "Processing",