mirror of https://github.com/gofiber/fiber.git
⚡ v2
parent
67ae8e7e69
commit
ec5d66e7a8
|
@ -1,23 +0,0 @@
|
|||
; https://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
|
||||
[*.md]
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
eclint_indent_style = unset
|
||||
|
||||
[Dockerfile]
|
||||
indent_size = 4
|
|
@ -1,2 +0,0 @@
|
|||
golint:
|
||||
enabled: false
|
|
@ -1 +0,0 @@
|
|||
* @gofiber/maintainers
|
|
@ -1,81 +0,0 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our community include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or advances of any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email address, without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [Gitter](https://gitter.im/gofiber/community). All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
|
||||
available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
|
|
@ -1,28 +0,0 @@
|
|||
# Contributing
|
||||
|
||||
When contributing to this repository, please first discuss the change you wish to make via our [Telegram](https://t.me/gofiber) group, by creating an [issue](https://github.com/gofiber/fiber/issues) or any other method with the owners of this repository before making a change.
|
||||
|
||||
Please note: we have a [code of conduct](https://github.com/gofiber/fiber/blob/master/.github/CODE_OF_CONDUCT.md), please follow it in all your interactions with the `Fiber` project.
|
||||
|
||||
## Pull Requests or Comits
|
||||
Titles always we must use prefix according to below:
|
||||
|
||||
> 🔥 Feature, ♻️ Refactor, 🩹 Fix, 🚨 Test, 📚 Doc, 🎨 Style
|
||||
- 🔥 Feature: Add flow to add person
|
||||
- ♻️ Refactor: Rename file X to Y
|
||||
- 🩹 Fix: Improve flow
|
||||
- 🚨 Test: Validate to add a new person
|
||||
- 📚 Doc: Translate to Portuguese middleware redirect
|
||||
- 🎨 Style: Respected pattern Golint
|
||||
|
||||
All pull request that contains a feature or fix is mandatory to have unit tests. Your PR is only to be merged if you respect this flow.
|
||||
|
||||
# 👍 Contribute
|
||||
|
||||
If you want to say **thank you** and/or support the active development of `Fiber`:
|
||||
|
||||
1. Add a [GitHub Star](https://github.com/gofiber/fiber/stargazers) to the project.
|
||||
2. Tweet about the project [on your Twitter](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. Write a review or tutorial on [Medium](https://medium.com/), [Dev.to](https://dev.to/) or personal blog.
|
||||
4. Help us to translate our API Documentation via [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Support the project by donating a [cup of coffee](https://buymeacoff.ee/fenny).
|
|
@ -1,8 +0,0 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
custom: https://gofiber.io/support
|
|
@ -1,28 +0,0 @@
|
|||
---
|
||||
name: "\U0001F41B Bug"
|
||||
about: Create a report to help us improve
|
||||
title: "\U0001F41B "
|
||||
labels: 'Type: Bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Fiber version**
|
||||
|
||||
**Issue description**
|
||||
|
||||
**Code snippet**
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/gofiber/fiber"
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Steps to reproduce
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
name: "\U0001F680 Feature"
|
||||
about: Suggest an idea for this project
|
||||
title: "\U0001F680 "
|
||||
labels: 'Type: Feature'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem?**
|
||||
|
||||
**Describe the solution you'd like**
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
|
||||
**Additional context**
|
|
@ -1,23 +0,0 @@
|
|||
---
|
||||
name: "\U0001F917 Question"
|
||||
about: Ask a question so we can help
|
||||
title: "\U0001F917 "
|
||||
labels: 'Type: Question'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Question description**
|
||||
|
||||
**Code snippet** _Optional_
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/gofiber/fiber"
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
// ..
|
||||
}
|
||||
```
|
|
@ -1,592 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<!--<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>-->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<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
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 Benchmarks
|
||||
|
||||
These tests are performed by [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) and [Go Web](https://github.com/smallnest/go-web-framework-benchmark). If you want to see all results, please visit our [Wiki](https://docs.gofiber.io/benchmarks).
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ Installation
|
||||
|
||||
First of all, [download](https://golang.org/dl/) and install Go. `1.11` or higher is required.
|
||||
|
||||
Installation is done using the [`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) command:
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber
|
||||
```
|
||||
|
||||
## 🎯 Features
|
||||
|
||||
- Robust [routing](https://docs.gofiber.io/routing)
|
||||
- Serve [static files](https://docs.gofiber.io/application#static)
|
||||
- Extreme [performance](https://docs.gofiber.io/benchmarks)
|
||||
- [Low memory](https://docs.gofiber.io/benchmarks) footprint
|
||||
- [API endpoints](https://docs.gofiber.io/context)
|
||||
- [Middleware](https://docs.gofiber.io/middleware) & [Next](https://docs.gofiber.io/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
|
||||
- [Template engines](https://github.com/gofiber/template)
|
||||
- [WebSocket support](https://docs.gofiber.io/middleware#websocket)
|
||||
- [Rate Limiter](https://docs.gofiber.io/middleware#limiter)
|
||||
- Translated in [15 languages](https://docs.gofiber.io/)
|
||||
- And much more, [explore Fiber](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 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 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 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), Discord [channel](https://gofiber.io/discord) _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
|
||||
|
||||
Listed below are some of the common examples. If you want to see more code examples , please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/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
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
``````
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
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
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket Upgrade
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 Media
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
- [📺 How to use the Go Fiber JWT middleware](https://youtu.be/ejEizICXm9w) - _30 July 2020_
|
||||
- [📺 Introduction to SQLC and how to use it with Fiber](https://youtu.be/xIqulnDQwp0) - _11 Aug 2020_
|
||||
|
||||
## 👍 Contribute
|
||||
|
||||
If you want to say **thank you** and/or support the active development of `Fiber`:
|
||||
|
||||
1. Add a [GitHub Star](https://github.com/gofiber/fiber/stargazers) to the project.
|
||||
2. Tweet about the project [on your Twitter](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
|
||||
3. Write a review or tutorial on [Medium](https://medium.com/), [Dev.to](https://dev.to/) or personal blog.
|
||||
4. Help us to translate our API Documentation via [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Support the project by donating a [cup of coffee](https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ Supporters
|
||||
|
||||
Fiber is an open source project that runs on donations to pay the bills e.g. our domain name, gitbook, netlify and serverless hosting. If you want to support Fiber, you can ☕ [**buy a coffee here**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Code Contributors
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ License
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,656 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a> -->
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<div dir="rtl">
|
||||
<b>Fiber</b> هو <b>إطار ويب</b> مستوحى من <a href="https://github.com/expressjs/express">Express</a> مبني على <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, <b>اسرع</b> محرك HTTP لـ <a href="https://golang.org/doc/">Go</a>. مصمم ليكون <b>سهل</b> لأغراض <b>السرعة</b> مع عدم <b>تخصيص ذاكرة والأداء</b> و <b>الاداء العالي</b> دائما.
|
||||
<div dir="rtl">
|
||||
</p>
|
||||
|
||||
## ⚡️ بداية سريعة
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
## 🤖 مقايس الاداء
|
||||
|
||||
يتم تنفيذ هذه الاختبارات من قبل [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) و [Go Web](https://github.com/smallnest/go-web-framework-benchmark). إذا كنت تريد رؤية جميع النتائج ، يرجى زيارة موقعنا [Wiki](https://docs.gofiber.io/benchmarks).
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
|
||||
## ⚙️ تثبيت
|
||||
|
||||
قبل كل شي قم , [بتحميل](https://golang.org/dl/) و تثبيت Go. `1.11` أو أعلى مطلوب.
|
||||
|
||||
بعد الانتهاء من التثبيت استخدم الامر [`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) :
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
## 🎯 الميزات
|
||||
|
||||
- قوي [routing](https://docs.gofiber.io/routing)
|
||||
- يقدم خدمة [static files](https://docs.gofiber.io/application#static)
|
||||
- أقصى [أداء](https://docs.gofiber.io/benchmarks)
|
||||
- [ذاكرة منخفضة](https://docs.gofiber.io/benchmarks)
|
||||
- [API endpoints](https://docs.gofiber.io/context)
|
||||
- [Middleware](https://docs.gofiber.io/middleware) & [Next](https://docs.gofiber.io/context#next) مدعوم
|
||||
- [سريع](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) server-side programming
|
||||
- [Template engines](https://github.com/gofiber/template)
|
||||
- [WebSocket دعم](https://docs.gofiber.io/middleware#websocket)
|
||||
- [Rate Limiter](https://docs.gofiber.io/middleware#limiter)
|
||||
- ترجم الى [15 لغة أخرى](https://docs.gofiber.io/)
|
||||
- وأكثر بكثير, [استكشف Fiber](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 فلسفة
|
||||
|
||||
قوفر(مستخدمي لغة Go الجدد) جديد يجعل التبديل من [Node.js](https://nodejs.org/en/about/) الى [Go](https://golang.org/doc/)تتعامل مع منحنى التعلم قبل أن يتمكنوا من البدء في بناءتطبيقات الويب . Fiber, كـ **إطار الويب**, تم إنشاؤه بفكرة **minimalism** ويتبع **UNIX way**, حتى يتمكن القوفرون الجدد من دخول عالم Go بترحيب حار وموثوق.
|
||||
|
||||
Fiber هو **مستوحى** من Express, إطار الويب الأكثر شعبية على الإنترنت. قمنا بدمج **سهولة** الـ Express و **الأداء الخام** لـ Go. إذا كنت قد قمت بتطبيق تطبيق ويب في Node.js (_using Express or similar_), ستظهر العديد من الأساليب والمبادئ **الاكثر شيوعاً** لك.
|
||||
|
||||
نحن **نصغي** لمستخدمينا [issues](https://github.com/gofiber/fiber/issues), نناقش [channel](https://gofiber.io/discord) _وفي جميع أنحاء الإنترنت_ لإنشاء **سريع**, **مرن** و **مألوف** Go إطار الويب لـ **لأي** مهمة, **الموعد الأخير
|
||||
** و تطوير **مهارات**! فقط مثل Express تفعل لـ JavaScript عالم.
|
||||
|
||||
## 👀 أمثلة
|
||||
|
||||
فيما يلي بعض الأمثلة الشائعة. إذا كنت ترغب في رؤية المزيد من أمثلة التعليمات البرمجية, يرجى زيارة [Recipes repository](https://github.com/gofiber/recipes) او زيارة [API documentation](https://docs.gofiber.io).
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
<div dir="ltr" >
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/application#static)
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
</div>
|
||||
|
||||
#### 📖 [**Middleware & Next**](https://docs.gofiber.io/context#next)
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<details>
|
||||
<summary>📚 إظهار المزيد من أمثلة التعليمات البرمجية</summary>
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
|
||||
<div dir="ltr" >
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Grouping routes into chains
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/application#group)
|
||||
|
||||
<div dir="ltr" >
|
||||
|
||||
```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
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Middleware logger
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
<div dir="ltr" >
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
``````
|
||||
|
||||
</div>
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
<div dir="ltr" >
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
التحقق من CORS عن طريق تمرير أي مجال `Origin` العنوان:
|
||||
|
||||
<div dir="ltr" >
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### مخصص 404 response
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
|
||||
<div dir="ltr" >
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
</div>
|
||||
|
||||
### JSON Response
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/context#json)
|
||||
|
||||
<div dir="ltr" >
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
### WebSocket Upgrade
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
<div dir="ltr" >
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Recover middleware
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
<div dir="ltr" >
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
هذه قائمة middlewares التي تم إنشاؤها من قبل المجتمع Fiber , الرجاء إنشاءPR إذا كنت تريد أن ترى ذلك!
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 وسائل الإعلام
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 مساهمة
|
||||
|
||||
إذا كنت تريد أن تقول **شكرا جزيل** و/او دعم التنمية النشطة للـ `Fiber`:
|
||||
|
||||
1. اضف [GitHub نجمة](https://github.com/gofiber/fiber/stargazers) للمشروع.
|
||||
2. غرد عن المشروع [في تويتر ](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
|
||||
3. اكتب مراجعة أو برنامج تعليمي عن [Medium](https://medium.com/), [Dev.to](https://dev.to/) او في موقعك الشخصي.
|
||||
4. ساعدنا في ترجمة موقعنا API التوثيق عبر [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. دعم المشروع بالتبرع بـ [كوب من القهوة](https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ الداعمين
|
||||
|
||||
Fiber هو مشروع مفتوح المصدر يعمل على التبرعات لدفع الفواتير ، على سبيل المثال اسم النطاق الخاص بنا , gitbook, netlify and serverless الاستضافة. إذا كنت تريد دعم Fiber, تستطيع ☕ [**شراء كوب قهوة هنا**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | المستخدم | التبرع |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 المساهمون في كتابة الكود
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ رخصة
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` هو برنامج مجاني ومفتوح المصدر مرخص بموجب [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). تم إنشاء الشعار الرسمي من قبل [Vic Shóstak](https://github.com/koddr) ووزعت تحت [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) رخصة (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,591 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<strong>Fiber</strong> ist ein von <a href="https://github.com/expressjs/express">Expressjs</a> inspiriertes <strong>Web-Framework</strong>, aufgebaut auf <a href="https://github.com/valyala/fasthttp">Fasthttp</a> - die <strong>schnellste</strong> HTTP engine für <a href="https://golang.org/doc/">Go</a>. Kreiert um Dinge zu <strong>vereinfachen</strong>, für <strong>schnelle</strong> Entwicklung mit <strong>keinen Speicherzuweisungen</strong> und <strong>Performance</strong> im Hinterkopf.
|
||||
</p>
|
||||
|
||||
## ⚡️ Schnellstart
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 Benchmarks
|
||||
|
||||
Diese Tests wurden von [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) und [Go Web](https://github.com/smallnest/go-web-framework-benchmark) ausgeführt. Falls du alle Resultate sehen möchtest, besuche bitte unser [Wiki](https://docs.gofiber.io/benchmarks).
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ Installation
|
||||
|
||||
Als erstes, [downloade](https://golang.org/dl/) und installiere Go. `1.11` oder höher.
|
||||
|
||||
Die Installation wird durch das [`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) Kommando gestartet:
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber
|
||||
```
|
||||
|
||||
## 🎯 Eigenschaften
|
||||
|
||||
- Robustes [Routing](https://docs.gofiber.io/routing)
|
||||
- Bereitstellen von [statischen Dateien](https://docs.gofiber.io/application#static)
|
||||
- Extreme [Performance](https://docs.gofiber.io/benchmarks)
|
||||
- [Geringe Arbeitsspeicher](https://docs.gofiber.io/benchmarks) verwendung
|
||||
- Express [API Endpunkte](https://docs.gofiber.io/context)
|
||||
- [Middleware](https://docs.gofiber.io/middleware) & [Next](https://docs.gofiber.io/context#next) Support
|
||||
- [Schnelle](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) serverseitige Programmierung
|
||||
- [Template engines](https://github.com/gofiber/template)
|
||||
- [WebSocket support](https://docs.gofiber.io/middleware#websocket)
|
||||
- [Rate Limiter](https://docs.gofiber.io/middleware#limiter)
|
||||
- Available in [15 languages](https://docs.gofiber.io/)
|
||||
- Und vieles mehr - [erkunde Fiber](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 Philosophie
|
||||
|
||||
Neue gopher welche von [Node.js](https://nodejs.org/en/about/) zu [Go](https://golang.org/doc/) umsteigen, müssen eine Lernkurve durchlaufen, bevor sie ihre Webanwendungen oder Microservices erstellen können. Fiber, als ein **Web-Framework**, wurde erschaffen mit der Idee von **Minimalismus** und folgt dem **UNIX Weg** damit neue Gophers mit einem herzlichen und vertrauenswürdigen Willkommen schnell in die Welt von Go eintreten können.
|
||||
|
||||
Fiber ist **inspiriert** von Expressjs, dem beliebtesten Web-Framework im Internet. Wir haben die **Leichtigkeit** von Express und die **Rohleistung** von Go kombiniert. Wenn du jemals eine Webanwendung mit Node.js implementiert hast (_mit Express.js oder ähnlichem_), werden dir viele Methoden und Prinzipien **sehr vertraut** vorkommen.
|
||||
|
||||
## 👀 Beispiele
|
||||
|
||||
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://docs.gofiber.io).
|
||||
|
||||
Listed below are some of the common examples. If you want to see more code examples , please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/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
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
``````
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
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
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket Upgrade
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 Medien
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 Mitwirken
|
||||
|
||||
Falls du **danke** sagen möchtest und/oder aktiv die Entwicklung von `fiber` fördern möchtest:
|
||||
|
||||
1. Füge dem Projekt einen [GitHub Stern](https://github.com/gofiber/fiber/stargazers) hinzu.
|
||||
2. Twittere über das Projekt [auf deinem Twitter](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
|
||||
3. Schreibe eine Rezension auf [Medium](https://medium.com/), [Dev.to](https://dev.to/) oder einem persönlichem Blog.
|
||||
4. Help us to translate our API Documentation via [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Support the project by donating a [cup of coffee](https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ Supporters
|
||||
|
||||
Fiber is an open source project that runs on donations to pay the bills e.g. our domain name, gitbook, netlify and serverless hosting. If you want to support Fiber, you can ☕ [**buy a coffee here**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Code Contributors
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ License
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party MIT licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,591 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<strong>Fiber</strong> es un <strong>framework web</strong> inspirado en <a href="https://github.com/expressjs/express">Express</a> construido sobre <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, el motor HTTP <strong>más rápido</strong> para <a href="https://golang.org/doc/">Go</a>. Diseñado para <strong>facilitar</strong> las cosas para <strong>un</strong> desarrollo <strong>rápido</strong> con <strong>cero asignación de memoria</strong> y <strong>rendimiento</strong> en mente.
|
||||
</p>
|
||||
|
||||
## ⚡️ Inicio rápido
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 Puntos de referencia
|
||||
|
||||
Estas pruebas son realizadas por [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) y [Go Web](https://github.com/smallnest/go-web-framework-benchmark) . Si desea ver todos los resultados, visite nuestro [Wiki](https://docs.gofiber.io/benchmarks) .
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ Instalación
|
||||
|
||||
En primer lugar, [descargue](https://golang.org/dl/) e instale Go. Se requiere `1.11` o superior.
|
||||
|
||||
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/...
|
||||
```
|
||||
|
||||
## 🎯 Características
|
||||
|
||||
- [Enrutamiento](https://docs.gofiber.io/routing) robusto
|
||||
- Servir [archivos estáticos](https://docs.gofiber.io/application#static)
|
||||
- [Rendimiento](https://docs.gofiber.io/benchmarks) extremo
|
||||
- [Poca](https://docs.gofiber.io/benchmarks) huella de [memoria](https://docs.gofiber.io/benchmarks)
|
||||
- [Puntos finales de API](https://docs.gofiber.io/context) Express
|
||||
- Middleware y [próximo](https://docs.gofiber.io/context#next) soporte
|
||||
- Programación [rápida](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) del lado del servidor
|
||||
- [Template engines](https://github.com/gofiber/template)
|
||||
- [WebSocket support](https://docs.gofiber.io/middleware#websocket)
|
||||
- [Rate Limiter](https://docs.gofiber.io/middleware#limiter)
|
||||
- Disponible en [15 idiomas](https://docs.gofiber.io/)
|
||||
- Y mucho más, [explora Fiber](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 Filosofía
|
||||
|
||||
Los nuevos gophers que hacen el cambio de [Node.js](https://nodejs.org/en/about/) a [Go](https://golang.org/doc/) están lidiando con una curva de aprendizaje antes de que puedan comenzar a construir sus aplicaciones web o microservicios. Fiber, como un **marco web** , fue creado con la idea del **minimalismo** y sigue el **camino de UNIX** , para que los nuevos gophers puedan ingresar rápidamente al mundo de Go con una cálida y confiable bienvenida.
|
||||
|
||||
Fiber está **inspirado** en Expressjs, el framework web más popular en Internet. Combinamos la **facilidad** de Express y **el rendimiento bruto** de Go. Si alguna vez ha implementado una aplicación web en Node.js ( *utilizando Express.js o similar* ), muchos métodos y principios le parecerán **muy comunes** .
|
||||
|
||||
## 👀 Ejemplos
|
||||
|
||||
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://docs.gofiber.io) .
|
||||
|
||||
Listed below are some of the common examples. If you want to see more code examples , please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Mostrar más ejemplos de código</summary>
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Agrupando rutas en cadenas
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/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
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Respuesta 404 personalizada
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
### Respuesta JSON
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket Upgrade
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 Medios
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 Contribuir
|
||||
|
||||
Si quiere **agradecer** y/o apoyar el desarrollo activo de `Fiber`:
|
||||
|
||||
1. Agrega una [estrella de GitHub](https://github.com/gofiber/fiber/stargazers) al proyecto.
|
||||
2. Tuitea sobre el proyecto [en tu Twitter](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
|
||||
3. Escribe una reseña o tutorial en [Medium](https://medium.com/) , [Dev.to](https://dev.to/) o blog personal.
|
||||
4. Ayúdanos a traducir la documentación de nuestra API a través de [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Apoya el proyecto donando una [tasa de café](https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ Personas que han mostrado su apoyo
|
||||
|
||||
Fiber es un proyecto open source que se mantiene a través de donaciones para pagar las cuentas e.g. nuestro nombre de dominio, gitbook, netlify y hosting serverless. Si quieres apoyar a Fiber, puedes ☕ [**comprar un café**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Contribuyentes de código
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ Licencia
|
||||
|
||||
Copyright (c) 2019-presente [Fenny](https://github.com/fenny) y [contribuyentes](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` es software libre y de código abierto bajo la licencia [MIT](https://github.com/gofiber/fiber/blob/master/LICENSE). El logo oficial fué creado por [Vic Shóstak](https://github.com/koddr) y distribuido bajo la licencia [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,591 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<b>Fiber</b> est un framework web inspiré d' <a href="https://github.com/expressjs/express">Express</a>. Il se base sur <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, l'implémentation HTTP de <a href="https://golang.org/doc/">Go</a> <b>la plus rapide</b>. Conçu pour <b>faciliter</b> les choses pour des développements <b>rapides</b>, Fiber garde à l'esprit <b>l'absence d'allocations mémoires</b>, ainsi que les <b>performances</b>.
|
||||
</p>
|
||||
|
||||
## ⚡️ Quickstart
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 Benchmarks
|
||||
|
||||
Ces tests sont effectués par [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) et [Go Web](https://github.com/smallnest/go-web-framework-benchmark). Si vous voulez voir tous les résultats, n'hésitez pas à consulter notre [Wiki](https://docs.gofiber.io/benchmarks).
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ Installation
|
||||
|
||||
Premièrement, [téléchargez](https://golang.org/dl/) et installez Go. Version `1.11` ou supérieur requise.
|
||||
|
||||
L'installation est ensuite lancée via la commande [`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them):
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber/...
|
||||
```
|
||||
|
||||
## 🎯 Features
|
||||
|
||||
- [Routing](https://docs.gofiber.io/routing) robuste
|
||||
- Serve [static files](https://docs.gofiber.io/application#static)
|
||||
- [Performances](https://docs.gofiber.io/benchmarks) extrêmes
|
||||
- [Faible empreinte mémoire](https://docs.gofiber.io/benchmarks)
|
||||
- [API endpoints](https://docs.gofiber.io/context)
|
||||
- Middleware & [Next](https://docs.gofiber.io/context#next) support
|
||||
- Programmation côté serveur [rapide](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497)
|
||||
- [Template engines](https://github.com/gofiber/template)
|
||||
- [WebSocket support](https://docs.gofiber.io/middleware#websocket)
|
||||
- [Rate Limiter](https://docs.gofiber.io/middleware#limiter)
|
||||
- Available in [15 languages](https://docs.gofiber.io/)
|
||||
- Et plus encore, [explorez Fiber](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 Philosophie
|
||||
|
||||
Les nouveaux gophers qui passent de [Node.js](https://nodejs.org/en/about/) à [Go](https://golang.org/doc/) sont confrontés à une courbe d'apprentissage, avant de pouvoir construire leurs applications web et microservices. Fiber, en tant que **framework web**, a été mis au point avec en tête l'idée de **minimalisme**, tout en suivant l'**UNIX way**, afin que les nouveaux gophers puissent rapidement entrer dans le monde de Go, avec un accueil chaleureux, de confiance.
|
||||
|
||||
Fiber est **inspiré** par Express, le framework web le plus populaire d'Internet. Nous avons combiné la **facilité** d'Express, et la **performance brute** de Go. Si vous avez déja développé une application web en Node.js (_en utilisant Express ou équivalent_), alors de nombreuses méthodes et principes vous sembleront **familiers**.
|
||||
|
||||
## 👀 Exemples
|
||||
|
||||
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://docs.gofiber.io).
|
||||
|
||||
Listed below are some of the common examples. If you want to see more code examples , please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/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
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
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
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket Upgrade
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 Media
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 Contribuer
|
||||
|
||||
Si vous voulez nous remercier et/ou soutenir le développement actif de `Fiber`:
|
||||
|
||||
1. Ajoutez une [GitHub Star](https://github.com/gofiber/fiber/stargazers) à ce projet.
|
||||
2. Twittez à propos de ce projet [sur votre Twitter](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
|
||||
3. Ecrivez un article (review, tutorial) sur [Medium](https://medium.com/), [Dev.to](https://dev.to/), ou encore un blog personnel.
|
||||
4. Help us to translate our API Documentation via [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Support the project by donating a [cup of coffee](https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ Supporters
|
||||
|
||||
Fiber is an open source project that runs on donations to pay the bills e.g. our domain name, gitbook, netlify and serverless hosting. If you want to support Fiber, you can ☕ [**buy a coffee here**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Code Contributors
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ License
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,738 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<div dir="rtl">
|
||||
|
||||
<b>Fiber</b> היא <b>web framework</b> בהשראת <a href="https://github.com/expressjs/express">Express</a> הבנויה על גבי <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, מנוע ה-HTTP <b>המהיר ביותר</b> עבור <a href="https://golang.org/doc/">Go</a>.
|
||||
נועדה <b>להקל</b> על העניינים למען פיתוח <b>מהיר</b>, <b>ללא הקצאות זכרון</b> ולוקחת <b>ביצועים</b> בחשבון.
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## ⚡️ התחלה מהירה
|
||||
</div>
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## 🤖 מדדים
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
הבדיקות מבוצעות על ידי [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) ו-[Go Web](https://github.com/smallnest/go-web-framework-benchmark). אם אתם רוצים לראות את כל התוצאות, אנא בקרו ב-[Wiki](https://docs.gofiber.io/benchmarks) שלנו.
|
||||
</div>
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## ⚙️ התקנה
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
קודם כל, [הורידו](https://golang.org/dl/) והתקינו את Go. נדרשת גרסה <span dir="ltr">`1.11`</span> ומעלה.
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
ההתקנה מתבצעת באמצעות הפקודה <span dir="ltr">[`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them)</span>:
|
||||
</div>
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber
|
||||
```
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## 🎯 יכולות
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
- [ניתוב](https://docs.gofiber.io/routing) רובסטי
|
||||
- הנגשת [קבצים סטטיים](https://docs.gofiber.io/application#static)
|
||||
- [ביצועים](https://docs.gofiber.io/benchmarks) גבוהים במיוחד
|
||||
- צורך כמות [זכרון קטנה](https://docs.gofiber.io/benchmarks)
|
||||
- [נקודות קצה עבור API](https://docs.gofiber.io/context)
|
||||
- תמיכה ב-[Middleware](https://docs.gofiber.io/middleware) & [Next](https://docs.gofiber.io/context#next)
|
||||
- תכנות [מהיר](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) של צד שרת
|
||||
- [מנועי תבניות](https://docs.gofiber.io/middleware#template)
|
||||
- [תמיכה ב-WebSocket](https://docs.gofiber.io/middleware#websocket)
|
||||
- [הגבלת קצבים ובקשות](https://docs.gofiber.io/middleware#limiter)
|
||||
- Available in [12 languages](https://docs.gofiber.io/)
|
||||
- והרבה יותר, [חקור את Fiber](https://docs.gofiber.io/)
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## 💡 פילוסופיה
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
gophers חדשים שעושים את המעבר מ-[Node.js](https://nodejs.org/en/about/) ל-[Go](https://golang.org/doc/) מתמודדים עם עקומת למידה לפני שהם יכולים להתחיל לבנות את יישומי האינטרנט או המיקרו-שירותים שלהם.
|
||||
Fiber כ-**web framework**, נוצרה עם רעיון **המינימליזם** ועוקבת אחרי **הדרך של UNIX**, כך ש-gophers חדשים יוכלו להיכנס במהירות לעולם של Go עם קבלת פנים חמה ואמינה.
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
Fiber נוצרה **בהשראת** Express, ה-web framework הפופולרית ביותר ברחבי האינטרנט. שילבנו את **הקלות** של Express ו**הביצועים הגולמיים** של Go. אם אי-פעם מימשתם יישום web ב-Node.js (_באמצעות Express או דומיו_), אז הרבה מהפונקציות והעקרונות ייראו לכם **מאוד מוכרים**.
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
אנחנו **מקשיבים** למשתמשים שלנו ב-[issues](https://github.com/gofiber/fiber/issues) (_ובכל רחבי האינטרנט_) כדי ליצור web framework **מהירה**, **גמישה**, ו**ידידותית** בשפת Go עבור **כל** משימה, **תאריך יעד** ו**כישורי** מפתח! בדיוק כמו ש-Express מבצע בעולם של JavaScript.
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## 👀 דוגמאות
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
להלן כמה מהדוגמאות הנפוצות. אם ברצונכם לראות דוגמאות קוד נוספות, אנא בקרו ב[מאגר המתכונים](https://github.com/gofiber/recipes) שלנו או בקרו ב[תיעוד ה-API](https://docs.gofiber.io) שלנו.
|
||||
</div>
|
||||
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
</div>
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/application#static)
|
||||
</div>
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
#### 📖 [**Middleware & Next**](https://docs.gofiber.io/context#next)
|
||||
</div>
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<div dir="rtl">
|
||||
<details>
|
||||
<summary>📚 הצג דוגמאות קוד נוספות</summary>
|
||||
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
</div>
|
||||
|
||||
### קיבוץ routes ל-chains
|
||||
|
||||
📖 [קבוצות](https://docs.gofiber.io/application#group)
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
```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
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
</div>
|
||||
|
||||
### Middleware של לוגים
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### שיתוף משאבים בין מקורות (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</div>
|
||||
|
||||
בדוק את ה-CORS על ידי העברת כל domain ב-header של <span dir="ltr">`Origin`</span>:
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
</div>
|
||||
|
||||
### תגובת 404 מותאמת אישית
|
||||
|
||||
📖 [שיטות HTTP](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
</div>
|
||||
|
||||
### תגובת JSON
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/context#json)
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
</div>
|
||||
|
||||
### WebSocket Upgrade
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
</div>
|
||||
|
||||
### Middleware של התאוששות
|
||||
|
||||
📖 [התאוששות](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## 💬 מדיה
|
||||
</div>
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## 👍 לתרום
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
אם אתם רוצים לומר **תודה** או/ו לתמוך בפיתוח הפעיל של <span dir="ltr">`Fiber`</span>:
|
||||
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
1. תוסיפו [GitHub Star](https://github.com/gofiber/fiber/stargazers) לפרויקט.
|
||||
2. צייצו לגבי הפרויקט [בטוויטר שלכם](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
|
||||
3. כתבו ביקורת או מדריך ב-[Medium](https://medium.com/), [Dev.to](https://dev.to/) או בבלוג האישי שלכם.
|
||||
4. עזרו לנו לתרגם את ה-<span dir="ltr">`README`</span> הזה לשפה אחרת.
|
||||
5. תמכו בפרויקט על ידי תרומת [כוס קפה](https://buymeacoff.ee/fenny).
|
||||
</div>
|
||||
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## ☕ תומכים
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
Fiber היא פרויקט קוד פתוח שתשלום חשובונתיו מסתמך על תרומות, כגון שם ה-domain שלנו, gitbook, netlify ו-serverless hosting. אם אתם רוצים לתמוך ב-Fiber, אתם יכולים ☕ [**קנו קפה כאן**](https://buymeacoff.ee/fenny).
|
||||
</div>
|
||||
|
||||
| | משתמש | תרומה |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## 💻 תורמי קוד
|
||||
</div>
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
</div>
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
## ⚠️ רישיון
|
||||
</div>
|
||||
|
||||
<div dir="ltr">
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
</div>
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
**רישיונות של ספריות צד שלישי**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
||||
</div>
|
|
@ -1,593 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 Pengukuran Kinerja
|
||||
|
||||
Pengukuran ini dilakukan oleh [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) dan [Go Web](https://github.com/smallnest/go-web-framework-benchmark). Apabila anda ingin melihat hasil lengkapnya, silahkan kunjungi halaman [Wiki](https://docs.gofiber.io/benchmarks) kami.
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ 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/...
|
||||
```
|
||||
|
||||
## 🎯 Fitur
|
||||
|
||||
- Sistem [Routing](https://docs.gofiber.io/routing) yang solid
|
||||
- Serve [file statis](https://docs.gofiber.io/application#static)
|
||||
- [Kinerja](https://docs.gofiber.io/benchmarks) ekstrim
|
||||
- [Penggunaan memori](https://docs.gofiber.io/benchmarks) yang kecil
|
||||
- Cocok untuk [API](https://docs.gofiber.io/context)
|
||||
- Mendukung Middleware & [Next](https://docs.gofiber.io/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)
|
||||
- [Template engines](https://github.com/gofiber/template)
|
||||
- [WebSocket support](https://docs.gofiber.io/middleware#websocket)
|
||||
- [Rate Limiter](https://docs.gofiber.io/middleware#limiter)
|
||||
- Available in [15 languages](https://docs.gofiber.io/)
|
||||
- Dan masih banyak lagi, [kunjungi Fiber](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 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://docs.gofiber.io) kami.
|
||||
|
||||
Listed below are some of the common examples. If you want to see more code examples , please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/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
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
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
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket Upgrade
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 Media
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 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=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%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. Help us to translate our API Documentation via [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Support the project by donating a [cup of coffee](https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ Supporters
|
||||
|
||||
Fiber is an open source project that runs on donations to pay the bills e.g. our domain name, gitbook, netlify and serverless hosting. If you want to support Fiber, you can ☕ [**buy a coffee here**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Code Contributors
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ License
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,594 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<strong>FIber</strong>は、<a href="https://github.com/expressjs/express">Express</a>に触発された<strong>Webフレームワーク</strong>です。<a href="https://golang.org/doc/">Go</a><strong> 最速</strong>のHTTPエンジンである<a href="https://github.com/valyala/fasthttp">Fasthttp</a>で作られています。<strong>ゼロメモリアロケーション</strong>と<strong>パフォーマンス</strong>を念頭に置いて設計されており、<strong>迅速</strong>な開発をサポートします。
|
||||
|
||||
</p>
|
||||
|
||||
## ⚡️ クイックスタート
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
## 🤖 ベンチマーク
|
||||
|
||||
これらのテストは[TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext)および[Go Web](https://github.com/smallnest/go-web-framework-benchmark)によって計測を行っています 。すべての結果を表示するには、 [Wiki](https://docs.gofiber.io/benchmarks)にアクセスしてください。
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ インストール
|
||||
|
||||
まず、Goを[ダウンロード](https://golang.org/dl/)してください。 `1.11`以降が必要です。
|
||||
|
||||
そして、[`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them)コマンドを使用してインストールしてください。
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber/...
|
||||
```
|
||||
|
||||
## 🎯 機能
|
||||
|
||||
- 堅牢な[ルーティング](https://docs.gofiber.io/routing)
|
||||
- [静的ファイル](https://docs.gofiber.io/application#static)のサポート
|
||||
- 究極の[パフォーマンス](https://docs.gofiber.io/benchmarks)
|
||||
- [低メモリ](https://docs.gofiber.io/benchmarks)フットプリント
|
||||
- Express [APIエンドポイント](https://docs.gofiber.io/context)
|
||||
- Middlewareと[Next](https://docs.gofiber.io/context#next)のサポート
|
||||
- [迅速](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497)なサーバーサイドプログラミング
|
||||
- [Template engines](https://github.com/gofiber/template)
|
||||
- [WebSocket support](https://docs.gofiber.io/middleware#websocket)
|
||||
- [Rate Limiter](https://docs.gofiber.io/middleware#limiter)
|
||||
- Available in [15 languages](https://docs.gofiber.io/)
|
||||
- [Fiber](https://docs.gofiber.io/)をもっと知る
|
||||
|
||||
## 💡 哲学
|
||||
|
||||
[Node.js](https://nodejs.org/en/about/)から[Go](https://golang.org/doc/) に乗り換えようとしている新しいGopherはWebフレームワークやマイクロサービスの構築を始める前に多くを学ばなければなりません。
|
||||
しかし、 **Webフレームワーク**であるFiberは**ミニマリズム**と**UNIX哲学**をもとに作られているため、新しいGopherはスムーズにGoの世界に入ることができます。
|
||||
|
||||
Fiberは人気の高いWebフレームワークであるExpressjsに**インスパイア**されています。
|
||||
わたしたちは Expressの**手軽さ**とGoの**パフォーマンス**を組み合わせました。
|
||||
もしも、WebアプリケーションをExpress等のNode.jsフレームワークで実装した経験があれば、多くの方法や原理がとても**馴染み深い**でしょう。
|
||||
|
||||
## 👀 例
|
||||
|
||||
以下に一般的な例をいくつか示します。他のコード例をご覧になりたい場合は、 [Recipesリポジトリ](https://github.com/gofiber/recipes)または[APIドキュメント](https://docs.gofiber.io)にアクセスしてください。
|
||||
|
||||
Listed below are some of the common examples. If you want to see more code examples , please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/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
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
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
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket Upgrade
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 メディア
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 貢献する
|
||||
|
||||
`Fiber`に開発支援してくださるなら:
|
||||
|
||||
1. [GitHub Star](https://github.com/gofiber/fiber/stargazers)をつけてください 。
|
||||
2. [あなたのTwitterで](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber)プロジェクトについてツイートしてください。
|
||||
3. [Medium](https://medium.com/) 、 [Dev.to、](https://dev.to/)または個人のブログでレビューまたはチュートリアルを書いてください。
|
||||
4. Help us to translate our API Documentation via [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Support the project by donating a [cup of coffee](https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ Supporters
|
||||
|
||||
Fiber is an open source project that runs on donations to pay the bills e.g. our domain name, gitbook, netlify and serverless hosting. If you want to support Fiber, you can ☕ [**buy a coffee here**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Code Contributors
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ License
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,596 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<b>Fiber</b>는 <a href="https://github.com/expressjs/express">Express</a>에서 영감을 받고, <a href="https://golang.org/doc/">Go</a>를 위한 <b>가장 빠른</b> HTTP 엔진인 <a ref="https://github.com/valyala/fasthttp">Fasthttp</a>를 토대로 만들어진 <b>웹 프레임워크</b> 입니다. <b>비 메모리 할당</b>과 <b>성능</b>을 고려한 <b>빠른</b> 개발을 위해 <b>손쉽게</b> 사용되도록 설계되었습니다.
|
||||
</p>
|
||||
|
||||
## ⚡️ 빠른 시작
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 벤치마크
|
||||
|
||||
이 테스트들은 [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext)와 [Go Web](https://github.com/smallnest/go-web-framework-benchmark)을 통해 측정되었습니다. 만약 모든 결과를 보고 싶다면, [Wiki](https://docs.gofiber.io/benchmarks)를 확인해 주세요.
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
|
||||
## ⚙️ 설치
|
||||
|
||||
우선, Go를 [다운로드](https://golang.org/dl/)하고 설치합니다. `1.11` 버전 이상이 요구됩니다.
|
||||
|
||||
[`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) 명령어를 이용해 설치가 완료됩니다:
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber/...
|
||||
```
|
||||
|
||||
## 🎯 특징
|
||||
|
||||
- 견고한 [라우팅](https://docs.gofiber.io/routing)
|
||||
- [정적 파일](https://docs.gofiber.io/application#static) 제공
|
||||
- 뛰어난 [성능](https://docs.gofiber.io/benchmarks)
|
||||
- [적은 메모리](https://docs.gofiber.io/benchmarks) 공간
|
||||
- [API 엔드포인트](https://docs.gofiber.io/context)
|
||||
- 미들웨어 & [Next](https://docs.gofiber.io/context#next) 지원
|
||||
- [빠른](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) 서버 사이드 프로그래밍
|
||||
- [Template engines](https://github.com/gofiber/template)
|
||||
- [WebSocket support](https://docs.gofiber.io/middleware#websocket)
|
||||
- [Rate Limiter](https://docs.gofiber.io/middleware#limiter)
|
||||
- Available in [15 languages](https://docs.gofiber.io/)
|
||||
- 더 알고 싶다면, [Fiber 둘러보기](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 철학
|
||||
|
||||
[Node.js](https://nodejs.org/en/about/)에서 [Go](https://golang.org/doc/)로 전환하는 새로운 고퍼분들은 웹 어플리케이션이나 마이크로 서비스 개발을 시작할 수 있게 되기 전에 학습 곡선에 시달리고 있습니다. Fiber는 **웹 프레임워크**로서, 새로운 고퍼분들이 따뜻하고 믿음직한 환영을 가지고 빠르게 Go의 세상에 진입할 수 있게 **미니멀리즘**의 개념과 **UNIX 방식**에 따라 개발되었습니다.
|
||||
|
||||
Fiber는 인터넷에서 가장 인기있는 웹 프레임워크인 Express에서 **영감을 받았습니다.** 우리는 Express의 **쉬운** 사용과 Go의 **성능**을 결합하였습니다. 만약 당신이 Node.js (Express 또는 비슷한 것을 사용하여) 로 웹 어플리케이션을 개발한 경험이 있다면, 많은 메소드들과 원리들이 **매우 비슷하게** 느껴질 것 입니다.
|
||||
|
||||
우리는 **어떤한** 작업, **마감일정**, 개발자의 **기술**이던간에 **빠르고**, **유연하고**, **익숙한** Go 웹 프레임워크를 만들기 위해 사용자들의 [이슈들](https://github.com/gofiber/fiber/issues)을(그리고 모든 인터넷을 통해) **듣고 있습니다**! Express가 자바스크립트 세계에서 하는 것 처럼요.
|
||||
|
||||
## 👀 예제
|
||||
|
||||
다음은 일반적인 예제들 입니다.
|
||||
|
||||
> 더 많은 코드 예제를 보고 싶다면, [Recipes 저장소](https://github.com/gofiber/recipes) 또는 [API 문서](https://docs.gofiber.io)를 방문하세요.
|
||||
|
||||
Listed below are some of the common examples. If you want to see more code examples , please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/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
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
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
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket Upgrade
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 미디어
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 기여
|
||||
|
||||
`Fiber`의 활발한 개발을 지원하고 감사 인사를 하고 싶다면:
|
||||
|
||||
1. 프로젝트에 [GitHub Star](https://github.com/gofiber/fiber/stargazers)를 추가하세요.
|
||||
2. [트위터에서](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber) 프로젝트에 대해 트윗하세요.
|
||||
3. [Medium](https://medium.com/), [Dev.to](https://dev.to/) 또는 개인 블로그에 리뷰 또는 튜토리얼을 작성하세요.
|
||||
4. Help us to translate our API Documentation via [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Support the project by donating a [cup of coffee](https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ Supporters
|
||||
|
||||
Fiber is an open source project that runs on donations to pay the bills e.g. our domain name, gitbook, netlify and serverless hosting. If you want to support Fiber, you can ☕ [**buy a coffee here**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Code Contributors
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ License
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,595 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<b>Fiber</b> is een <b>web framework</b> geïnspireerd door <a href="https://github.com/expressjs/express">Express</a> gebouwd bovenop <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, de <b>snelste</b> HTTP-engine voor <a href="https://golang.org/doc/">Go</a>. Ontworpen om <b>snelle</b> ontwikkeling <b>gemakkelijker</b> te maken <b>zonder geheugenallocatie</b> tezamen met <b>hoge prestaties</b>.
|
||||
</p>
|
||||
|
||||
## ⚡️ Bliksemsnelle start
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 Benchmarks
|
||||
|
||||
Deze tests zijn uitgevoerd door [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) en [Go Web](https://github.com/smallnest/go-web-framework-benchmark). Bezoek onze [Wiki](https://fiber.wiki/benchmarks) voor alle benchmark resultaten.
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ Installatie
|
||||
|
||||
Allereerst, [download](https://golang.org/dl/) en installeer Go. `1.11` of hoger is vereist.
|
||||
|
||||
Installatie wordt gedaan met behulp van het [`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) commando:
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber
|
||||
```
|
||||
|
||||
## 🎯 Features
|
||||
|
||||
- Robuuste [routing](https://fiber.wiki/routing)
|
||||
- Serveer [statische bestanden](https://fiber.wiki/application#static)
|
||||
- Extreme [prestaties](https://fiber.wiki/benchmarks)
|
||||
- [Weinig geheugenruimte](https://fiber.wiki/benchmarks)
|
||||
- [API endpoints](https://fiber.wiki/context)
|
||||
- [Middleware](https://fiber.wiki/middleware) & [Next](https://fiber.wiki/context#next) ondersteuning
|
||||
- [Snelle](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) server-side programmering
|
||||
- [Template engines](https://fiber.wiki/middleware#template)
|
||||
- [WebSocket ondersteuning](https://fiber.wiki/middleware#websocket)
|
||||
- [Rate Limiter](https://fiber.wiki/middleware#limiter)
|
||||
- Vertaald in [15 talen](https://docs.gofiber.io/)
|
||||
- En nog veel meer, [ontdek Fiber](https://fiber.wiki/)
|
||||
|
||||
## 💡 Filosofie
|
||||
|
||||
Nieuwe gophers die de overstap maken van [Node.js](https://nodejs.org/en/about/) naar [Go](https://golang.org/doc/), hebben te maken met een leercurve voordat ze kunnen beginnen met het bouwen van hun webapplicaties of microservices. Fiber, als een **web framework**, is gebouwd met het idee van **minimalisme** en volgt de **UNIX-manier**, zodat nieuwe gophers snel de wereld van Go kunnen betreden met een warm en vertrouwd welkom.\
|
||||
|
||||
Fiber is **geïnspireerd** door Express, het populairste webframework op internet. We hebben het **gemak** van Express gecombineerd met de **onbewerkte prestaties** van Go. Als je ooit een webapplicatie in Node.js hebt geïmplementeerd (_zoals Express of vergelijkbaar_), dan zullen veel methoden en principes **heel gewoon** voor je lijken.
|
||||
|
||||
We **luisteren** naar onze gebruikers in [issues](https://github.com/gofiber/fiber/issues) (_en overal op het internet_) om een **snelle**, **flexibele** en **vriendelijk** Go web framework te maken voor **elke** taak, **deadline** en ontwikkelaar **vaardigheid**! Net zoals Express dat doet in de JavaScript-wereld.
|
||||
|
||||
## 👀 Voorbeelden
|
||||
|
||||
Hieronder staan enkele van de meest voorkomende voorbeelden.
|
||||
|
||||
> Bekijk ons [Recepten repository](https://github.com/gofiber/recipes) voor meer voorbeelden met code of bezoek onze [API documentatie](https://fiber.wiki).
|
||||
|
||||
Listed below are some of the common examples. If you want to see more code examples , please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/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
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
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
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket Upgrade
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 Media
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 Bijdragen
|
||||
|
||||
Om de actieve ontwikkelingen van `Fiber` te ondersteunen of om een **bedankje** te geven:
|
||||
|
||||
1. Voeg een [GitHub Star](https://github.com/gofiber/fiber/stargazers) toe aan het project.
|
||||
2. Tweet over het project [op je Twitter account](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
|
||||
3. Schrijf een recensie of tutorial op [Medium](https://medium.com/), [Dev.to](https://dev.to/) of een persoonlijke blog.
|
||||
4. Help us to translate our API Documentation via [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Support the project by donating a [cup of coffee](https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ Supporters
|
||||
|
||||
Fiber is an open source project that runs on donations to pay the bills e.g. our domain name, gitbook, netlify and serverless hosting. If you want to support Fiber, you can ☕ [**buy a coffee here**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Code Contributors
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ License
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,591 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<b>Fiber</b> é um <b>framework web</b> inspirado no <a href="https://github.com/expressjs/express">Express</a>, construído sobre o <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, o motor HTTP <b>mais rápido</b> do <a href="https://golang.org/doc/">Go</a>. Projetado para <b>facilitar</b> e <b>acelerar</b> o desenvolvimento, com <b>zero de alocação de memória</b> e <b>desempenho</b> em mente.
|
||||
</p>
|
||||
|
||||
## ⚡️ Início rápido
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 Benchmarks
|
||||
|
||||
Esses testes são realizados pelo [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) e [Go Web](https://github.com/smallnest/go-web-framework-benchmark). Se você quiser ver todos os resultados, visite nosso [Wiki](https://docs.gofiber.io/benchmarks) .
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ Instalação
|
||||
|
||||
Primeiro de tudo, faça o [download](https://golang.org/dl/) e instale o Go. É necessário a versão `1.11` ou superior.
|
||||
|
||||
A instalação é feita usando o comando [`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) :
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber/...
|
||||
```
|
||||
|
||||
## 🎯 Recursos
|
||||
|
||||
- [Roteamento](https://docs.gofiber.io/routing) robusto
|
||||
- Servir [arquivos estáticos](https://docs.gofiber.io/application#static)
|
||||
- [Desempenho](https://docs.gofiber.io/benchmarks) extremo
|
||||
- [Baixo consumo de memória](https://docs.gofiber.io/benchmarks)
|
||||
- [API de rotas](https://docs.gofiber.io/context)
|
||||
- Suporte à Middleware e [Next](https://docs.gofiber.io/context#next)
|
||||
- Programação [rápida](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) de aplicações de servidor
|
||||
- [Templates](https://github.com/gofiber/template)
|
||||
- [Suporte à WebSockets](https://docs.gofiber.io/middleware#websocket)
|
||||
- [Limitador de requisições](https://docs.gofiber.io/middleware#limiter)
|
||||
- Disponível em [15 línguas](https://docs.gofiber.io/)
|
||||
- E muito mais, [explore o Fiber](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 Filosofia
|
||||
|
||||
Os novos gophers que mudaram do [Node.js](https://nodejs.org/en/about/) para o [Go](https://golang.org/doc/) estão tendo que lidar com uma curva de aprendizado antes que possam começar a criar seus aplicativos web ou microsserviços. O Fiber, como um **framework web**, foi criado com a ideia de ser **minimalista** e seguindo a **filosofia UNIX**, para que novos gophers possam, rapidamente, entrar no mundo do Go com uma recepção calorosa e confiável.
|
||||
|
||||
O Fiber é **inspirado** no Express, o framework web mais popular da Internet. Combinamos a **facilidade** do Express e com o **desempenho bruto** do Go. Se você já implementou um aplicativo web com Node.js ( _usando Express.js ou similar_ ), então muitos métodos e princípios parecerão **muito familiares** para você.
|
||||
|
||||
## 👀 Exemplos
|
||||
|
||||
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://docs.gofiber.io).
|
||||
|
||||
#### 📖 [**Roteamento básico**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Servindo arquivos estáticos**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Mostrar mais exemplos</summary>
|
||||
|
||||
### Engines de visualização
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
O Fiber usa por padrão o [html/template](https://golang.org/pkg/html/template/) quando nenhuma engine é selecionada.
|
||||
|
||||
Se você quiser uma execução parcial ou usar uma engine diferente como [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) ou [pug](https://github.com/Joker/jade) etc.. Dê uma olhada no package [Template](https://github.com/gofiber/template) que suporta multiplas engines de visualização.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Agrupamento de rotas
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/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
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Verifique o CORS passando qualquer domínio no header `Origin`:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Resposta 404 customizada
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
### Resposta JSON
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware Recover
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬Middlewares Fiber
|
||||
|
||||
Os middlewares Fiber listados aqui são mantidos pelo [Time Fiber](https://github.com/orgs/gofiber/people).
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Middlewares Third Party
|
||||
|
||||
Esta é uma lista de middlewares criados pela comunidade do Fiber, se quiser ter o seu middleware aqui, é só abrir um PR!
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 Mídia
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 Contribuindo
|
||||
|
||||
Se você quer **agradecer** e/ou apoiar o desenvolvimento ativo do `Fiber`:
|
||||
|
||||
1. Deixe uma [estrela no GitHub](https://github.com/gofiber/fiber/stargazers) do projeto.
|
||||
2. Tweet sobre o projeto [no seu Twitter](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
|
||||
3. Escreva um review ou tutorial no [Medium](https://medium.com/), [Dev.to](https://dev.to/) ou blog pessoal.
|
||||
4. Nos ajude a traduzir a documentação da API no [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Apoie o projeto pagando uma [xícara de café](https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ Apoiadores
|
||||
|
||||
Fiber é um projeto open source que usa de doações para pagar seus custos (domínio, GitBook, Netlify e hospedagem serverless). Se você quiser apoiar o projeto, você pode ☕ [**pagar um café**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Contribuidores de código
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ Licença
|
||||
|
||||
Todos os direitos reservados (c) 2019-presente [Fenny](https://github.com/fenny) e [Contribuidores](https://github.com/gofiber/fiber/graphs/contributors).
|
||||
`Fiber` é software livre e aberto sob a [licença MIT](https://github.com/gofiber/fiber/blob/master/LICENSE).
|
||||
O logo oficial foi criado por [Vic Shóstak](https://github.com/koddr) e distribuído sob a licença [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) (CC BY-SA 4.0 International).
|
||||
|
||||
**Licença das bibliotecas de terceiros**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,596 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<strong>Fiber</strong> — это <strong>веб фреймворк</strong>, который был вдохновлен <a href="https://github.com/expressjs/express">Express</a> и основан на <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, самом быстром HTTP-движке написанном на <a href="https://golang.org/doc/">Go</a>. Фреймворк был разработан с целью <strong>упростить</strong> процесс <strong>быстрой</strong> разработки <strong>высокопроизводительных</strong> веб-приложений с <strong>нулевым распределением памяти</strong>.
|
||||
</p>
|
||||
|
||||
## ⚡️ Быстрый старт
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 Бенчмарки
|
||||
|
||||
Тестирование проводилось с помощью [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) и [Go Web](https://github.com/smallnest/go-web-framework-benchmark). Если вы хотите увидеть все результаты, пожалуйста, посетите наш [Wiki](https://docs.gofiber.io/benchmarks).
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ Установка
|
||||
|
||||
Прежде всего, [скачайте](https://golang.org/dl/) и установите Go. Версия **1.11** или выше.
|
||||
|
||||
Установка выполняется с помощью команды [`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them):
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber
|
||||
```
|
||||
|
||||
## 🎯 Особенности
|
||||
|
||||
- Надежная [маршрутизация](https://docs.gofiber.io/routing)
|
||||
- Доступ к [статичным файлам](https://docs.gofiber.io/application#static)
|
||||
- Экстремальная [производительность](https://docs.gofiber.io/benchmarks)
|
||||
- [Низкий объем потребления памяти](https://docs.gofiber.io/benchmarks)
|
||||
- [Эндпоинты](https://docs.gofiber.io/context), как в [API](https://docs.gofiber.io/context) Express
|
||||
- [Middleware](https://docs.gofiber.io/middleware) и поддержка [Next](https://docs.gofiber.io/context#next)
|
||||
- [Быстрое](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) программирование на стороне сервера
|
||||
- [Template engines](https://github.com/gofiber/template)
|
||||
- [Поддержка WebSocket](https://docs.gofiber.io/middleware#websocket)
|
||||
- [Rate Limiter](https://docs.gofiber.io/middleware#limiter)
|
||||
- Документация доступна на [15 языках](https://docs.gofiber.io/)
|
||||
- И многое другое, [посетите наш Wiki](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 Философия
|
||||
|
||||
Новые Go-программисты, которые переключаются с [Node.js](https://nodejs.org/en/about/) на [Go](https://golang.org/doc/), имеют дело с очень извилистой кривой обучения, прежде чем они смогут начать создавать свои веб-приложения или микросервисы. Fiber, как **веб-фреймворк**, был создан с идеей **минимализма** и следовал **принципу UNIX**, так что новички смогут быстро войти в мир Go без особых проблем.
|
||||
|
||||
Fiber **вдохновлен** Express, самым популярным веб фреймворком в Интернете. Мы объединили **простоту** Express и **чистую производительность** Go. Если вы когда-либо реализовывали веб-приложение на Node.js (*с использованием Express или аналогичного фреймворка*), то многие методы и принципы покажутся вам **очень знакомыми**.
|
||||
|
||||
Мы **прислушиваемся** к нашим пользователям в [issues](https://github.com/gofiber/fiber/issues), Discord [канале](https://gofiber.io/discord) _и в остальном Интернете_, чтобы создать **быстрый**, **гибкий** и **дружелюбный** веб фреймворк на Go для **любых** задач, **дедлайнов** и **уровней** разработчиков! Как это делает Express в мире JavaScript.
|
||||
|
||||
## 👀 Примеры
|
||||
|
||||
Ниже перечислены некоторые из распространенных примеров. Если вы хотите увидеть больше примеров кода, пожалуйста, посетите наш [репозиторий рецептов](https://github.com/gofiber/recipes) или [документацию по API](https://docs.gofiber.io).
|
||||
|
||||
Listed below are some of the common examples. If you want to see more code examples , please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Показать больше примеров кода</summary>
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/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
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Проверем CORS, присвоив домен в заголовок `Origin`, отличный от `localhost`:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket Upgrade
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Middlewares от сторонних разработчиков
|
||||
|
||||
Это список middlewares, созданных сообществом Fiber. Пожалуйста, [создайте PR](https://github.com/gofiber/fiber/pulls), если хотите добавить в этот список свой или известный вам middleware для веб фреймворка Fiber!
|
||||
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 Медиа
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 Помощь проекту
|
||||
|
||||
Если вы хотите сказать **спасибо** и/или поддержать активное развитие `Fiber`:
|
||||
|
||||
1. Добавьте [GitHub Star](https://github.com/gofiber/fiber/stargazers) в проект.
|
||||
2. Напишите о проекте [в вашем Twitter](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
|
||||
3. Сделайте обзор фреймворка на [Medium](https://medium.com/), [Dev.to](https://dev.to/) или в личном блоге.
|
||||
4. Помогите перевести нашу API документацию на платформе [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Поддержите проект, купив [чашку кофе](https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ Поддержка проекта
|
||||
|
||||
Fiber — это проект с открытым исходным кодом, который работает на пожертвования для оплаты счетов, например, нашего доменного имени, GitBook, Netlify и serverless-хостинга.
|
||||
|
||||
Если вы хотите поддержать, то ☕ [**купите чашку кофе**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | Пользователи | Пожертвования |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Контрибьютеры
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ License
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,588 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<b>Fiber</b>, <a href="https://golang.org/doc/">Go</a> için <b>en hızlı</b> HTTP motoru olan <a href="https://github.com/valyala/fasthttp">Fasthttp</a> üzerine inşa edilmiş, <a href="https://github.com/expressjs/express">Express</a> den ilham alan bir <b>web çatısıdır</b>. <b>Sıfır bellek ayırma</b> ve <b>performans</b> göz önünde bulundurularak <b>hızlı</b> geliştirme için işleri <b>kolaylaştırmak</b> üzere tasarlandı.
|
||||
</p>
|
||||
|
||||
## ⚡️ Hızlı Başlangıç
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 Performans Ölçümleri
|
||||
|
||||
Bu testler [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) ve [Go Web](https://github.com/smallnest/go-web-framework-benchmark) ile koşuldu. Bütün sonuçları görmek için lütfen [Wiki](https://docs.gofiber.io/benchmarks) sayfasını ziyaret ediniz.
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ Kurulum
|
||||
|
||||
İlk önce, Go yu [indirip](https://golang.org/dl/) kuruyoruz. `1.11` veya daha yeni sürüm gereklidir.
|
||||
|
||||
[`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) komutunu kullanarak kurulumu tamamlıyoruz:
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber/...
|
||||
```
|
||||
|
||||
## 🎯 Özellikler
|
||||
|
||||
- Güçlü [rotalar](https://docs.gofiber.io/routing)
|
||||
- [Statik dosya](https://docs.gofiber.io/application#static) yönetimi
|
||||
- Olağanüstü [performans](https://docs.gofiber.io/benchmarks)
|
||||
- [Düşük bellek](https://docs.gofiber.io/benchmarks) tüketimi
|
||||
- [API uç noktaları](https://docs.gofiber.io/context)
|
||||
- Ara katman & [Sonraki](https://docs.gofiber.io/context#next) desteği
|
||||
- [Hızlı](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) sunucu taraflı programlama
|
||||
- [Template engines](https://github.com/gofiber/template)
|
||||
- [WebSocket support](https://docs.gofiber.io/middleware#websocket)
|
||||
- [Rate Limiter](https://docs.gofiber.io/middleware#limiter)
|
||||
- Available in [15 languages](https://docs.gofiber.io/)
|
||||
- Ve daha fazlası, [Fiber ı keşfet](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 Felsefe
|
||||
|
||||
[Node.js](https://nodejs.org/en/about/) den [Go](https://golang.org/doc/) ya geçen yeni gopher lar kendi web uygulamalarını ve mikroservislerini yazmaya başlamadan önce dili öğrenmek ile uğraşıyorlar. Fiber, bir **web çatısı** olarak, **minimalizm** ve **UNIX yolu**nu izlemek fikri ile oluşturuldu. Böylece yeni gopher lar sıcak ve güvenilir bir hoşgeldin ile Go dünyasına giriş yapabilirler.
|
||||
|
||||
Fiber internet üzerinde en popüler olan Express web çatısından **esinlenmiştir**. Biz Express in **kolaylığını** ve Go nun **ham performansını** birleştirdik. Daha önce Node.js üzerinde (Express veya benzerini kullanarak) bir web uygulaması geliştirdiyseniz, pek çok metod ve prensip size **çok tanıdık** gelecektir.
|
||||
|
||||
## 👀 Örnekler
|
||||
|
||||
Aşağıda yaygın örneklerden bazıları listelenmiştir. Daha fazla kod örneği görmek için, lütfen [Kod deposunu](https://github.com/gofiber/recipes) veya [API dökümantasyonunu](https://docs.gofiber.io) ziyaret ediniz.
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Daha fazla kod örneği göster</summary>
|
||||
|
||||
### Views engines
|
||||
|
||||
📖 [Settings](https://docs.gofiber.io/application#settings)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
📖 [Render](https://docs.gofiber.io/context#render)
|
||||
|
||||
Fiber defaults to the [html/template](https://golang.org/pkg/html/template/) when no view engine is set.
|
||||
|
||||
If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache) or [pug](https://github.com/Joker/jade) etc..
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Rotaları Zincirlere Gruplama
|
||||
|
||||
📖 [Grup](https://docs.gofiber.io/application#group)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Kök API rotası
|
||||
api := app.Group("/api", cors()) // /api
|
||||
|
||||
// API v1 rotası
|
||||
v1 := api.Group("/v1", mysql()) // /api/v1
|
||||
v1.Get("/list", handler) // /api/v1/list
|
||||
v1.Get("/user", handler) // /api/v1/user
|
||||
|
||||
// API v2 rotası
|
||||
v2 := api.Group("/v2", mongodb()) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Ara Katman Günlükcüsü(Logger)
|
||||
|
||||
📖 [Günlükcü](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Farklı Merkezler Arası Kaynak Paylaşımı (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Varsayılan ayarlarla CORS
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
`Origin` başlığı içinde herhangı bir alan adı kullanarak CORS'u kontrol et:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Özelleştirilebilir 404 yanıtları
|
||||
|
||||
📖 [HTTP Methodlari](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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!")
|
||||
})
|
||||
|
||||
// Herhangi bir şeyle eşleşen son ara katman
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Yanıtları
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket Yükseltmesi
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber Middleware
|
||||
|
||||
The Fiber middleware modules listed here are maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||
|
||||
| Middleware | Description | Built-in middleware |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 Third Party Middlewares
|
||||
|
||||
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 Medya
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 Destek
|
||||
|
||||
Eğer **teşekkür etmek** ve/veya `Fiber`'in aktif geliştirilmesini desteklemek istiyorsanız:
|
||||
|
||||
1. Projeye [GitHub Yıldızı](https://github.com/gofiber/fiber/stargazers) verin.
|
||||
2. [Twitter hesabınızdan](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber) proje hakkında tweet atın.
|
||||
3. [Medium](https://medium.com/), [Dev.to](https://dev.to/) veya kişisel blog üzerinden bir inceleme veya eğitici yazı yazın.
|
||||
4. API dökümantasyonunu çevirerek destek olabilirsiniz [Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)
|
||||
5. Projeye [bir fincan kahve] ısmarlayarak projeye destek olabilirsiniz(https://buymeacoff.ee/fenny).
|
||||
|
||||
## ☕ Destekçiler
|
||||
Fiber, alan adı, gitbook, netlify, serverless yer sağlayıcısı giderleri ve benzeri şeyleri ödemek için bağışlarla yaşayan bir açık kaynaklı projedir. Eğer Fiber'e destek olmak isterseniz, ☕ [**buradan kahve ısmarlayabilirsiniz.**](https://buymeacoff.ee/fenny)
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Koda Katkı Sağlayanlar
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ Lisans
|
||||
|
||||
Telif (c) 2019-günümüz [Fenny](https://github.com/fenny) ve [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber`, [MIT Lisansı](https://github.com/gofiber/fiber/blob/master/LICENSE) altında özgür ve açık kaynaklı bir yazılımdır. Resmi logosu [Vic Shóstak](https://github.com/koddr) tarafında tasarlanmıştır ve [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) lisansı altında dağıtımı yapılır. (CC BY-SA 4.0 International).
|
||||
|
||||
**3. Parti yazılım lisanları**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,593 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<b>Fiber</b>是一个受到<a href="https://github.com/expressjs/express">Express</a>启发的<b>Web框架</b>,建立在<a href="https://golang.org/doc/">Go</a>语言写的<b>最快的</b><a href="https://github.com/valyala/fasthttp">Fasthttp</a>HTTP引擎的基础上。旨在<b>简化</b> <b>零内存分配</b>和<b>提高性能</b>,以便<b>快速</b>开发。
|
||||
</p>
|
||||
|
||||
## ⚡️ 快速入门
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 性能
|
||||
|
||||
这些测试由[TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext)和[Go Web](https://github.com/smallnest/go-web-framework-benchmark) 执行。如果要查看所有结果,请访问我们的[Wiki](https://docs.gofiber.io/benchmarks) 。
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ 安装
|
||||
|
||||
首先, [下载](https://golang.org/dl/)并安装Go。 需要`1.11`或更高版本。
|
||||
|
||||
使用[`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them)命令完成安装:
|
||||
|
||||
```bash
|
||||
export GO111MODULE=on
|
||||
export GOPROXY=https://goproxy.cn
|
||||
|
||||
go get -u github.com/gofiber/fiber
|
||||
```
|
||||
|
||||
## 🎯 特点
|
||||
|
||||
- 强大的[路由](https://docs.gofiber.io/routing)
|
||||
- [静态文件](https://docs.gofiber.io/application#static)服务
|
||||
- 极限[表现](https://docs.gofiber.io/benchmarks)
|
||||
- [内存占用低](https://docs.gofiber.io/benchmarks)
|
||||
- [API接口](https://docs.gofiber.io/context)
|
||||
- [中间件](https://docs.gofiber.io/middleware)和[Next](https://docs.gofiber.io/context#next)支持
|
||||
- [快速](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497)服务器端编程
|
||||
- [模版引擎](https://github.com/gofiber/template)
|
||||
- [WebSocket支持](https://docs.gofiber.io/middleware#websocket)
|
||||
- [频率限制器](https://docs.gofiber.io/middleware#limiter)
|
||||
- [15种语言](https://docs.gofiber.io/)
|
||||
- 以及更多请[探索文档](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 哲学
|
||||
|
||||
从[Node.js](https://nodejs.org/en/about/)切换到[Go](https://golang.org/doc/)的新`gopher`在开始构建`Web`应用程序或微服务之前正在应对学习曲线。 `Fiber`作为一个**Web框架** ,是按照**极简主义**的思想并遵循**UNIX方式**创建的,因此新的`gopher`可以在热烈和可信赖的欢迎中迅速进入`Go`的世界。
|
||||
|
||||
`Fiber`受到了互联网上最流行的`Web`框架`Express`的**启发** 。我们结合了`Express`的**易用性**和`Go`的**原始性能** 。如果您曾经在`Node.js`上实现过`Web`应用程序(*使用Express或类似工具*),那么许多方法和原理对您来说应该**非常易懂**。
|
||||
|
||||
我们**关注** _整个互联网_ 用户在[issues](https://github.com/gofiber/fiber/issues)和Discord [channel](https://gofiber.io/discord)的消息,为了创建一个**迅速**,**灵活**以及**友好**的`Go web`框架,满足**任何**任务,**最后期限**和开发者**技能**。就像`Express`在`JavaScript`世界中一样。
|
||||
|
||||
## 👀 示例
|
||||
|
||||
下面列出了一些常见示例。如果您想查看更多代码示例,请访问我们的[Recipes](https://github.com/gofiber/recipes)代码库或[API文档](https://docs.gofiber.io) 。
|
||||
|
||||
#### 📖 [**基础路由**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**静态文件**](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**中间件**](https://docs.gofiber.io/middleware)和[**Next**](https://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 展示更多代码示例</summary>
|
||||
|
||||
### 模版引擎
|
||||
|
||||
📖 [配置](https://docs.gofiber.io/application#settings)
|
||||
📖 [模版引擎](https://github.com/gofiber/template)
|
||||
📖 [渲染](https://docs.gofiber.io/context#render)
|
||||
|
||||
如果未设置模版引擎,则`Fiber`默认使用[html/template](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)等等...
|
||||
|
||||
请查看我们的[Template](https://github.com/gofiber/template)包,该包支持多个模版引擎。
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 组合路由链
|
||||
|
||||
📖 [路由分组](https://docs.gofiber.io/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
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 日志中间件
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Custom logging format
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
### 跨域资源共享(CORS)中间件
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
通过在请求头中设置`Origin`传递任何域来检查CORS:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### 自定义404响应
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
### JSON响应
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### 升级到WebSocket
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### 恢复(panic)中间件
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber中间件
|
||||
|
||||
此处列出的`Fiber`中间件模块由[Fiber团队](https://github.com/orgs/gofiber/people)维护。
|
||||
|
||||
| 中间件 | 描述 | 内置中间件 |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | `net/http`处理程序与`Fiber`处理程序之间的适配器,特别感谢 @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | 基本身份验证中间件提供HTTP基本身份验证。验证有效时,它调用下一个处理程序,否则返回`401 Unauthorized`响应。 | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | `Fiber`的压缩中间件,默认情况下支持`deflate`,`gzip`和`brotli`。 | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | 使用各种选项启用跨域资源共享(CORS)。 | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | 保护免受CSRF攻击。 | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | `Fiber`的FileSystem中间件,特别感谢 Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | 如果提供了`favicon`文件路径,则忽略日志中的图标或从内存中提供图标。 | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | 通过设置各种HTTP标头来保护您的应用程序。 | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT是返回JSON Web令牌(JWT)的身份验证中间件。 | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | 密钥身份验证中间件提供基于密钥的身份验证。 | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | `Fiber`的频率限制中间件。用于限制对公共API的重复请求,例如密码重置。 | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP 访问日志中间件。 | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | 特别感谢 Matthew Lee (@mthli) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | 恢复中间件可从堆栈链中任何地方的`panic`中恢复,并将控制权交给集中式[错误处理器](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | `Rewrite`中间件根据提供的规则重写`URL`路径。它对于向后兼容或创建更简洁,更具描述性的链接很有帮助。 | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID中间件为请求生成唯一的ID。 | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | `session`中间件通过了 @savsgio MIT 许可,建立在`fasthttp/session`之上。特别感谢 @thomasvvugt 帮助完成此中间件。 | - |
|
||||
| [template](https://github.com/gofiber/template) | 该软件包包含8个模板引擎,需要配合Fiber`v1.10.x`以及Go`1.13`或更高版本使用。 | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | `Fiber`基于`Fasthttp WebSocket`的中间件,支持`Locals`功能! | - |
|
||||
|
||||
## 🌱 第三方中间件
|
||||
|
||||
这是由`Fiber`社区创建的中间件列表,如果您想看到自己的中间件,请创建`PR`。
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 媒体
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 贡献
|
||||
|
||||
如果您要说声**谢谢**或支持`Fiber`的积极发展:
|
||||
|
||||
1. 为`Fiber`[GitHub Star](https://github.com/gofiber/fiber/stargazers)点个⭐星星。
|
||||
2. 在[Twitter](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber)上发布有关项目的[推文](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber)。
|
||||
3. 在[Medium](https://medium.com/),[Dev.to](https://dev.to/)或个人博客上写评论或教程。
|
||||
4. 帮助我们通过[Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)翻译我们的API文档
|
||||
5. 通过捐赠[一杯咖啡](https://buymeacoff.ee/fenny)来支持本项目。
|
||||
|
||||
## ☕ 支持者
|
||||
|
||||
`Fibre`是一个开源项目,依靠捐赠来支付账单,例如我们的域名,`gitbook`,`netlify`和无服务器托管。如果要支持`Fiber`,可以 ☕ [**在这里买一杯咖啡**](https://buymeacoff.ee/fenny)
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 Code Contributors
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ License
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,591 +0,0 @@
|
|||
<p align="center">
|
||||
<a href="https://gofiber.io">
|
||||
<img alt="Fiber" height="125" src="https://raw.githubusercontent.com/gofiber/docs/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<!-- base64 flags are available at https://www.phoca.cz/cssflags/ -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/EN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjAgMzAiIGhlaWdodD0iNjAwIj4NCjxkZWZzPg0KPGNsaXBQYXRoIGlkPSJ0Ij4NCjxwYXRoIGQ9Im0zMCwxNWgzMHYxNXp2MTVoLTMwemgtMzB2LTE1enYtMTVoMzB6Ii8+DQo8L2NsaXBQYXRoPg0KPC9kZWZzPg0KPHBhdGggZmlsbD0iIzAwMjQ3ZCIgZD0ibTAsMHYzMGg2MHYtMzB6Ii8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iNiIgZD0ibTAsMGw2MCwzMG0wLTMwbC02MCwzMCIvPg0KPHBhdGggc3Ryb2tlPSIjY2YxNDJiIiBzdHJva2Utd2lkdGg9IjQiIGQ9Im0wLDBsNjAsMzBtMC0zMGwtNjAsMzAiIGNsaXAtcGF0aD0idXJsKCN0KSIvPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjxwYXRoIHN0cm9rZT0iI2NmMTQyYiIgc3Ryb2tlLXdpZHRoPSI2IiBkPSJtMzAsMHYzMG0tMzAtMTVoNjAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/RU-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NTAgMzAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoNDUwdjEwMGgtNDUweiIvPg0KPHBhdGggZmlsbD0iIzAwZiIgZD0ibTAsMTAwaDQ1MHYxMDBoLTQ1MHoiLz4NCjxwYXRoIGZpbGw9IiNmMDAiIGQ9Im0wLDIwMGg0NTB2MTAwaC00NTB6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ES-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3NTAgNTAwIj4NCjxwYXRoIGZpbGw9IiNjNjBiMWUiIGQ9Im0wLDBoNzUwdjUwMGgtNzUweiIvPg0KPHBhdGggZmlsbD0iI2ZmYzQwMCIgZD0ibTAsMTI1aDc1MHYyNTBoLTc1MHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/JA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNmZmYiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPGNpcmNsZSBmaWxsPSIjYmUwMDI2IiBjeD0iNDUwIiBjeT0iMzAwIiByPSIxODAiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/PT-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHJlY3QgeT0iODUuMzM3IiBzdHlsZT0iZmlsbDojRDgwMDI3OyIgd2lkdGg9IjUxMiIgaGVpZ2h0PSIzNDEuMzI2Ii8+Cjxwb2x5Z29uIHN0eWxlPSJmaWxsOiM2REE1NDQ7IiBwb2ludHM9IjE5Ni42NDEsODUuMzM3IDE5Ni42NDEsMjYxLjU2NSAxOTYuNjQxLDQyNi42NjMgMCw0MjYuNjYzIDAsODUuMzM3ICIvPgo8Y2lyY2xlIHN0eWxlPSJmaWxsOiNGRkRBNDQ7IiBjeD0iMTk2LjY0MSIgY3k9IjI1NiIgcj0iNjQiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0Q4MDAyNzsiIGQ9Ik0xNjAuNjM4LDIyNHY0MC4wMDFjMCwxOS44ODIsMTYuMTE4LDM2LDM2LDM2czM2LTE2LjExOCwzNi0zNlYyMjRIMTYwLjYzOHoiLz4KPHBhdGggc3R5bGU9ImZpbGw6I0YwRjBGMDsiIGQ9Ik0xOTYuNjM4LDI3NmMtNi42MTcsMC0xMi01LjM4My0xMi0xMnYtMTZoMjQuMDAxdjE2QzIwOC42MzgsMjcwLjYxNiwyMDMuMjU0LDI3NiwxOTYuNjM4LDI3NnoiLz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+Cg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/CN-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjAwIDgwMCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPHBhdGggZmlsbD0iI2RlMjkxMCIgZD0ibTAsMGgxMjAwdjgwMGgtMTIwMHoiLz4NCjxwYXRoIGZpbGw9IiNmZmRlMDAiIGQ9Im0tMTYuNTc5Niw5OS42MDA3bDIuMzY4Ni04LjEwMzItNi45NTMtNC43ODgzIDguNDM4Ni0uMjUxNCAyLjQwNTMtOC4wOTI0IDIuODQ2Nyw3Ljk0NzkgOC40Mzk2LS4yMTMxLTYuNjc5Miw1LjE2MzQgMi44MTA2LDcuOTYwNy02Ljk3NDctNC43NTY3LTYuNzAyNSw1LjEzMzF6IiB0cmFuc2Zvcm09Im1hdHJpeCg5LjkzMzUyIC4yNzc0NyAtLjI3NzQ3IDkuOTMzNTIgMzI0LjI5MjUgLTY5NS4yNDE1KSIvPg0KPHBhdGggZmlsbD0iI2ZmZGUwMCIgaWQ9InN0YXIiIGQ9Im0zNjUuODU1MiwzMzIuNjg5NWwyOC4zMDY4LDExLjM3NTcgMTkuNjcyMi0yMy4zMTcxLTIuMDcxNiwzMC40MzY3IDI4LjI1NDksMTEuNTA0LTI5LjU4NzIsNy40MzUyLTIuMjA5NywzMC40MjY5LTE2LjIxNDItMjUuODQxNS0yOS42MjA2LDcuMzAwOSAxOS41NjYyLTIzLjQwNjEtMTYuMDk2OC0yNS45MTQ4eiIvPg0KPGcgZmlsbD0iI2ZmZGUwMCI+DQo8cGF0aCBkPSJtNTE5LjA3NzksMTc5LjMxMjlsLTMwLjA1MzQtNS4yNDE4LTE0LjM5NDUsMjYuODk3Ni00LjMwMTctMzAuMjAyMy0zMC4wMjkzLTUuMzc4MSAyNy4zOTQ4LTEzLjQyNDItNC4xNjQ3LTMwLjIyMTUgMjEuMjMyNiwyMS45MDU3IDI3LjQ1NTQtMTMuMjk5OC0xNC4yNzIzLDI2Ljk2MjcgMjEuMTMzMSwyMi4wMDE3eiIvPg0KPHBhdGggZD0ibTQ1NS4yNTkyLDMxNS45Nzk1bDkuMzczNC0yOS4wMzE0LTI0LjYzMjUtMTcuOTk3OCAzMC41MDctLjA1NjYgOS41MDUtMjguOTg4NiA5LjQ4MSwyOC45OTY0IDMwLjUwNywuMDgxOC0yNC42NDc0LDE3Ljk3NzQgOS4zNDkzLDI5LjAzOTItMjQuNzE0LTE3Ljg4NTgtMjQuNzI4OCwxNy44NjUzeiIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjc3RhciIgdHJhbnNmb3JtPSJtYXRyaXgoLjk5ODYzIC4wNTIzNCAtLjA1MjM0IC45OTg2MyAxOS40MDAwNSAtMzAwLjUzNjgxKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-TW.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TW-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmc+DQo8c3ZnIHdpZHRoPSI5MDAiIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItNjAgLTQwIDI0MCAxNjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KICAgPHJlY3QgeD0iLTYwIiB5PSItNDAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9IiNmZTAwMDAiLz4NCiAgIDxyZWN0IHg9Ii02MCIgeT0iLTQwIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSIgZmlsbD0iIzAwMDA5NSIvPg0KICAgPHBhdGggaWQ9ImZvdXJfcmF5cyIgZD0iTSA4LDAgTCAwLDMwIEwgLTgsMCBMIDAsLTMwIE0gMCw4IEwgMzAsMCBMIDAsLTggTCAtMzAsMCIgZmlsbD0iI2ZmZiIvPg0KICAgPHVzZSB4bGluazpocmVmPSIjZm91cl9yYXlzIiB0cmFuc2Zvcm09InJvdGF0ZSgzMCkiLz4NCiAgIDx1c2UgeGxpbms6aHJlZj0iI2ZvdXJfcmF5cyIgdHJhbnNmb3JtPSJyb3RhdGUoNjApIi8+DQogICA8Y2lyY2xlIHI9IjE3IiBmaWxsPSIjMDAwMDk1Ii8+DQogICA8Y2lyY2xlIHI9IjE1IiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4=">
|
||||
</a> -->
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/DE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDUgMyI+DQo8cGF0aCBkPSJtMCwwaDV2M2gtNXoiLz4NCjxwYXRoIGZpbGw9IiNkMDAiIGQ9Im0wLDFoNXYyaC01eiIvPg0KPHBhdGggZmlsbD0iI2ZmY2UwMCIgZD0ibTAsMmg1djFoLTV6Ii8+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_nl.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/NL-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSIwIDAgOSA2Ij4NCjxwYXRoIGZpbGw9IiMyMTQ2OGIiIGQ9Im0wLDBoOXY2aC05eiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg5djRoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjYWUxYzI4IiBkPSJtMCwwaDl2MmgtOXoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/KO-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNjAwIiB2aWV3Qm94PSItMzYgLTI0IDcyIDQ4IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtLTM2LTI0aDcydjQ4aC03MnoiLz4NCjxnIHRyYW5zZm9ybT0ibWF0cml4KC41NTQ3IC0uODMyMDUgLjgzMjA1IC41NTQ3IDAgMCkiPg0KPGcgaWQ9ImIyIj4NCjxwYXRoIHN0cm9rZT0iIzAwMCIgaWQ9ImIiIHN0cm9rZS13aWR0aD0iMiIgZD0iTS02LTI1SDZNLTYtMjJINk0tNi0xOUg2Ii8+DQo8dXNlIHk9IjQ0IiB4bGluazpocmVmPSIjYiIvPg0KPC9nPg0KPHBhdGggc3Ryb2tlPSIjZmZmIiBkPSJtMCwxN3YxMCIvPg0KPGNpcmNsZSBmaWxsPSIjYzYwYzMwIiByPSIxMiIvPg0KPHBhdGggZmlsbD0iIzAwMzQ3OCIgZD0iTTAtMTJBNiw2IDAgMCAwIDAsMEE2LDYgMCAwIDEgMCwxMkExMiwxMiAwIDAsMSAwLTEyWiIvPg0KPC9nPg0KPGcgdHJhbnNmb3JtPSJtYXRyaXgoLS41NTQ3IC0uODMyMDUgLjgzMjA1IC0uNTU0NyAwIDApIj4NCjx1c2UgeGxpbms6aHJlZj0iI2IyIi8+DQo8cGF0aCBzdHJva2U9IiNmZmYiIGQ9Im0wLTIzLjV2M20wLDM3LjV2My41bTAsM3YzIi8+DQo8L2c+DQo8L3N2Zz4NCg==">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/FR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA5MDAgNjAwIj4NCjxwYXRoIGZpbGw9IiNlZDI5MzkiIGQ9Im0wLDBoOTAwdjYwMGgtOTAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMGg2MDB2NjAwaC02MDB6Ii8+DQo8cGF0aCBmaWxsPSIjMDAyMzk1IiBkPSJtMCwwaDMwMHY2MDBoLTMwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/TR-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDM2MCAyNDAiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNlMzBhMTciIGQ9Im0wLDBoMzYwdjI0MGgtMzYweiIvPg0KPGNpcmNsZSBmaWxsPSIjZmZmIiBjeD0iMTIwIiBjeT0iMTIwIiByPSI2MCIvPg0KPGNpcmNsZSBmaWxsPSIjZTMwYTE3IiBjeD0iMTM1IiBjeT0iMTIwIiByPSI0OCIvPg0KPGcgZmlsbD0iI2ZmZiIgdHJhbnNmb3JtPSJtYXRyaXgoMCAtMzAgMzAgMCAyMDAuNyAxMjApIj4NCjxnIGlkPSJnMiI+DQo8cGF0aCBpZD0iZzEiIGQ9Im0wLDAgMCwxIC41LDB6IiB0cmFuc2Zvcm09Im1hdHJpeCguOTUxMDYgLjMwOTAyIC0uMzA5MDIgLjk1MTA2IDAgLTEpIi8+DQo8dXNlIHhsaW5rOmhyZWY9IiNnMSIgdHJhbnNmb3JtPSJzY2FsZSgtMSAxKSIvPg0KPC9nPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDcyKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0ibWF0cml4KC4zMDkwMiAtLjk1MTA2IC45NTEwNiAuMzA5MDIgMCAwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjZzIiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4NCjx1c2UgeGxpbms6aHJlZj0iI2cyIiB0cmFuc2Zvcm09Im1hdHJpeCgtLjgwOTAyIC0uNTg3NzkgLjU4Nzc5IC0uODA5MDIgMCAwKSIvPg0KPC9nPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/ID-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNDAwIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoNjAwdjIwMGgtNjAweiIvPg0KPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTAsMjAwaDYwMHYyMDBoLTYwMHoiLz4NCjwvc3ZnPg0K">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_he.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/HE-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgwIiB2aWV3Qm94PSIwIDAgMjIwIDE2MCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPg0KPGRlZnM+DQo8cGF0aCBzdHJva2U9IiMwMDM4YjgiIGZpbGwtb3BhY2l0eT0iMCIgaWQ9InRyaWFuZ2xlIiBzdHJva2Utd2lkdGg9IjUuNSIgZD0ibTAtMjkuMTQxLTI1LjIzNjksNDMuNzExNSA1MC40NzM4LTB6Ii8+DQo8L2RlZnM+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMCwwaDIyMHYxNjBoLTIyMHoiLz4NCjxnIGZpbGw9IiMwMDM4YjgiPg0KPHBhdGggZD0ibTAsMTVoMjIwdjI1aC0yMjB6Ii8+DQo8cGF0aCBkPSJtMCwxMjBoMjIwdjI1aC0yMjB6Ii8+DQo8L2c+DQo8dXNlIHhsaW5rOmhyZWY9IiN0cmlhbmdsZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTEwIDgwKSIvPg0KPHVzZSB4bGluazpocmVmPSIjdHJpYW5nbGUiIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgLTAgLTEgMTEwIDgwKSIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ar_SA.md">
|
||||
<img height="20px" src="https://img.shields.io/badge/SA-flag.svg?color=555555&style=flat&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjYwMCIgdmlld0JveD0iMCAwIDEyIDYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4NCjxwYXRoIGZpbGw9IiNjZTExMjYiIGQ9Im0wLDBoM3Y2aC0zeiIvPg0KPHBhdGggZmlsbD0iIzAwOWEwMCIgZD0ibTMsMGg5djJoLTl6Ii8+DQo8cGF0aCBmaWxsPSIjZmZmIiBkPSJtMywyaDl2MmgtOXoiLz4NCjxwYXRoIGQ9Im0zLDRoOXYyaC05eiIvPg0KPC9zdmc+DQo=">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%94%8E%20gocover-97.8%25-75C46B.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3AGosec">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Security?label=%F0%9F%94%91%20gosec&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
|
||||
<img src="https://img.shields.io/github/workflow/status/gofiber/fiber/Test?label=%F0%9F%A7%AA%20tests&style=flat&color=75C46B">
|
||||
</a>
|
||||
<a href="https://docs.gofiber.io">
|
||||
<img src="https://img.shields.io/badge/%F0%9F%92%A1%20fiber-docs-00ACD7.svg?style=flat">
|
||||
</a>
|
||||
<a href="https://gofiber.io/discord">
|
||||
<img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<b>Fiber</b>是移植NodeJS的<a href="https://github.com/expressjs/express">Express</a><b>框架</b>改以<a href="https://golang.org/doc/">Go</a>語言編寫。<b>本套件基於</b><a href="https://github.com/valyala/fasthttp">Fasthttp</a>,Fasthttp有<b>不分配記憶體空間</b>和<b>Request Pool</b>的特性,在網路效能方面有著顯著的效能。
|
||||
</p>
|
||||
|
||||
## ⚡️ 快速入門
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 效能
|
||||
|
||||
本測試使用[TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext)和[Go Web框架效能測試](https://github.com/smallnest/go-web-framework-benchmark)。如果要看全部的執行結果,請到[Wiki](https://docs.gofiber.io/benchmarks) 。
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark-pipeline.png" width="49%">
|
||||
<img src="https://raw.githubusercontent.com/gofiber/docs/master/.gitbook/assets/benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## ⚙️ 安裝
|
||||
|
||||
第一步, [下載](https://golang.org/dl/)並安裝Go。 請使用`1.11`以上版本。
|
||||
|
||||
下指令[`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them)下載套件:
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber
|
||||
```
|
||||
|
||||
## 🎯 功能
|
||||
|
||||
- 強大的[路由](https://docs.gofiber.io/routing)
|
||||
- [靜態檔案](https://docs.gofiber.io/application#static)服務
|
||||
- [超快速](https://docs.gofiber.io/benchmarks)
|
||||
- [佔用很少記憶體](https://docs.gofiber.io/benchmarks)
|
||||
- 支援Express的[API](https://docs.gofiber.io/context)
|
||||
- 支援中介器和[下一步](https://docs.gofiber.io/context#next)
|
||||
- [立即上手](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497)
|
||||
- [樣板引擎](https://github.com/gofiber/template)
|
||||
- 支援[WebSocket](https://docs.gofiber.io/middleware#websocket)
|
||||
- 支援[限速](https://docs.gofiber.io/middleware#limiter)
|
||||
- 被翻譯成[15]國語言(https://docs.gofiber.io/)
|
||||
- 豐富的[文件](https://docs.gofiber.io/)
|
||||
|
||||
## 💡 理念
|
||||
|
||||
不少[Node.js](https://nodejs.org/en/about/)的工程師跳到[Go](https://golang.org/doc/)必須學習一些知識,因此做了一個跟Express一樣的Fiber省這些麻煩。設計還是照原本的**極簡主義**還有遵循**UNIX慣例**,因此新手們可以**無痛**迅速進入Go的世界。
|
||||
|
||||
Fiber **受到** 網路上最流行的Web框架ExpressJS**啟發**,結合Express的**易用性**和Go的**高效能**。若你之前用過Node.js寫Web應用(*使用ExpressJS/Koa或類似工具*),那你已經**上手**了。
|
||||
|
||||
有什麼問題請發[issues](https://github.com/gofiber/fiber/issues)或加入Discord [channel](https://gofiber.io/discord)討論,我們想要創造**快速**、**彈性**、**友善**的社群給**任何人**使用!就像Express那樣。
|
||||
|
||||
## 👀 範例
|
||||
|
||||
以下是一些常見範例。
|
||||
|
||||
> 更多程式碼在[範例專案](https://github.com/gofiber/recipes)中或直接看[API文件](https://docs.gofiber.io)。
|
||||
|
||||
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
|
||||
c.Send(msg) // => Hello john 👋!
|
||||
})
|
||||
|
||||
// GET /john/75
|
||||
app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
|
||||
c.Send(msg) // => 👴 john is 75 years old
|
||||
})
|
||||
|
||||
// GET /dictionary.txt
|
||||
app.Get("/:file.:ext", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
|
||||
c.Send(msg) // => 📃 dictionary.txt
|
||||
})
|
||||
|
||||
// GET /flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
|
||||
c.Send(msg) // => 💸 From: LAX, To: SFO
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/*", func(c *fiber.Ctx) {
|
||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||
c.Send(msg) // => ✋ /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/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://docs.gofiber.io/context#next)
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("🥇 First handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥈 Second handler")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("🥉 Last handler")
|
||||
c.Send("Hello, World 👋!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 顯示更多範例</summary>
|
||||
|
||||
### 界面引擎
|
||||
|
||||
📖 [設定](https://docs.gofiber.io/application#settings)
|
||||
📖 [引擎](https://github.com/gofiber/template)
|
||||
📖 [渲染](https://docs.gofiber.io/context#render)
|
||||
|
||||
當不指定樣板引擎時Fiber預設用[html/template](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)之類…請參考符合多樣板引擎的[樣板](https://github.com/gofiber/template)套件。
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/template/pug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 你可以在初始化前套用樣板引擎
|
||||
app := fiber.New(&fiber.Settings{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// 或在初始化後任意時間套用:
|
||||
app.Settings.Views = pug.New("./views", ".pug"),
|
||||
|
||||
// 現在,你可以像這樣呼叫樣板 `./views/home.pug`:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "首頁",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/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
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 中介器logger
|
||||
|
||||
📖 [Logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// 預設
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// 客制格式
|
||||
app.Use(middleware.Logger("${method} - ${path}"))
|
||||
|
||||
// 客制設定
|
||||
app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Path() != "/private"
|
||||
},
|
||||
Format: "${method} - ${path}",
|
||||
Output: io.Writer,
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
|
||||
### 跨網域資源共享 (CORS)
|
||||
|
||||
📖 [CORS](https://docs.gofiber.io/middleware#cors)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// 預設的CORS
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
在`Origin` header中放網域來檢查CORS:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### 客制404回應
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/application#http-methods)
|
||||
|
||||
```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!")
|
||||
})
|
||||
|
||||
// 用最後一個中介器攔截剩餘的case
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### JSON 回應
|
||||
|
||||
📖 [JSON](https://docs.gofiber.io/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)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket 升級
|
||||
|
||||
📖 [Websocket](https://docs.gofiber.io/middleware#websocket)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover 中介器
|
||||
|
||||
📖 [Recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md)
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("normally this would crash your app")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🧬 Fiber中介器
|
||||
|
||||
官方[團隊](https://github.com/orgs/gofiber/people)維護的中介器。
|
||||
|
||||
| 中介器 | 敘述 | 是否內建 |
|
||||
| :--- | :--- | :--- |
|
||||
| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! | - |
|
||||
| [basicauth](https://github.com/gofiber/basicauth) | Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials. | - |
|
||||
| [compress](https://github.com/gofiber/fiber/blob/master/middleware/compress.md) | Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli` by default. | `middleware.Compress()` |
|
||||
| [cors](https://github.com/gofiber/cors) | Enable cross-origin resource sharing \(CORS\) with various options. | - |
|
||||
| [csrf](https://github.com/gofiber/csrf) | Protect from CSRF exploits. | - |
|
||||
| [filesystem](https://github.com/gofiber/fiber/blob/master/middleware/filesystem.md) | FileSystem middleware for Fiber, special thanks and credits to Alireza Salary | - |
|
||||
| [favicon](https://github.com/gofiber/fiber/blob/master/middleware/favicon.md) | Ignore favicon from logs or serve from memory if a file path is provided. | `middleware.Favicon()` |
|
||||
| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. | - |
|
||||
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. | - |
|
||||
| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. | - |
|
||||
| [limiter](https://github.com/gofiber/limiter) | Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset. | - |
|
||||
| [logger](https://github.com/gofiber/fiber/blob/master/middleware/logger.md) | HTTP request/response logger. | `middleware.Logger()` |
|
||||
| [pprof](https://github.com/gofiber/pprof) | Special thanks to Matthew Lee \(@mthli\) | - |
|
||||
| [recover](https://github.com/gofiber/fiber/blob/master/middleware/recover.md) | Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized[ ErrorHandler](error-handling.md). | `middleware.Recover()` |
|
||||
| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. | - |
|
||||
| [requestid](https://github.com/gofiber/fiber/blob/master/middleware/request_id.md) | Request ID middleware generates a unique id for a request. | `middleware.RequestID()` |
|
||||
| [session](https://github.com/gofiber/session) | This session middleware is build on top of fasthttp/session by @savsgio MIT. Special thanks to @thomasvvugt for helping with this middleware. | - |
|
||||
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. | - |
|
||||
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! | - |
|
||||
|
||||
## 🌱 第三方中介器
|
||||
|
||||
由社群建立的中介器列表,要新增請發PR!
|
||||
|
||||
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
|
||||
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
|
||||
- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
|
||||
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
|
||||
- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
|
||||
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
|
||||
- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
|
||||
- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
|
||||
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
|
||||
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
|
||||
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
|
||||
## 💬 新聞
|
||||
|
||||
<p float="left" align="middle">
|
||||
<a href="https://www.youtube.com/watch?v=Iq2qT0fRhAA"><img src="https://img.youtube.com/vi/Iq2qT0fRhAA/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
<a href="https://www.youtube.com/watch?v=kvwsPeWDLM8"><img src="https://img.youtube.com/vi/kvwsPeWDLM8/mqdefault.jpg" width="49%" style="border-radius:4px"></a>
|
||||
</p>
|
||||
|
||||
- [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) — _03 Feb 2020_
|
||||
- [Fiber released v1.7! 🎉 What's new and is it 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) — _21 Feb 2020_
|
||||
- [🚀 Fiber v1.8. What's new, updated and re-thinked?](https://dev.to/koddr/fiber-v1-8-what-s-new-updated-and-re-thinked-339h) — _03 Mar 2020_
|
||||
- [Is switching from Express to Fiber worth it? 🤔](https://dev.to/koddr/are-sure-what-your-lovely-web-framework-running-so-fast-2jl1) — _01 Apr 2020_
|
||||
- [Creating Fast APIs In Go Using Fiber](https://dev.to/jozsefsallai/creating-fast-apis-in-go-using-fiber-59m9) — _07 Apr 2020_
|
||||
- [Building a Basic REST API in Go using Fiber](https://tutorialedge.net/golang/basic-rest-api-go-fiber/) - _23 Apr 2020_
|
||||
- [📺 Building a REST API using GORM and Fiber](https://youtu.be/Iq2qT0fRhAA) - _25 Apr 2020_
|
||||
- [🌎 Create a travel list app with Go, Fiber, Angular, MongoDB and Google Cloud Secret Manager](https://blog.yongweilun.me/create-a-travel-list-app-with-go-fiber-angular-mongodb-and-google-cloud-secret-manager-ck9fgxy0p061pcss1xt1ubu8t) - _25 Apr 2020_
|
||||
- [Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?](https://dev.to/koddr/fiber-v1-9-5-how-to-improve-performance-by-817-and-stay-fast-flexible-and-friendly-2dp6) - _12 May 2020_
|
||||
- [The road to web-based authentication with Fiber ⚡](https://vugt.me/the-road-to-web-based-authentication-with-fiber/) - _20 May 2020_
|
||||
- [Building an Express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/) - _10 June 2020_
|
||||
- [基于golang fiber和angular开发web](https://zhuanlan.zhihu.com/p/148925642) - _19 June 2020_
|
||||
- [基于延迟计算令牌桶的gofiber频率限制中间件实现](https://zhuanlan.zhihu.com/p/149308936) - _20 June 2020_
|
||||
- [Construir una API en Golang con Fiber 🇪🇸](https://enbonnet.me/article/53/construir-api-golang-con-fiber) - _28 June 2020_
|
||||
- [📺Why Go Fiber Is THE New Framework To Learn](https://www.youtube.com/watch?v=kvwsPeWDLM8) - _29 June 2020_
|
||||
- [解析Gofiber路由管理](https://zhuanlan.zhihu.com/p/152494502) - _08 July 2020_
|
||||
- [📺 Introduction to Fiber - An Express-inspired web framework](https://youtu.be/MfFi4Gt-tos) - _25 July 2020_
|
||||
|
||||
## 👍 貢獻
|
||||
|
||||
如果您要說聲**謝謝**或支援`Fiber`的積極發展:
|
||||
|
||||
1. 點擊[GitHub Star](https://github.com/gofiber/fiber/stargazers)關注本專案。
|
||||
2. 在[Twitter](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber)轉[推](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber)。
|
||||
3. 在[Medium](https://medium.com/)、[Dev.to](https://dev.to/)、部落格上發表意見或教學。
|
||||
4. 在[Crowdin](https://crowdin.com/project/gofiber) [](https://crowdin.com/project/gofiber)幫我們翻譯API文件
|
||||
5. 贊助我們[一杯咖啡](https://buymeacoff.ee/fenny)。
|
||||
|
||||
## ☕ 支持者
|
||||
|
||||
Fiber是一個以贊助維生的開源專案,像是: 網域、gitbook、netlify、serverless伺服器。如果你想贊助也可以☕ [**買杯咖啡**](https://buymeacoff.ee/fenny)
|
||||
|
||||
| | User | Donation |
|
||||
| :---------------------------------------------------------- | :----------------------------------------------- | :-------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@ankush](https://github.com/ankush) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|  | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
|
||||
|  | [@marvinjwendt](https://github.com/thomasvvugt) | ☕ x 1 |
|
||||
|  | [@toishy](https://github.com/toishy) | ☕ x 1 |
|
||||
|
||||
## 💻 貢獻者
|
||||
|
||||
<img src="https://opencollective.com/fiber/contributors.svg?width=890&button=false" alt="Code Contributors" style="max-width:100%;">
|
||||
|
||||
## ⭐️ Stargazers
|
||||
|
||||
<img src="https://starchart.cc/gofiber/fiber.svg" alt="Stargazers over time" style="max-width: 100%">
|
||||
|
||||
## ⚠️ 授權
|
||||
|
||||
Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).
|
||||
|
||||
**Third-party library licenses**
|
||||
- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
|
||||
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
- [fasttemplate](https://github.com/valyala/fasttemplate/blob/master/LICENSE)
|
||||
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
|
|
@ -1,76 +0,0 @@
|
|||
# Security Policy
|
||||
|
||||
1. [Supported Versions](#versions)
|
||||
2. [Reporting security problems to Fiber](#reporting)
|
||||
3. [Security Point of Contact](#contact)
|
||||
4. [Incident Response Process](#process)
|
||||
|
||||
<a name="versions"></a>
|
||||
## Supported Versions
|
||||
|
||||
The table below shows the supported versions for Fiber which include security updates.
|
||||
|
||||
| Version | Supported |
|
||||
| --------- | ------------------ |
|
||||
| >= 1.12.6 | :white_check_mark: |
|
||||
| < 1.12.6 | :x: |
|
||||
|
||||
<a name="reporting"></a>
|
||||
## Reporting security problems to Fiber
|
||||
|
||||
**DO NOT CREATE AN ISSUE** to report a security problem. Instead, please
|
||||
send us an e-mail at `team@gofiber.io` or join our discord server via
|
||||
[this invite link](https://discord.gg/bSnH7db) and send a private message
|
||||
to Fenny or any of the maintainers.
|
||||
|
||||
<a name="contact"></a>
|
||||
## Security Point of Contact
|
||||
|
||||
The security point of contact is [Fenny](https://github.com/Fenny). Fenny responds
|
||||
to security incident reports as fast as possible, within one business day at the
|
||||
latest.
|
||||
|
||||
In case Fenny does not respond within a reasonable time, the secondary point
|
||||
of contact are any of the [@maintainers](https://github.com/orgs/gofiber/teams/maintainers).
|
||||
The maintainers are the only other persons with administrative access to Fiber's source code.
|
||||
|
||||
<a name="process"></a>
|
||||
## Incident Response Process
|
||||
|
||||
In case an incident is discovered or reported, we will follow the following
|
||||
process to contain, respond and remediate:
|
||||
|
||||
### 1. Containment
|
||||
|
||||
The first step is to find out the root cause, nature and scope of the incident.
|
||||
|
||||
- Is still ongoing? If yes, first priority is to stop it.
|
||||
- Is the incident outside of our influence? If yes, first priority is to contain it.
|
||||
- Find out knows about the incident and who is affected.
|
||||
- Find out what data was potentially exposed.
|
||||
|
||||
### 2. Response
|
||||
|
||||
After the initial assessment and containment to our best abilities, we will
|
||||
document all actions taken in a response plan.
|
||||
|
||||
We will create a comment in the official `#announcements` channel to inform users about
|
||||
the incident and what actions we took to contain it.
|
||||
|
||||
### 3. Remediation
|
||||
|
||||
Once the incident is confirmed to be resolved, we will summarize the lessons
|
||||
learned from the incident and create a list of actions we will take to prevent
|
||||
it from happening again.
|
||||
|
||||
### Secure accounts with access
|
||||
|
||||
The [Fiber Organization](https://github.com/gofiber) requires 2FA authorization
|
||||
for all of it's members.
|
||||
|
||||
### Critical Updates And Security Notices
|
||||
|
||||
We learn about critical software updates and security threats from these sources
|
||||
|
||||
1. GitHub Security Alerts
|
||||
2. GitHub: https://status.github.com/ & [@githubstatus](https://twitter.com/githubstatus)
|
|
@ -1 +0,0 @@
|
|||
<h1>{{.Title}}</h1>
|
|
@ -1,28 +0,0 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD4IQusAs8PJdnG
|
||||
3mURt/AXtgC+ceqLOatJ49JJE1VPTkMAy+oE1f1XvkMrYsHqmDf6GWVzgVXryL4U
|
||||
wq2/nJSm56ddhN55nI8oSN3dtywUB8/ShelEN73nlN77PeD9tl6NksPwWaKrqxq0
|
||||
FlabRPZSQCfmgZbhDV8Sa8mfCkFU0G0lit6kLGceCKMvmW+9Bz7ebsYmVdmVMxmf
|
||||
IJStFD44lWFTdUc65WISKEdW2ELcUefb0zOLw+0PCbXFGJH5x5ktksW8+BBk2Hkg
|
||||
GeQRL/qPCccthbScO0VgNj3zJ3ZZL0ObSDAbvNDG85joeNjDNq5DT/BAZ0bOSbEF
|
||||
sh+f9BAzAgMBAAECggEBAJWv2cq7Jw6MVwSRxYca38xuD6TUNBopgBvjREixURW2
|
||||
sNUaLuMb9Omp7fuOaE2N5rcJ+xnjPGIxh/oeN5MQctz9gwn3zf6vY+15h97pUb4D
|
||||
uGvYPRDaT8YVGS+X9NMZ4ZCmqW2lpWzKnCFoGHcy8yZLbcaxBsRdvKzwOYGoPiFb
|
||||
K2QuhXZ/1UPmqK9i2DFKtj40X6vBszTNboFxOVpXrPu0FJwLVSDf2hSZ4fMM0DH3
|
||||
YqwKcYf5te+hxGKgrqRA3tn0NCWii0in6QIwXMC+kMw1ebg/tZKqyDLMNptAK8J+
|
||||
DVw9m5X1seUHS5ehU/g2jrQrtK5WYn7MrFK4lBzlRwECgYEA/d1TeANYECDWRRDk
|
||||
B0aaRZs87Rwl/J9PsvbsKvtU/bX+OfSOUjOa9iQBqn0LmU8GqusEET/QVUfocVwV
|
||||
Bggf/5qDLxz100Rj0ags/yE/kNr0Bb31kkkKHFMnCT06YasR7qKllwrAlPJvQv9x
|
||||
IzBKq+T/Dx08Wep9bCRSFhzRCnsCgYEA+jdeZXTDr/Vz+D2B3nAw1frqYFfGnEVY
|
||||
wqmoK3VXMDkGuxsloO2rN+SyiUo3JNiQNPDub/t7175GH5pmKtZOlftePANsUjBj
|
||||
wZ1D0rI5Bxu/71ibIUYIRVmXsTEQkh/ozoh3jXCZ9+bLgYiYx7789IUZZSokFQ3D
|
||||
FICUT9KJ36kCgYAGoq9Y1rWJjmIrYfqj2guUQC+CfxbbGIrrwZqAsRsSmpwvhZ3m
|
||||
tiSZxG0quKQB+NfSxdvQW5ulbwC7Xc3K35F+i9pb8+TVBdeaFkw+yu6vaZmxQLrX
|
||||
fQM/pEjD7A7HmMIaO7QaU5SfEAsqdCTP56Y8AftMuNXn/8IRfo2KuGwaWwKBgFpU
|
||||
ILzJoVdlad9E/Rw7LjYhZfkv1uBVXIyxyKcfrkEXZSmozDXDdxsvcZCEfVHM6Ipk
|
||||
K/+7LuMcqp4AFEAEq8wTOdq6daFaHLkpt/FZK6M4TlruhtpFOPkoNc3e45eM83OT
|
||||
6mziKINJC1CQ6m65sQHpBtjxlKMRG8rL/D6wx9s5AoGBAMRlqNPMwglT3hvDmsAt
|
||||
9Lf9pdmhERUlHhD8bj8mDaBj2Aqv7f6VRJaYZqP403pKKQexuqcn80mtjkSAPFkN
|
||||
Cj7BVt/RXm5uoxDTnfi26RF9F6yNDEJ7UU9+peBr99aazF/fTgW/1GcMkQnum8uV
|
||||
c257YgaWmjK9uB0Y2r2VxS0G
|
||||
-----END PRIVATE KEY-----
|
|
@ -1,17 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICujCCAaKgAwIBAgIJAMbXnKZ/cikUMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNV
|
||||
BAMTCnVidW50dS5uYW4wHhcNMTUwMjA0MDgwMTM5WhcNMjUwMjAxMDgwMTM5WjAV
|
||||
MRMwEQYDVQQDEwp1YnVudHUubmFuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEA+CELrALPDyXZxt5lEbfwF7YAvnHqizmrSePSSRNVT05DAMvqBNX9V75D
|
||||
K2LB6pg3+hllc4FV68i+FMKtv5yUpuenXYTeeZyPKEjd3bcsFAfP0oXpRDe955Te
|
||||
+z3g/bZejZLD8Fmiq6satBZWm0T2UkAn5oGW4Q1fEmvJnwpBVNBtJYrepCxnHgij
|
||||
L5lvvQc+3m7GJlXZlTMZnyCUrRQ+OJVhU3VHOuViEihHVthC3FHn29Mzi8PtDwm1
|
||||
xRiR+ceZLZLFvPgQZNh5IBnkES/6jwnHLYW0nDtFYDY98yd2WS9Dm0gwG7zQxvOY
|
||||
6HjYwzauQ0/wQGdGzkmxBbIfn/QQMwIDAQABow0wCzAJBgNVHRMEAjAAMA0GCSqG
|
||||
SIb3DQEBCwUAA4IBAQBQjKm/4KN/iTgXbLTL3i7zaxYXFLXsnT1tF+ay4VA8aj98
|
||||
L3JwRTciZ3A5iy/W4VSCt3eASwOaPWHKqDBB5RTtL73LoAqsWmO3APOGQAbixcQ2
|
||||
45GXi05OKeyiYRi1Nvq7Unv9jUkRDHUYVPZVSAjCpsXzPhFkmZoTRxmx5l0ZF7Li
|
||||
K91lI5h+eFq0dwZwrmlPambyh1vQUi70VHv8DNToVU29kel7YLbxGbuqETfhrcy6
|
||||
X+Mha6RYITkAn5FqsZcKMsc9eYGEF4l3XV+oS7q6xfTxktYJMFTI18J0lQ2Lv/CI
|
||||
whdMnYGntDQBE/iFCrJEGNsKGc38796GBOb5j+zd
|
||||
-----END CERTIFICATE-----
|
|
@ -1 +0,0 @@
|
|||
<h1>{{.Title}</h1>
|
|
@ -1 +0,0 @@
|
|||
<h1>{{.Title}}</h1>
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +0,0 @@
|
|||
# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
|
||||
# Comment to be posted to on first time issues
|
||||
newIssueWelcomeComment: >
|
||||
Thanks for opening your first issue here! 🎉 Be sure to follow the issue template!
|
||||
If you need help or want to chat with us, join us on Discord https://gofiber.io/discord
|
||||
|
||||
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
|
||||
# Comment to be posted to on PRs from first time contributors in your repository
|
||||
newPRWelcomeComment: >
|
||||
Thanks for opening this pull request! 🎉 Please check out our contributing guidelines.
|
||||
If you need help or want to chat with us, join us on Discord https://gofiber.io/discord
|
||||
|
||||
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
|
||||
# Comment to be posted to on pull requests merged by a first time user
|
||||
firstPRMergeComment: >
|
||||
Congrats on merging your first pull request! 🎉 We here at Fiber are proud of you!
|
||||
If you need help or want to chat with us, join us on Discord https://gofiber.io/discord
|
|
@ -1,14 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Test file</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
Hello, World!
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
**Please provide enough information so that others can review your pull request:**
|
||||
|
||||
<!-- You can skip this if you're fixing a typo or adding an app to the Showcase. -->
|
||||
|
||||
**Explain the *details* for making this change. What existing problem does the pull request solve?**
|
||||
|
||||
<!-- Example: When "Adding a function to do X", explain why it is necessary to have a way to do X. -->
|
||||
|
||||
**Commit formatting**
|
||||
|
||||
Use emojis on commit messages so it provides an easy way of identifying the purpose or intention of a commit. Check out the emoji cheatsheet here: https://gitmoji.carloscuesta.me/
|
|
@ -1,26 +0,0 @@
|
|||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: wontfix
|
||||
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
👋 Hello. Is this still relevant? If so, what is blocking it? Is there
|
||||
anything you can do to help move it forward?
|
||||
|
||||
> This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
|
||||
|
||||
Thank you for your contributions.
|
||||
|
||||
# Comment to post when closing a stale Issue or Pull Request. Set to `false` to disable
|
||||
closeComment: >
|
||||
⚡️ This issue has been automatically closed because it has not had recent activity.
|
|
@ -1,28 +0,0 @@
|
|||
on: [push]
|
||||
name: Benchmark
|
||||
jobs:
|
||||
Compare:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.14.x
|
||||
- name: Fetch Repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Run Benchmark
|
||||
run: go test ./... -benchmem -run=^$ -bench . | tee output.txt
|
||||
- name: Get Previous Benchmark Results
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ./cache
|
||||
key: ${{ runner.os }}-benchmark
|
||||
- name: Save Benchmark Results
|
||||
uses: rhysd/github-action-benchmark@v1
|
||||
with:
|
||||
tool: 'go'
|
||||
output-file-path: output.txt
|
||||
github-token: ${{ secrets.BENCHMARK_TOKEN }}
|
||||
fail-on-alert: true
|
||||
comment-on-alert: true
|
||||
auto-push: true
|
|
@ -1,54 +0,0 @@
|
|||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [master]
|
||||
schedule:
|
||||
- cron: '0 3 * * 6'
|
||||
|
||||
jobs:
|
||||
analyse:
|
||||
name: Analyse
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
with:
|
||||
languages: go
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
|
@ -1,12 +0,0 @@
|
|||
on: [push, pull_request]
|
||||
name: Linter
|
||||
jobs:
|
||||
Golint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Fetch Repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Run Golint
|
||||
uses: reviewdog/action-golangci-lint@v1
|
||||
with:
|
||||
golangci_lint_flags: "--tests=false"
|
|
@ -1,12 +0,0 @@
|
|||
on: [push, pull_request]
|
||||
name: Security
|
||||
jobs:
|
||||
Gosec:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Fetch Repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Run Gosec
|
||||
uses: securego/gosec@master
|
||||
with:
|
||||
args: ./...
|
|
@ -1,18 +0,0 @@
|
|||
on: [push, pull_request]
|
||||
name: Test
|
||||
jobs:
|
||||
Build:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.11.x, 1.14.x]
|
||||
platform: [ubuntu-latest, windows-latest]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Fetch Repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Run Test
|
||||
run: go test ./... -v -race
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
*.tmp
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
@ -23,4 +24,7 @@
|
|||
*.workspace
|
||||
|
||||
# Dependencies
|
||||
vendor
|
||||
/vendor/
|
||||
vendor/
|
||||
vendor
|
||||
/Godeps/
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019-2020 Fenny and Contributors
|
||||
Copyright (c) 2019-present Joey Burggraaf (@Fenny) and Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
611
app.go
611
app.go
|
@ -11,9 +11,7 @@ package fiber
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
|
@ -25,20 +23,24 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
utils "github.com/gofiber/utils"
|
||||
colorable "github.com/mattn/go-colorable"
|
||||
isatty "github.com/mattn/go-isatty"
|
||||
fasthttp "github.com/valyala/fasthttp"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/gofiber/fiber/v2/utils/colorable"
|
||||
"github.com/gofiber/fiber/v2/utils/isatty"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// Version of current package
|
||||
const Version = "1.14.6"
|
||||
const Version = "2.0.0"
|
||||
|
||||
// Map is a shortcut for map[string]interface{}, useful for JSON returns
|
||||
type Map map[string]interface{}
|
||||
|
||||
// Handler defines a function to serve HTTP requests.
|
||||
type Handler = func(*Ctx)
|
||||
type Handler = func(*Ctx) error
|
||||
|
||||
// ErrorHandler defines a function that will process all errors
|
||||
// returned from any handlers in the stack
|
||||
type ErrorHandler = func(*Ctx, error) error
|
||||
|
||||
// Error represents an error that occurred while handling a request.
|
||||
type Error struct {
|
||||
|
@ -48,7 +50,6 @@ type Error struct {
|
|||
|
||||
// App denotes the Fiber application.
|
||||
type App struct {
|
||||
out io.Writer
|
||||
mutex sync.Mutex
|
||||
// Route stack divided by HTTP methods
|
||||
stack [][]*Route
|
||||
|
@ -62,23 +63,15 @@ type App struct {
|
|||
pool sync.Pool
|
||||
// Fasthttp server
|
||||
server *fasthttp.Server
|
||||
// App settings
|
||||
Settings *Settings `json:"settings"`
|
||||
// App config
|
||||
config Config
|
||||
}
|
||||
|
||||
// Settings is a struct holding the server settings.
|
||||
type Settings struct {
|
||||
// ErrorHandler is executed when you pass an error in the Next(err) method.
|
||||
// This function is also executed when middleware.Recover() catches a panic
|
||||
// Default: func(ctx *Ctx, err error) {
|
||||
// code := StatusInternalServerError
|
||||
// if e, ok := err.(*Error); ok {
|
||||
// code = e.Code
|
||||
// }
|
||||
// ctx.Set(HeaderContentType, MIMETextPlainCharsetUTF8)
|
||||
// ctx.Status(code).SendString(err.Error())
|
||||
// }
|
||||
ErrorHandler func(*Ctx, error) `json:"-"`
|
||||
// Config is a struct holding the server settings.
|
||||
type Config struct {
|
||||
// When set to true, this will spawn multiple Go processes listening on the same port.
|
||||
// Default: false
|
||||
Prefork bool `json:"prefork"`
|
||||
|
||||
// Enables the "Server: value" HTTP header.
|
||||
// Default: ""
|
||||
|
@ -111,10 +104,6 @@ type Settings struct {
|
|||
// Default: false
|
||||
ETag bool `json:"etag"`
|
||||
|
||||
// When set to true, this will spawn multiple Go processes listening on the same port.
|
||||
// Default: false
|
||||
Prefork bool `json:"prefork"`
|
||||
|
||||
// Max body size that the server accepts.
|
||||
// Default: 4 * 1024 * 1024
|
||||
BodyLimit int `json:"body_limit"`
|
||||
|
@ -123,28 +112,6 @@ type Settings struct {
|
|||
// Default: 256 * 1024
|
||||
Concurrency int `json:"concurrency"`
|
||||
|
||||
// When set to true, disables keep-alive connections.
|
||||
// The server will close incoming connections after sending the first response to client.
|
||||
// Default: false
|
||||
DisableKeepalive bool `json:"disable_keep_alive"`
|
||||
|
||||
// When set to true, causes the default date header to be excluded from the response.
|
||||
// Default: false
|
||||
DisableDefaultDate bool `json:"disable_default_date"`
|
||||
|
||||
// When set to true, causes the default Content-Type header to be excluded from the response.
|
||||
// Default: false
|
||||
DisableDefaultContentType bool `json:"disable_default_content_type"`
|
||||
|
||||
// When set to true, disables header normalization.
|
||||
// By default all header names are normalized: conteNT-tYPE -> Content-Type.
|
||||
// Default: false
|
||||
DisableHeaderNormalizing bool `json:"disable_header_normalizing"`
|
||||
|
||||
// When set to true, it will not print out the «Fiber» ASCII art and listening address.
|
||||
// Default: false
|
||||
DisableStartupMessage bool `json:"disable_startup_message"`
|
||||
|
||||
// Views is the interface that wraps the Render function.
|
||||
// Default: nil
|
||||
Views Views `json:"-"`
|
||||
|
@ -181,7 +148,56 @@ type Settings struct {
|
|||
// Default: ".fiber.gz"
|
||||
CompressedFileSuffix string `json:"compressed_file_suffix"`
|
||||
|
||||
// FEATURE: v1.13
|
||||
// ProxyHeader will enable c.IP() to return the value of the given header key
|
||||
// By default c.IP() will return the Remote IP from the TCP connection
|
||||
// This property can be useful if you are behind a load balancer: X-Forwarded-*
|
||||
// NOTE: headers are easily spoofed and the detected IP addresses are unreliable.
|
||||
// Default: ""
|
||||
ProxyHeader string `json:"proxy_header"`
|
||||
|
||||
// GETOnly rejects all non-GET requests if set to true.
|
||||
// This option is useful as anti-DoS protection for servers
|
||||
// accepting only GET requests. The request size is limited
|
||||
// by ReadBufferSize if GETOnly is set.
|
||||
// Server accepts all the requests by default.
|
||||
GETOnly bool `json:"get_only"`
|
||||
|
||||
// ErrorHandler is executed when an error is returned from fiber.Handler.
|
||||
// cfg := fiber.Config{}
|
||||
// cfg.ErrorHandler = func(c *Ctx, err error) error {
|
||||
// code := StatusInternalServerError
|
||||
// if e, ok := err.(*Error); ok {
|
||||
// code = e.Code
|
||||
// }
|
||||
// c.Set(HeaderContentType, MIMETextPlainCharsetUTF8)
|
||||
// return c.Status(code).SendString(err.Error())
|
||||
// }
|
||||
// app := fiber.New(cfg)
|
||||
ErrorHandler ErrorHandler `json:"-"`
|
||||
|
||||
// When set to true, disables keep-alive connections.
|
||||
// The server will close incoming connections after sending the first response to client.
|
||||
// Default: false
|
||||
DisableKeepalive bool `json:"disable_keep_alive"`
|
||||
|
||||
// When set to true, causes the default date header to be excluded from the response.
|
||||
// Default: false
|
||||
DisableDefaultDate bool `json:"disable_default_date"`
|
||||
|
||||
// When set to true, causes the default Content-Type header to be excluded from the response.
|
||||
// Default: false
|
||||
DisableDefaultContentType bool `json:"disable_default_content_type"`
|
||||
|
||||
// When set to true, disables header normalization.
|
||||
// By default all header names are normalized: conteNT-tYPE -> Content-Type.
|
||||
// Default: false
|
||||
DisableHeaderNormalizing bool `json:"disable_header_normalizing"`
|
||||
|
||||
// When set to true, it will not print out the «Fiber» ASCII art and listening address.
|
||||
// Default: false
|
||||
DisableStartupMessage bool `json:"disable_startup_message"`
|
||||
|
||||
// FEATURE: v1.16.x
|
||||
// The router executes the same handler by default if StrictRouting or CaseSensitive is disabled.
|
||||
// Enabling RedirectFixedPath will change this behaviour into a client redirect to the original route path.
|
||||
// Using the status code 301 for GET requests and 308 for all other request methods.
|
||||
|
@ -193,47 +209,47 @@ type Static struct {
|
|||
// When set to true, the server tries minimizing CPU usage by caching compressed files.
|
||||
// This works differently than the github.com/gofiber/compression middleware.
|
||||
// Optional. Default value false
|
||||
Compress bool
|
||||
Compress bool `json:"compress"`
|
||||
|
||||
// When set to true, enables byte range requests.
|
||||
// Optional. Default value false
|
||||
ByteRange bool
|
||||
ByteRange bool `json:"byte_range"`
|
||||
|
||||
// When set to true, enables directory browsing.
|
||||
// Optional. Default value false.
|
||||
Browse bool
|
||||
Browse bool `json:"browse"`
|
||||
|
||||
// The name of the index file for serving a directory.
|
||||
// Optional. Default value "index.html".
|
||||
Index string
|
||||
Index string `json:"index"`
|
||||
}
|
||||
|
||||
// default settings
|
||||
// Default settings
|
||||
const (
|
||||
defaultBodyLimit = 4 * 1024 * 1024
|
||||
defaultConcurrency = 256 * 1024
|
||||
defaultReadBufferSize = 4096
|
||||
defaultWriteBufferSize = 4096
|
||||
defaultCompressedFileSuffix = ".fiber.gz"
|
||||
DefaultBodyLimit = 4 * 1024 * 1024
|
||||
DefaultConcurrency = 256 * 1024
|
||||
DefaultReadBufferSize = 4096
|
||||
DefaultWriteBufferSize = 4096
|
||||
DefaultCompressedFileSuffix = ".fiber.gz"
|
||||
)
|
||||
|
||||
var defaultErrorHandler = func(ctx *Ctx, err error) {
|
||||
var DefaultErrorHandler = func(c *Ctx, err error) error {
|
||||
code := StatusInternalServerError
|
||||
if e, ok := err.(*Error); ok {
|
||||
code = e.Code
|
||||
}
|
||||
ctx.Set(HeaderContentType, MIMETextPlainCharsetUTF8)
|
||||
ctx.Status(code).SendString(err.Error())
|
||||
c.Set(HeaderContentType, MIMETextPlainCharsetUTF8)
|
||||
return c.Status(code).SendString(err.Error())
|
||||
}
|
||||
|
||||
// New creates a new Fiber named instance.
|
||||
// myApp := app.New()
|
||||
// You can pass an optional settings by passing a *Settings struct:
|
||||
// myApp := app.New(&fiber.Settings{
|
||||
// app := fiber.New()
|
||||
// You can pass an optional settings by passing a Config struct:
|
||||
// app := fiber.New(fiber.Config{
|
||||
// Prefork: true,
|
||||
// ServerHeader: "Fiber",
|
||||
// })
|
||||
func New(settings ...*Settings) *App {
|
||||
func New(config ...Config) *App {
|
||||
// Create a new app
|
||||
app := &App{
|
||||
// Create router stack
|
||||
|
@ -245,48 +261,55 @@ func New(settings ...*Settings) *App {
|
|||
return new(Ctx)
|
||||
},
|
||||
},
|
||||
// Set settings
|
||||
Settings: &Settings{},
|
||||
// Create config
|
||||
config: Config{},
|
||||
}
|
||||
|
||||
// Overwrite settings if provided
|
||||
if len(settings) > 0 {
|
||||
app.Settings = settings[0]
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
app.config = config[0]
|
||||
}
|
||||
|
||||
if app.Settings.BodyLimit <= 0 {
|
||||
app.Settings.BodyLimit = defaultBodyLimit
|
||||
// Override default values
|
||||
if app.config.BodyLimit <= 0 {
|
||||
app.config.BodyLimit = DefaultBodyLimit
|
||||
}
|
||||
if app.Settings.Concurrency <= 0 {
|
||||
app.Settings.Concurrency = defaultConcurrency
|
||||
if app.config.Concurrency <= 0 {
|
||||
app.config.Concurrency = DefaultConcurrency
|
||||
}
|
||||
if app.Settings.ReadBufferSize <= 0 {
|
||||
app.Settings.ReadBufferSize = defaultReadBufferSize
|
||||
if app.config.ReadBufferSize <= 0 {
|
||||
app.config.ReadBufferSize = DefaultReadBufferSize
|
||||
}
|
||||
if app.Settings.WriteBufferSize <= 0 {
|
||||
app.Settings.WriteBufferSize = defaultWriteBufferSize
|
||||
if app.config.WriteBufferSize <= 0 {
|
||||
app.config.WriteBufferSize = DefaultWriteBufferSize
|
||||
}
|
||||
if app.Settings.CompressedFileSuffix == "" {
|
||||
app.Settings.CompressedFileSuffix = defaultCompressedFileSuffix
|
||||
if app.config.CompressedFileSuffix == "" {
|
||||
app.config.CompressedFileSuffix = DefaultCompressedFileSuffix
|
||||
}
|
||||
if app.Settings.ErrorHandler == nil {
|
||||
app.Settings.ErrorHandler = defaultErrorHandler
|
||||
}
|
||||
if app.Settings.Immutable {
|
||||
if app.config.Immutable {
|
||||
getBytes, getString = getBytesImmutable, getStringImmutable
|
||||
}
|
||||
|
||||
if app.config.ErrorHandler == nil {
|
||||
app.config.ErrorHandler = DefaultErrorHandler
|
||||
}
|
||||
// Init app
|
||||
app.init()
|
||||
// Return app
|
||||
return app
|
||||
}
|
||||
|
||||
// Use registers a middleware route.
|
||||
// Middleware matches requests beginning with the provided prefix.
|
||||
// Providing a prefix is optional, it defaults to "/".
|
||||
// Use registers a middleware route. that will match requests
|
||||
// that contain the provided prefix ( which is optional and defaults to "/" ).
|
||||
//
|
||||
// app.Use(handler)
|
||||
// app.Use("/api", handler)
|
||||
// app.Use("/api", handler, handler)
|
||||
// app.Use(func(c *fiber.Ctx) error {
|
||||
// return c.Next()
|
||||
// })
|
||||
// app.Use("/api", func(c *fiber.Ctx) error {
|
||||
// return c.Next()
|
||||
// })
|
||||
// app.Use("/api", handler(), func(c *fiber.Ctx) error {
|
||||
// return c.Next()
|
||||
// })
|
||||
//
|
||||
// This method will match all HTTP verbs: GET, POST, PUT, HEAD etc...
|
||||
func (app *App) Use(args ...interface{}) Router {
|
||||
var prefix string
|
||||
var handlers []Handler
|
||||
|
@ -297,6 +320,15 @@ func (app *App) Use(args ...interface{}) Router {
|
|||
prefix = arg
|
||||
case Handler:
|
||||
handlers = append(handlers, arg)
|
||||
case *App:
|
||||
stack := arg.Stack()
|
||||
for m := range stack {
|
||||
for r := range stack[m] {
|
||||
route := app.copyRoute(stack[m][r])
|
||||
app.addRoute(route.Method, app.addPrefixToRoute(prefix, route))
|
||||
}
|
||||
}
|
||||
return app
|
||||
default:
|
||||
panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf(arg)))
|
||||
}
|
||||
|
@ -308,12 +340,7 @@ func (app *App) Use(args ...interface{}) Router {
|
|||
// Get registers a route for GET methods that requests a representation
|
||||
// of the specified resource. Requests using GET should only retrieve data.
|
||||
func (app *App) Get(path string, handlers ...Handler) Router {
|
||||
route := app.register(MethodGet, path, handlers...)
|
||||
// Add HEAD route
|
||||
headRoute := route
|
||||
app.addRoute(MethodHead, &headRoute)
|
||||
|
||||
return app
|
||||
return app.Add(MethodHead, path, handlers...).Add(MethodGet, path, handlers...)
|
||||
}
|
||||
|
||||
// Head registers a route for HEAD methods that asks for a response identical
|
||||
|
@ -363,27 +390,27 @@ func (app *App) Patch(path string, handlers ...Handler) Router {
|
|||
return app.Add(MethodPatch, path, handlers...)
|
||||
}
|
||||
|
||||
// Add ...
|
||||
// Add allows you to specify a HTTP method to register a route
|
||||
func (app *App) Add(method, path string, handlers ...Handler) Router {
|
||||
app.register(method, path, handlers...)
|
||||
return app
|
||||
return app.register(method, path, handlers...)
|
||||
}
|
||||
|
||||
// Static ...
|
||||
// Static will create a file server serving static files
|
||||
func (app *App) Static(prefix, root string, config ...Static) Router {
|
||||
app.registerStatic(prefix, root, config...)
|
||||
return app
|
||||
return app.registerStatic(prefix, root, config...)
|
||||
}
|
||||
|
||||
// All ...
|
||||
// All will register the handler on all HTTP methods
|
||||
func (app *App) All(path string, handlers ...Handler) Router {
|
||||
for _, method := range intMethod {
|
||||
app.Add(method, path, handlers...)
|
||||
_ = app.Add(method, path, handlers...)
|
||||
}
|
||||
return app
|
||||
}
|
||||
|
||||
// Group is used for Routes with common prefix to define a new sub-router with optional middleware.
|
||||
// api := app.Group("/api")
|
||||
// api.Get("/users", handler())
|
||||
func (app *App) Group(prefix string, handlers ...Handler) Router {
|
||||
if len(handlers) > 0 {
|
||||
app.register(methodUse, prefix, handlers...)
|
||||
|
@ -391,126 +418,81 @@ func (app *App) Group(prefix string, handlers ...Handler) Router {
|
|||
return &Group{prefix: prefix, app: app}
|
||||
}
|
||||
|
||||
// Error makes it compatible with `error` interface.
|
||||
// Error makes it compatible with the `error` interface.
|
||||
func (e *Error) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
// NewError creates a new HTTPError instance.
|
||||
// NewError creates a new HTTPError instance with an optional message
|
||||
func NewError(code int, message ...string) *Error {
|
||||
e := &Error{code, utils.StatusMessage(code)}
|
||||
e := &Error{
|
||||
Code: code,
|
||||
}
|
||||
if len(message) > 0 {
|
||||
e.Message = message[0]
|
||||
} else {
|
||||
e.Message = utils.StatusMessage(code)
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
// Routes returns all registered routes
|
||||
// for _, r := range app.Routes() {
|
||||
// fmt.Printf("%s\t%s\n", r.Method, r.Path)
|
||||
// }
|
||||
func (app *App) Routes() []*Route {
|
||||
fmt.Println("routes is deprecated since v1.13.2, please use `app.Stack()` to access the raw router stack")
|
||||
routes := make([]*Route, 0)
|
||||
for m := range app.stack {
|
||||
stackLoop:
|
||||
for r := range app.stack[m] {
|
||||
// Don't duplicate USE routesCount
|
||||
if app.stack[m][r].use {
|
||||
for i := range routes {
|
||||
if routes[i].use && routes[i].Path == app.stack[m][r].Path {
|
||||
continue stackLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
routes = append(routes, app.stack[m][r])
|
||||
}
|
||||
}
|
||||
return routes
|
||||
}
|
||||
|
||||
// Listener can be used to pass a custom listener.
|
||||
// You can pass an optional *tls.Config to enable TLS.
|
||||
// This method does not support the Prefork feature
|
||||
// To use Prefork, please use app.Listen()
|
||||
func (app *App) Listener(ln net.Listener, tlsconfig ...*tls.Config) error {
|
||||
// Update server settings
|
||||
app.init()
|
||||
// TLS config
|
||||
if len(tlsconfig) > 0 {
|
||||
ln = tls.NewListener(ln, tlsconfig[0])
|
||||
func (app *App) Listener(ln net.Listener) error {
|
||||
// Prefork is supported for custom listeners
|
||||
if app.config.Prefork {
|
||||
addr, tls := lnMetadata(ln)
|
||||
return app.prefork(addr, tls)
|
||||
}
|
||||
|
||||
// Print startup message
|
||||
if !app.Settings.DisableStartupMessage {
|
||||
app.startupMessage(ln.Addr().String(), len(tlsconfig) > 0, "")
|
||||
if !app.config.DisableStartupMessage {
|
||||
app.startupMessage(ln.Addr().String(), false, "")
|
||||
}
|
||||
|
||||
// TODO: Detect TLS
|
||||
return app.server.Serve(ln)
|
||||
}
|
||||
|
||||
// Listen serves HTTP requests from the given addr or port.
|
||||
// You can pass an optional *tls.Config to enable TLS.
|
||||
// Listen serves HTTP requests from the given addr.
|
||||
//
|
||||
// app.Listen(8080)
|
||||
// app.Listen("8080")
|
||||
// app.Listen(":8080")
|
||||
// app.Listen("127.0.0.1:8080")
|
||||
func (app *App) Listen(address interface{}, tlsconfig ...*tls.Config) error {
|
||||
// Convert address to string
|
||||
addr, ok := address.(string)
|
||||
if !ok {
|
||||
port, ok := address.(int)
|
||||
if !ok {
|
||||
return fmt.Errorf("listen: host must be an `int` port or `string` address")
|
||||
}
|
||||
addr = strconv.Itoa(port)
|
||||
}
|
||||
if !strings.Contains(addr, ":") {
|
||||
addr = ":" + addr
|
||||
}
|
||||
// Update server settings
|
||||
app.init()
|
||||
func (app *App) Listen(addr string) error {
|
||||
// Start prefork
|
||||
if app.Settings.Prefork {
|
||||
return app.prefork(addr, tlsconfig...)
|
||||
}
|
||||
// Set correct network protocol
|
||||
network := "tcp4"
|
||||
if isIPv6(addr) {
|
||||
network = "tcp6"
|
||||
if app.config.Prefork {
|
||||
return app.prefork(addr, nil)
|
||||
}
|
||||
// Setup listener
|
||||
ln, err := net.Listen(network, addr)
|
||||
ln, err := net.Listen("tcp4", addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Add TLS config if provided
|
||||
if len(tlsconfig) > 0 {
|
||||
ln = tls.NewListener(ln, tlsconfig[0])
|
||||
}
|
||||
// Print startup message
|
||||
if !app.Settings.DisableStartupMessage {
|
||||
app.startupMessage(ln.Addr().String(), len(tlsconfig) > 0, "")
|
||||
if !app.config.DisableStartupMessage {
|
||||
app.startupMessage(ln.Addr().String(), false, "")
|
||||
}
|
||||
// Start listening
|
||||
return app.server.Serve(ln)
|
||||
}
|
||||
|
||||
// Handler returns the server handler.
|
||||
func (app *App) Handler() fasthttp.RequestHandler {
|
||||
app.init()
|
||||
return app.handler
|
||||
// Config returns the app config as value ( read-only ).
|
||||
func (app *App) Config() Config {
|
||||
return app.config
|
||||
}
|
||||
|
||||
// Handler returns the server handler.
|
||||
func (app *App) Handler() fasthttp.RequestHandler {
|
||||
return app.handler
|
||||
}
|
||||
|
||||
// Stack returns the raw router stack.
|
||||
func (app *App) Stack() [][]*Route {
|
||||
return app.stack
|
||||
}
|
||||
|
||||
// Shutdown gracefully
|
||||
// shuts down the server without interrupting any active connections.
|
||||
// Shutdown gracefully shuts down the server without interrupting any active connections.
|
||||
// Shutdown works by first closing all open listeners and then waiting indefinitely for all connections to return to idle and then shut down.
|
||||
//
|
||||
// When Shutdown is called, Serve, ListenAndServe, and ListenAndServeTLS immediately return nil.
|
||||
// Make sure the program doesn't exit and waits instead for Shutdown to return.
|
||||
//
|
||||
// Shutdown does not close keepalive connections so its recommended to set ReadTimeout to something else than 0.
|
||||
|
@ -525,33 +507,38 @@ func (app *App) Shutdown() error {
|
|||
|
||||
// Test is used for internal debugging by passing a *http.Request.
|
||||
// Timeout is optional and defaults to 1s, -1 will disable it completely.
|
||||
func (app *App) Test(request *http.Request, msTimeout ...int) (*http.Response, error) {
|
||||
timeout := 1000 // 1 second default
|
||||
func (app *App) Test(req *http.Request, msTimeout ...int) (resp *http.Response, err error) {
|
||||
// Set timeout
|
||||
timeout := 1000
|
||||
if len(msTimeout) > 0 {
|
||||
timeout = msTimeout[0]
|
||||
}
|
||||
|
||||
// Add Content-Length if not provided with body
|
||||
if request.Body != http.NoBody && request.Header.Get("Content-Length") == "" {
|
||||
request.Header.Add("Content-Length", strconv.FormatInt(request.ContentLength, 10))
|
||||
if req.Body != http.NoBody && req.Header.Get(HeaderContentLength) == "" {
|
||||
req.Header.Add(HeaderContentLength, strconv.FormatInt(req.ContentLength, 10))
|
||||
}
|
||||
|
||||
// Dump raw http request
|
||||
dump, err := httputil.DumpRequest(request, true)
|
||||
dump, err := httputil.DumpRequest(req, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Update server settings
|
||||
app.init()
|
||||
|
||||
// Create test connection
|
||||
conn := new(testConn)
|
||||
|
||||
// Write raw http request
|
||||
if _, err = conn.r.Write(dump); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Serve conn to server
|
||||
channel := make(chan error)
|
||||
go func() {
|
||||
channel <- app.server.ServeConn(conn)
|
||||
}()
|
||||
|
||||
// Wait for callback
|
||||
if timeout >= 0 {
|
||||
// With timeout
|
||||
|
@ -564,19 +551,17 @@ func (app *App) Test(request *http.Request, msTimeout ...int) (*http.Response, e
|
|||
// Without timeout
|
||||
err = <-channel
|
||||
}
|
||||
|
||||
// Check for errors
|
||||
if err != nil {
|
||||
if err != nil && err != fasthttp.ErrGetOnly {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Read response
|
||||
buffer := bufio.NewReader(&conn.w)
|
||||
|
||||
// Convert raw http response to *http.Response
|
||||
resp, err := http.ReadResponse(buffer, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Return *http.Response
|
||||
return resp, nil
|
||||
return http.ReadResponse(buffer, req)
|
||||
}
|
||||
|
||||
type disableLogger struct{}
|
||||
|
@ -586,128 +571,148 @@ func (dl *disableLogger) Printf(format string, args ...interface{}) {
|
|||
}
|
||||
|
||||
func (app *App) init() *App {
|
||||
// Lock application
|
||||
// lock application
|
||||
app.mutex.Lock()
|
||||
defer app.mutex.Unlock()
|
||||
|
||||
// Load view engine if provided
|
||||
if app.Settings != nil {
|
||||
// Only load templates if an view engine is specified
|
||||
if app.Settings.Views != nil {
|
||||
if err := app.Settings.Views.Load(); err != nil {
|
||||
fmt.Printf("views: %v\n", err)
|
||||
// Only load templates if an view engine is specified
|
||||
if app.config.Views != nil {
|
||||
if err := app.config.Views.Load(); err != nil {
|
||||
fmt.Printf("views: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
// create fasthttp server
|
||||
app.server = &fasthttp.Server{
|
||||
Logger: &disableLogger{},
|
||||
LogAllErrors: false,
|
||||
ErrorHandler: func(fctx *fasthttp.RequestCtx, err error) {
|
||||
c := app.AcquireCtx(fctx)
|
||||
if _, ok := err.(*fasthttp.ErrSmallBuffer); ok {
|
||||
err = ErrRequestHeaderFieldsTooLarge
|
||||
} else if netErr, ok := err.(*net.OpError); ok && netErr.Timeout() {
|
||||
err = ErrRequestTimeout
|
||||
} else if err == fasthttp.ErrBodyTooLarge {
|
||||
err = ErrRequestEntityTooLarge
|
||||
} else if err == fasthttp.ErrGetOnly {
|
||||
err = ErrMethodNotAllowed
|
||||
} else if strings.Contains(err.Error(), "timeout") {
|
||||
err = ErrRequestTimeout
|
||||
} else {
|
||||
err = ErrBadRequest
|
||||
}
|
||||
}
|
||||
app.config.ErrorHandler(c, err)
|
||||
app.ReleaseCtx(c)
|
||||
},
|
||||
}
|
||||
if app.server == nil {
|
||||
app.server = &fasthttp.Server{
|
||||
Logger: &disableLogger{},
|
||||
LogAllErrors: false,
|
||||
ErrorHandler: func(fctx *fasthttp.RequestCtx, err error) {
|
||||
ctx := app.AcquireCtx(fctx)
|
||||
if _, ok := err.(*fasthttp.ErrSmallBuffer); ok {
|
||||
ctx.err = ErrRequestHeaderFieldsTooLarge
|
||||
} else if netErr, ok := err.(*net.OpError); ok && netErr.Timeout() {
|
||||
ctx.err = ErrRequestTimeout
|
||||
} else if len(err.Error()) == 33 && err.Error() == "body size exceeds the given limit" {
|
||||
ctx.err = ErrRequestEntityTooLarge
|
||||
} else {
|
||||
ctx.err = ErrBadRequest
|
||||
}
|
||||
app.Settings.ErrorHandler(ctx, ctx.err)
|
||||
app.ReleaseCtx(ctx)
|
||||
},
|
||||
}
|
||||
}
|
||||
if app.server.Handler == nil {
|
||||
app.server.Handler = app.handler
|
||||
}
|
||||
app.server.Name = app.Settings.ServerHeader
|
||||
app.server.Concurrency = app.Settings.Concurrency
|
||||
app.server.NoDefaultDate = app.Settings.DisableDefaultDate
|
||||
app.server.NoDefaultContentType = app.Settings.DisableDefaultContentType
|
||||
app.server.DisableHeaderNamesNormalizing = app.Settings.DisableHeaderNormalizing
|
||||
app.server.DisableKeepalive = app.Settings.DisableKeepalive
|
||||
app.server.MaxRequestBodySize = app.Settings.BodyLimit
|
||||
app.server.NoDefaultServerHeader = app.Settings.ServerHeader == ""
|
||||
app.server.ReadTimeout = app.Settings.ReadTimeout
|
||||
app.server.WriteTimeout = app.Settings.WriteTimeout
|
||||
app.server.IdleTimeout = app.Settings.IdleTimeout
|
||||
app.server.ReadBufferSize = app.Settings.ReadBufferSize
|
||||
app.server.WriteBufferSize = app.Settings.WriteBufferSize
|
||||
app.buildTree()
|
||||
|
||||
// fasthttp server settings
|
||||
app.server.Handler = app.handler
|
||||
app.server.Name = app.config.ServerHeader
|
||||
app.server.Concurrency = app.config.Concurrency
|
||||
app.server.NoDefaultDate = app.config.DisableDefaultDate
|
||||
app.server.NoDefaultContentType = app.config.DisableDefaultContentType
|
||||
app.server.DisableHeaderNamesNormalizing = app.config.DisableHeaderNormalizing
|
||||
app.server.DisableKeepalive = app.config.DisableKeepalive
|
||||
app.server.MaxRequestBodySize = app.config.BodyLimit
|
||||
app.server.NoDefaultServerHeader = app.config.ServerHeader == ""
|
||||
app.server.ReadTimeout = app.config.ReadTimeout
|
||||
app.server.WriteTimeout = app.config.WriteTimeout
|
||||
app.server.IdleTimeout = app.config.IdleTimeout
|
||||
app.server.ReadBufferSize = app.config.ReadBufferSize
|
||||
app.server.WriteBufferSize = app.config.WriteBufferSize
|
||||
app.server.GetOnly = app.config.GETOnly
|
||||
|
||||
// unlock application
|
||||
app.mutex.Unlock()
|
||||
return app
|
||||
}
|
||||
|
||||
const (
|
||||
cBlack = "\u001b[90m"
|
||||
cRed = "\u001b[91m"
|
||||
// cGreen = "\u001b[92m"
|
||||
// cYellow = "\u001b[93m"
|
||||
// cBlue = "\u001b[94m"
|
||||
// cMagenta = "\u001b[95m"
|
||||
cCyan = "\u001b[96m"
|
||||
// cWhite = "\u001b[97m"
|
||||
cReset = "\u001b[0m"
|
||||
)
|
||||
|
||||
func (app *App) startupMessage(addr string, tls bool, pids string) {
|
||||
// ignore child processes
|
||||
if app.IsChild() {
|
||||
if IsChild() {
|
||||
return
|
||||
}
|
||||
|
||||
// ascii logo
|
||||
var logo string
|
||||
logo += `%s _______ __ %s` + "\n"
|
||||
logo += `%s ____%s / ____(_) /_ ___ _____ %s` + "\n"
|
||||
logo += `%s_____%s / /_ / / __ \/ _ \/ ___/ %s` + "\n"
|
||||
logo += `%s __%s / __/ / / /_/ / __/ / %s` + "\n"
|
||||
logo += `%s /_/ /_/_.___/\___/_/%s %s` + ""
|
||||
logo += cRed + "v2 will be released on 15 September 2020!\nPlease visit https://gofiber.io/v2 for more information.\n" + cReset
|
||||
host, port := parseAddr(addr)
|
||||
padding := strconv.Itoa(len(host))
|
||||
if len(host) <= 4 {
|
||||
padding = "5"
|
||||
}
|
||||
var (
|
||||
tlsStr = "FALSE"
|
||||
preforkStr = "FALSE"
|
||||
handlerCount = strconv.Itoa(app.handlerCount)
|
||||
osName = utils.ToUpper(runtime.GOOS)
|
||||
cpuThreads = runtime.NumCPU()
|
||||
pid = os.Getpid()
|
||||
// logo += `%s _______ __ %s` + "\n"
|
||||
// logo += `%s ____%s / ____(_) /_ ___ _____ %s` + "\n"
|
||||
// logo += `%s_____%s / /_ / / __ \/ _ \/ ___/ %s` + "\n"
|
||||
// logo += `%s __%s / __/ / / /_/ / __/ / %s` + "\n"
|
||||
// logo += `%s /_/ /_/_.___/\___/_/%s %s` + "\n"
|
||||
|
||||
logo += "\n%s"
|
||||
logo += " ┌───────────────────────────────────────────────────────┐\n"
|
||||
logo += " │ %sFiber v%s%s │\n"
|
||||
logo += " │ Express inspired web framework │\n"
|
||||
logo += " │ │\n"
|
||||
logo += " │ Host : %s %s : OS │\n"
|
||||
logo += " │ Port : %s %s : Threads │\n"
|
||||
logo += " │ TLS : %s %s : Prefork │\n"
|
||||
logo += " │ Handlers : %s %s : PID │\n"
|
||||
logo += " └───────────────────────────────────────────────────────┘"
|
||||
logo += "%s\n"
|
||||
|
||||
const (
|
||||
cBlack = "\u001b[90m"
|
||||
cRed = "\u001b[91m"
|
||||
cCyan = "\u001b[96m"
|
||||
cGreen = "\u001b[92m"
|
||||
// cYellow = "\u001b[93m"
|
||||
// cBlue = "\u001b[94m"
|
||||
// cMagenta = "\u001b[95m"
|
||||
// cWhite = "\u001b[97m"
|
||||
cReset = "\u001b[0m"
|
||||
)
|
||||
|
||||
clrL := func(v interface{}) string {
|
||||
if v == "disabled" {
|
||||
return fmt.Sprintf("%s%15v%s", cRed, v, cBlack)
|
||||
}
|
||||
if v == "enabled" {
|
||||
return fmt.Sprintf("%s%15v%s", cGreen, v, cBlack)
|
||||
}
|
||||
return fmt.Sprintf("%s%15v%s", cCyan, v, cBlack)
|
||||
}
|
||||
clR := func(v interface{}) string {
|
||||
if v == "disabled" {
|
||||
return fmt.Sprintf("%s%-15v%s", cRed, v, cBlack)
|
||||
}
|
||||
if v == "enabled" {
|
||||
return fmt.Sprintf("%s%-15v%s", cGreen, v, cBlack)
|
||||
}
|
||||
return fmt.Sprintf("%s%-15v%s", cCyan, v, cBlack)
|
||||
}
|
||||
|
||||
host, port := parseAddr(addr)
|
||||
var (
|
||||
isTLS = "disabled"
|
||||
isPrefork = "disabled"
|
||||
)
|
||||
|
||||
if host == "" {
|
||||
host = "0.0.0.0"
|
||||
}
|
||||
if tls {
|
||||
tlsStr = "TRUE"
|
||||
isTLS = "enabled"
|
||||
}
|
||||
if app.Settings.Prefork {
|
||||
preforkStr = "TRUE"
|
||||
if app.config.Prefork {
|
||||
isPrefork = "enabled"
|
||||
}
|
||||
// tabwriter makes sure the spacing are consistent across different values
|
||||
// colorable handles the escape sequence for stdout using ascii color codes
|
||||
host = fmt.Sprintf("%-"+padding+"s", host)
|
||||
port = fmt.Sprintf("%-"+padding+"s", port)
|
||||
tlsStr = fmt.Sprintf("%-"+padding+"s", tlsStr)
|
||||
handlerCount = fmt.Sprintf("%-"+padding+"s", handlerCount)
|
||||
|
||||
app.out = colorable.NewColorableStdout()
|
||||
// Check if colors are supported
|
||||
if os.Getenv("TERM") == "dumb" ||
|
||||
(!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) {
|
||||
app.out = colorable.NewNonColorable(os.Stdout)
|
||||
out := colorable.NewColorableStdout()
|
||||
if os.Getenv("TERM") == "dumb" || (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) {
|
||||
out = colorable.NewNonColorable(os.Stdout)
|
||||
}
|
||||
// simple Sprintf function that defaults back to black
|
||||
cyan := func(v interface{}) string {
|
||||
return fmt.Sprintf("%s%v%s", cCyan, v, cBlack)
|
||||
}
|
||||
// Build startup banner
|
||||
fmt.Fprintf(app.out, logo, cBlack, cBlack,
|
||||
cCyan, cBlack, fmt.Sprintf(" HOST %s OS %s", cyan(host), cyan(osName)),
|
||||
cCyan, cBlack, fmt.Sprintf(" PORT %s THREADS %s", cyan(port), cyan(cpuThreads)),
|
||||
cCyan, cBlack, fmt.Sprintf(" TLS %s PREFORK %s", cyan(tlsStr), cyan(preforkStr)),
|
||||
cBlack, cyan(Version), fmt.Sprintf(" HANDLERS %s PID %s%s%s\n", cyan(handlerCount), cyan(pid), pids, cReset),
|
||||
|
||||
fmt.Fprintf(out, logo,
|
||||
cBlack,
|
||||
cCyan, Version, cBlack,
|
||||
clR(host), clrL(utils.ToUpper(runtime.GOOS)),
|
||||
clR(port), clrL(runtime.NumCPU()),
|
||||
clR(isTLS), clrL(isPrefork),
|
||||
clR(app.handlerCount), clrL(os.Getpid()),
|
||||
cReset,
|
||||
)
|
||||
|
||||
}
|
||||
|
|
369
app_test.go
369
app_test.go
|
@ -20,11 +20,15 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
utils "github.com/gofiber/utils"
|
||||
fasthttp "github.com/valyala/fasthttp"
|
||||
fasthttputil "github.com/valyala/fasthttp/fasthttputil"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/valyala/fasthttp"
|
||||
"github.com/valyala/fasthttp/fasthttputil"
|
||||
)
|
||||
|
||||
var testEmptyHandler = func(c *Ctx) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func testStatus200(t *testing.T, app *App, url string, method string) {
|
||||
req := httptest.NewRequest(method, url, nil)
|
||||
|
||||
|
@ -36,11 +40,13 @@ func testStatus200(t *testing.T, app *App, url string, method string) {
|
|||
func Test_App_MethodNotAllowed(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Use(func(ctx *Ctx) { ctx.Next() })
|
||||
app.Use(func(c *Ctx) error {
|
||||
return c.Next()
|
||||
})
|
||||
|
||||
app.Post("/", func(c *Ctx) {})
|
||||
app.Post("/", testEmptyHandler)
|
||||
|
||||
app.Options("/", func(c *Ctx) {})
|
||||
app.Options("/", testEmptyHandler)
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("POST", "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
@ -62,7 +68,7 @@ func Test_App_MethodNotAllowed(t *testing.T) {
|
|||
utils.AssertEqual(t, 405, resp.StatusCode)
|
||||
utils.AssertEqual(t, "POST, OPTIONS", resp.Header.Get(HeaderAllow))
|
||||
|
||||
app.Get("/", func(c *Ctx) {})
|
||||
app.Get("/", testEmptyHandler)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest("TRACE", "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
@ -83,22 +89,21 @@ func Test_App_MethodNotAllowed(t *testing.T) {
|
|||
func Test_App_Custom_Middleware_404_Should_Not_SetMethodNotAllowed(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Use(func(ctx *Ctx) {
|
||||
ctx.Status(404)
|
||||
app.Use(func(c *Ctx) error {
|
||||
return c.SendStatus(404)
|
||||
})
|
||||
|
||||
app.Post("/", func(c *Ctx) {})
|
||||
app.Post("/", testEmptyHandler)
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, 404, resp.StatusCode)
|
||||
|
||||
g := app.Group("/with-next", func(ctx *Ctx) {
|
||||
ctx.Status(404)
|
||||
ctx.Next()
|
||||
g := app.Group("/with-next", func(c *Ctx) error {
|
||||
return c.Status(404).Next()
|
||||
})
|
||||
|
||||
g.Post("/", func(c *Ctx) {})
|
||||
g.Post("/", testEmptyHandler)
|
||||
|
||||
resp, err = app.Test(httptest.NewRequest("GET", "/with-next", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
@ -111,7 +116,7 @@ func Test_App_ServerErrorHandler_SmallReadBuffer(t *testing.T) {
|
|||
)
|
||||
app := New()
|
||||
|
||||
app.Get("/", func(c *Ctx) {
|
||||
app.Get("/", func(c *Ctx) error {
|
||||
panic(errors.New("should never called"))
|
||||
})
|
||||
|
||||
|
@ -132,13 +137,13 @@ func Test_App_ServerErrorHandler_SmallReadBuffer(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func Test_App_ErrorHandler(t *testing.T) {
|
||||
app := New(&Settings{
|
||||
func Test_App_Errors(t *testing.T) {
|
||||
app := New(Config{
|
||||
BodyLimit: 4,
|
||||
})
|
||||
|
||||
app.Get("/", func(c *Ctx) {
|
||||
c.Next(errors.New("hi, i'm an error"))
|
||||
app.Get("/", func(c *Ctx) error {
|
||||
return errors.New("hi, i'm an error")
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
|
@ -156,14 +161,14 @@ func Test_App_ErrorHandler(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_App_ErrorHandler_Custom(t *testing.T) {
|
||||
app := New(&Settings{
|
||||
ErrorHandler: func(ctx *Ctx, err error) {
|
||||
ctx.Status(200).SendString("hi, i'm an custom error")
|
||||
app := New(Config{
|
||||
ErrorHandler: func(c *Ctx, err error) error {
|
||||
return c.Status(200).SendString("hi, i'm an custom error")
|
||||
},
|
||||
})
|
||||
|
||||
app.Get("/", func(c *Ctx) {
|
||||
c.Next(errors.New("hi, i'm an error"))
|
||||
app.Get("/", func(c *Ctx) error {
|
||||
return errors.New("hi, i'm an error")
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
|
@ -178,17 +183,17 @@ func Test_App_ErrorHandler_Custom(t *testing.T) {
|
|||
func Test_App_Nested_Params(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
c.Status(400).Send("Should move on")
|
||||
app.Get("/test", func(c *Ctx) error {
|
||||
return c.Status(400).Send([]byte("Should move on"))
|
||||
})
|
||||
app.Get("/test/:param", func(c *Ctx) {
|
||||
c.Status(400).Send("Should move on")
|
||||
app.Get("/test/:param", func(c *Ctx) error {
|
||||
return c.Status(400).Send([]byte("Should move on"))
|
||||
})
|
||||
app.Get("/test/:param/test", func(c *Ctx) {
|
||||
c.Status(400).Send("Should move on")
|
||||
app.Get("/test/:param/test", func(c *Ctx) error {
|
||||
return c.Status(400).Send([]byte("Should move on"))
|
||||
})
|
||||
app.Get("/test/:param/test/:param2", func(c *Ctx) {
|
||||
c.Status(200).Send("Good job")
|
||||
app.Get("/test/:param/test/:param2", func(c *Ctx) error {
|
||||
return c.Status(200).Send([]byte("Good job"))
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/test/john/test/doe", nil)
|
||||
|
@ -198,20 +203,37 @@ func Test_App_Nested_Params(t *testing.T) {
|
|||
utils.AssertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
}
|
||||
|
||||
// func Test_App_Use_App(t *testing.T) {
|
||||
// micro := New()
|
||||
// micro.Get("/doe", func(c *Ctx) error {
|
||||
// return c.SendStatus(StatusOK)
|
||||
// })
|
||||
|
||||
// app := New()
|
||||
// app.Use("/john", micro)
|
||||
|
||||
// resp, err := app.Test(httptest.NewRequest("GET", "/john/doe", nil))
|
||||
// utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
// utils.AssertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
// }
|
||||
|
||||
func Test_App_Use_Params(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Use("/prefix/:param", func(c *Ctx) {
|
||||
app.Use("/prefix/:param", func(c *Ctx) error {
|
||||
utils.AssertEqual(t, "john", c.Params("param"))
|
||||
return nil
|
||||
})
|
||||
|
||||
app.Use("/foo/:bar?", func(c *Ctx) {
|
||||
app.Use("/foo/:bar?", func(c *Ctx) error {
|
||||
utils.AssertEqual(t, "foobar", c.Params("bar", "foobar"))
|
||||
return nil
|
||||
})
|
||||
|
||||
app.Use("/:param/*", func(c *Ctx) {
|
||||
app.Use("/:param/*", func(c *Ctx) error {
|
||||
utils.AssertEqual(t, "john", c.Params("param"))
|
||||
utils.AssertEqual(t, "doe", c.Params("*"))
|
||||
return nil
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/prefix/john", nil))
|
||||
|
@ -244,59 +266,59 @@ func Test_App_Add_Method_Test(t *testing.T) {
|
|||
utils.AssertEqual(t, "add: invalid http method JOHN\n", fmt.Sprintf("%v", err))
|
||||
}
|
||||
}()
|
||||
app.Add("JOHN", "/doe", func(c *Ctx) {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func Test_App_Listen_TLS(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
// Create tls certificate
|
||||
cer, err := tls.LoadX509KeyPair("./.github/TEST_DATA/ssl.pem", "./.github/TEST_DATA/ssl.key")
|
||||
if err != nil {
|
||||
utils.AssertEqual(t, nil, err)
|
||||
}
|
||||
config := &tls.Config{Certificates: []tls.Certificate{cer}}
|
||||
|
||||
go func() {
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
utils.AssertEqual(t, nil, app.Shutdown())
|
||||
}()
|
||||
|
||||
utils.AssertEqual(t, nil, app.Listen(3078, config))
|
||||
app.Add("JOHN", "/doe", testEmptyHandler)
|
||||
}
|
||||
|
||||
func Test_App_Listener_TLS(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
// Create tls certificate
|
||||
cer, err := tls.LoadX509KeyPair("./.github/TEST_DATA/ssl.pem", "./.github/TEST_DATA/ssl.key")
|
||||
cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")
|
||||
if err != nil {
|
||||
utils.AssertEqual(t, nil, err)
|
||||
}
|
||||
config := &tls.Config{Certificates: []tls.Certificate{cer}}
|
||||
|
||||
ln, err := net.Listen("tcp4", ":3078")
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
||||
ln = tls.NewListener(ln, config)
|
||||
|
||||
go func() {
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
utils.AssertEqual(t, nil, app.Shutdown())
|
||||
}()
|
||||
|
||||
ln, err := net.Listen("tcp4", ":3055")
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
||||
utils.AssertEqual(t, nil, app.Listener(ln, config))
|
||||
utils.AssertEqual(t, nil, app.Listener(ln))
|
||||
}
|
||||
|
||||
// go test -run Test_App_GETOnly
|
||||
func Test_App_GETOnly(t *testing.T) {
|
||||
app := New(Config{
|
||||
GETOnly: true,
|
||||
})
|
||||
|
||||
app.Post("/", func(c *Ctx) error {
|
||||
return c.SendString("Hello 👋!")
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("POST", "/", nil)
|
||||
resp, err := app.Test(req)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, StatusMethodNotAllowed, resp.StatusCode, "Status code")
|
||||
}
|
||||
|
||||
func Test_App_Use_Params_Group(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
group := app.Group("/prefix/:param/*")
|
||||
group.Use("/", func(c *Ctx) {
|
||||
c.Next()
|
||||
group.Use("/", func(c *Ctx) error {
|
||||
return c.Next()
|
||||
})
|
||||
group.Get("/test", func(c *Ctx) {
|
||||
group.Get("/test", func(c *Ctx) error {
|
||||
utils.AssertEqual(t, "john", c.Params("param"))
|
||||
utils.AssertEqual(t, "doe", c.Params("*"))
|
||||
return nil
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/prefix/john/doe/test", nil))
|
||||
|
@ -305,12 +327,12 @@ func Test_App_Use_Params_Group(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_App_Chaining(t *testing.T) {
|
||||
n := func(c *Ctx) {
|
||||
c.Next()
|
||||
n := func(c *Ctx) error {
|
||||
return c.Next()
|
||||
}
|
||||
app := New()
|
||||
app.Use("/john", n, n, n, n, func(c *Ctx) {
|
||||
c.Status(202)
|
||||
app.Use("/john", n, n, n, n, func(c *Ctx) error {
|
||||
return c.SendStatus(202)
|
||||
})
|
||||
// check handler count for registered HEAD route
|
||||
utils.AssertEqual(t, 5, len(app.stack[methodInt(MethodHead)][0].Handlers), "app.Test(req)")
|
||||
|
@ -321,8 +343,8 @@ func Test_App_Chaining(t *testing.T) {
|
|||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, 202, resp.StatusCode, "Status code")
|
||||
|
||||
app.Get("/test", n, n, n, n, func(c *Ctx) {
|
||||
c.Status(203)
|
||||
app.Get("/test", n, n, n, n, func(c *Ctx) error {
|
||||
return c.SendStatus(203)
|
||||
})
|
||||
|
||||
req = httptest.NewRequest("GET", "/test", nil)
|
||||
|
@ -336,18 +358,19 @@ func Test_App_Chaining(t *testing.T) {
|
|||
func Test_App_Order(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Get("/test", func(c *Ctx) {
|
||||
c.Write("1")
|
||||
c.Next()
|
||||
app.Get("/test", func(c *Ctx) error {
|
||||
c.Write([]byte("1"))
|
||||
return c.Next()
|
||||
})
|
||||
|
||||
app.All("/test", func(c *Ctx) {
|
||||
c.Write("2")
|
||||
c.Next()
|
||||
app.All("/test", func(c *Ctx) error {
|
||||
c.Write([]byte("2"))
|
||||
return c.Next()
|
||||
})
|
||||
|
||||
app.Use(func(c *Ctx) {
|
||||
c.Write("3")
|
||||
app.Use(func(c *Ctx) error {
|
||||
c.Write([]byte("3"))
|
||||
return nil
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/test", nil)
|
||||
|
@ -361,7 +384,7 @@ func Test_App_Order(t *testing.T) {
|
|||
utils.AssertEqual(t, "123", string(body))
|
||||
}
|
||||
func Test_App_Methods(t *testing.T) {
|
||||
var dummyHandler = func(c *Ctx) {}
|
||||
var dummyHandler = testEmptyHandler
|
||||
|
||||
app := New()
|
||||
|
||||
|
@ -402,20 +425,16 @@ func Test_App_Methods(t *testing.T) {
|
|||
|
||||
func Test_App_New(t *testing.T) {
|
||||
app := New()
|
||||
app.Get("/", func(*Ctx) {
|
||||
app.Get("/", testEmptyHandler)
|
||||
|
||||
})
|
||||
|
||||
appConfig := New(&Settings{
|
||||
appConfig := New(Config{
|
||||
Immutable: true,
|
||||
})
|
||||
appConfig.Get("/", func(*Ctx) {
|
||||
|
||||
})
|
||||
appConfig.Get("/", testEmptyHandler)
|
||||
}
|
||||
|
||||
func Test_App_Shutdown(t *testing.T) {
|
||||
app := New(&Settings{
|
||||
app := New(Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
if err := app.Shutdown(); err != nil {
|
||||
|
@ -483,9 +502,9 @@ func Test_App_Static_Direct(t *testing.T) {
|
|||
func Test_App_Static_Group(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
grp := app.Group("/v1", func(c *Ctx) {
|
||||
grp := app.Group("/v1", func(c *Ctx) error {
|
||||
c.Set("Test-Header", "123")
|
||||
c.Next()
|
||||
return c.Next()
|
||||
})
|
||||
|
||||
grp.Static("/v2", "./.github/FUNDING.yml")
|
||||
|
@ -588,15 +607,15 @@ func Test_App_Mixed_Routes_WithSameLen(t *testing.T) {
|
|||
app := New()
|
||||
|
||||
// middleware
|
||||
app.Use(func(ctx *Ctx) {
|
||||
ctx.Set("TestHeader", "TestValue")
|
||||
ctx.Next()
|
||||
app.Use(func(c *Ctx) error {
|
||||
c.Set("TestHeader", "TestValue")
|
||||
return c.Next()
|
||||
})
|
||||
// routes with the same length
|
||||
app.Static("/tesbar", "./.github")
|
||||
app.Get("/foobar", func(ctx *Ctx) {
|
||||
ctx.Send("FOO_BAR")
|
||||
ctx.Type("html")
|
||||
app.Get("/foobar", func(c *Ctx) error {
|
||||
c.Type("html")
|
||||
return c.Send([]byte("FOO_BAR"))
|
||||
})
|
||||
|
||||
// match get route
|
||||
|
@ -637,7 +656,7 @@ func Test_App_Group_Invalid(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_App_Group(t *testing.T) {
|
||||
var dummyHandler = func(c *Ctx) {}
|
||||
var dummyHandler = testEmptyHandler
|
||||
|
||||
app := New()
|
||||
|
||||
|
@ -695,18 +714,18 @@ func Test_App_Group(t *testing.T) {
|
|||
|
||||
func Test_App_Deep_Group(t *testing.T) {
|
||||
runThroughCount := 0
|
||||
var dummyHandler = func(c *Ctx) {
|
||||
var dummyHandler = func(c *Ctx) error {
|
||||
runThroughCount++
|
||||
c.Next()
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
app := New()
|
||||
gAPI := app.Group("/api", dummyHandler)
|
||||
gV1 := gAPI.Group("/v1", dummyHandler)
|
||||
gUser := gV1.Group("/user", dummyHandler)
|
||||
gUser.Get("/authenticate", func(ctx *Ctx) {
|
||||
gUser.Get("/authenticate", func(c *Ctx) error {
|
||||
runThroughCount++
|
||||
ctx.SendStatus(200)
|
||||
return c.SendStatus(200)
|
||||
})
|
||||
testStatus200(t, app, "/api/v1/user/authenticate", "GET")
|
||||
utils.AssertEqual(t, 4, runThroughCount, "Loop count")
|
||||
|
@ -715,12 +734,13 @@ func Test_App_Deep_Group(t *testing.T) {
|
|||
// go test -run Test_App_Next_Method
|
||||
func Test_App_Next_Method(t *testing.T) {
|
||||
app := New()
|
||||
app.Settings.DisableStartupMessage = true
|
||||
app.config.DisableStartupMessage = true
|
||||
|
||||
app.Use(func(c *Ctx) {
|
||||
app.Use(func(c *Ctx) error {
|
||||
utils.AssertEqual(t, "GET", c.Method())
|
||||
c.Next()
|
||||
utils.AssertEqual(t, "GET", c.Method())
|
||||
return nil
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
|
@ -732,30 +752,24 @@ func Test_App_Next_Method(t *testing.T) {
|
|||
func Test_App_Listen(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
utils.AssertEqual(t, false, app.Listen(1.23) == nil)
|
||||
go func() {
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
utils.AssertEqual(t, nil, app.Shutdown())
|
||||
}()
|
||||
|
||||
utils.AssertEqual(t, false, app.Listen(":1.23") == nil)
|
||||
utils.AssertEqual(t, nil, app.Listen(":4003"))
|
||||
|
||||
go func() {
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
utils.AssertEqual(t, nil, app.Shutdown())
|
||||
}()
|
||||
|
||||
utils.AssertEqual(t, nil, app.Listen(4003))
|
||||
|
||||
go func() {
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
utils.AssertEqual(t, nil, app.Shutdown())
|
||||
}()
|
||||
|
||||
utils.AssertEqual(t, nil, app.Listen("[::]:4010"))
|
||||
utils.AssertEqual(t, nil, app.Listen(":4010"))
|
||||
}
|
||||
|
||||
// go test -run Test_App_Listener
|
||||
func Test_App_Listener(t *testing.T) {
|
||||
app := New(&Settings{
|
||||
Prefork: true,
|
||||
})
|
||||
app := New()
|
||||
|
||||
go func() {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
@ -766,16 +780,25 @@ func Test_App_Listener(t *testing.T) {
|
|||
utils.AssertEqual(t, nil, app.Listener(ln))
|
||||
}
|
||||
|
||||
// go test -v -run=^$ -bench=Benchmark_AcquireCtx -benchmem -count=4
|
||||
func Benchmark_AcquireCtx(b *testing.B) {
|
||||
app := New()
|
||||
for n := 0; n < b.N; n++ {
|
||||
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
||||
app.ReleaseCtx(c)
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -run=^$ -bench=Benchmark_App_ETag -benchmem -count=4
|
||||
func Benchmark_App_ETag(b *testing.B) {
|
||||
app := New()
|
||||
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
||||
defer app.ReleaseCtx(c)
|
||||
c.Send("Hello, World!")
|
||||
c.Send([]byte("Hello, World!"))
|
||||
for n := 0; n < b.N; n++ {
|
||||
setETag(c, false)
|
||||
}
|
||||
utils.AssertEqual(b, `"13-1831710635"`, string(c.Fasthttp.Response.Header.Peek(HeaderETag)))
|
||||
utils.AssertEqual(b, `"13-1831710635"`, string(c.Response().Header.Peek(HeaderETag)))
|
||||
}
|
||||
|
||||
// go test -v -run=^$ -bench=Benchmark_App_ETag_Weak -benchmem -count=4
|
||||
|
@ -783,11 +806,11 @@ func Benchmark_App_ETag_Weak(b *testing.B) {
|
|||
app := New()
|
||||
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
||||
defer app.ReleaseCtx(c)
|
||||
c.Send("Hello, World!")
|
||||
c.Send([]byte("Hello, World!"))
|
||||
for n := 0; n < b.N; n++ {
|
||||
setETag(c, true)
|
||||
}
|
||||
utils.AssertEqual(b, `W/"13-1831710635"`, string(c.Fasthttp.Response.Header.Peek(HeaderETag)))
|
||||
utils.AssertEqual(b, `W/"13-1831710635"`, string(c.Response().Header.Peek(HeaderETag)))
|
||||
}
|
||||
|
||||
// go test -run Test_NewError
|
||||
|
@ -799,16 +822,17 @@ func Test_NewError(t *testing.T) {
|
|||
|
||||
func Test_Test_Timeout(t *testing.T) {
|
||||
app := New()
|
||||
app.Settings.DisableStartupMessage = true
|
||||
app.config.DisableStartupMessage = true
|
||||
|
||||
app.Get("/", func(_ *Ctx) {})
|
||||
app.Get("/", testEmptyHandler)
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil), -1)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
|
||||
app.Get("timeout", func(c *Ctx) {
|
||||
app.Get("timeout", func(c *Ctx) error {
|
||||
time.Sleep(55 * time.Millisecond)
|
||||
return nil
|
||||
})
|
||||
|
||||
_, err = app.Test(httptest.NewRequest("GET", "/timeout", nil), 50)
|
||||
|
@ -823,9 +847,9 @@ func (errorReader) Read([]byte) (int, error) {
|
|||
|
||||
func Test_Test_DumpError(t *testing.T) {
|
||||
app := New()
|
||||
app.Settings.DisableStartupMessage = true
|
||||
app.config.DisableStartupMessage = true
|
||||
|
||||
app.Get("/", func(_ *Ctx) {})
|
||||
app.Get("/", testEmptyHandler)
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", errorReader(0)))
|
||||
utils.AssertEqual(t, true, resp == nil)
|
||||
|
@ -844,24 +868,23 @@ func (invalidView) Load() error { return errors.New("invalid view") }
|
|||
func (i invalidView) Render(io.Writer, string, interface{}, ...string) error { panic("implement me") }
|
||||
|
||||
func Test_App_Init_Error_View(t *testing.T) {
|
||||
app := New(&Settings{Views: invalidView{}})
|
||||
app.init()
|
||||
app := New(Config{Views: invalidView{}})
|
||||
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
utils.AssertEqual(t, "implement me", fmt.Sprintf("%v", err))
|
||||
}
|
||||
}()
|
||||
_ = app.Settings.Views.Render(nil, "", nil)
|
||||
_ = app.config.Views.Render(nil, "", nil)
|
||||
}
|
||||
|
||||
func Test_App_Stack(t *testing.T) {
|
||||
app := New()
|
||||
|
||||
app.Use("/path0", func(_ *Ctx) {})
|
||||
app.Get("/path1", func(_ *Ctx) {})
|
||||
app.Get("/path2", func(_ *Ctx) {})
|
||||
app.Post("/path3", func(_ *Ctx) {})
|
||||
app.Use("/path0", testEmptyHandler)
|
||||
app.Get("/path1", testEmptyHandler)
|
||||
app.Get("/path2", testEmptyHandler)
|
||||
app.Post("/path3", testEmptyHandler)
|
||||
|
||||
stack := app.Stack()
|
||||
utils.AssertEqual(t, 9, len(stack))
|
||||
|
@ -877,49 +900,49 @@ func Test_App_Stack(t *testing.T) {
|
|||
}
|
||||
|
||||
// go test -run Test_App_ReadTimeout
|
||||
//func Test_App_ReadTimeout(t *testing.T) {
|
||||
// app := New(&Settings{
|
||||
// ReadTimeout: time.Nanosecond,
|
||||
// IdleTimeout: time.Minute,
|
||||
// DisableStartupMessage: true,
|
||||
// DisableKeepalive: true,
|
||||
// })
|
||||
//
|
||||
// app.Get("/read-timeout", func(c *Ctx) {
|
||||
// c.SendString("I should not be sent")
|
||||
// })
|
||||
//
|
||||
// go func() {
|
||||
// time.Sleep(500 * time.Millisecond)
|
||||
//
|
||||
// conn, err := net.Dial("tcp4", "127.0.0.1:4004")
|
||||
// utils.AssertEqual(t, nil, err)
|
||||
// defer conn.Close()
|
||||
//
|
||||
// _, err = conn.Write([]byte("HEAD /read-timeout HTTP/1.1\r\n"))
|
||||
// utils.AssertEqual(t, nil, err)
|
||||
//
|
||||
// buf := make([]byte, 1024)
|
||||
// var n int
|
||||
// n, err = conn.Read(buf)
|
||||
//
|
||||
// utils.AssertEqual(t, nil, err)
|
||||
// utils.AssertEqual(t, true, bytes.Contains(buf[:n], []byte("408 Request Timeout")))
|
||||
//
|
||||
// utils.AssertEqual(t, nil, app.Shutdown())
|
||||
// }()
|
||||
//
|
||||
// utils.AssertEqual(t, nil, app.Listen(4004))
|
||||
//}
|
||||
func Test_App_ReadTimeout(t *testing.T) {
|
||||
app := New(Config{
|
||||
ReadTimeout: time.Nanosecond,
|
||||
IdleTimeout: time.Minute,
|
||||
DisableStartupMessage: true,
|
||||
DisableKeepalive: true,
|
||||
})
|
||||
|
||||
app.Get("/read-timeout", func(c *Ctx) error {
|
||||
return c.SendString("I should not be sent")
|
||||
})
|
||||
|
||||
go func() {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
conn, err := net.Dial("tcp4", "127.0.0.1:4004")
|
||||
utils.AssertEqual(t, nil, err)
|
||||
defer conn.Close()
|
||||
|
||||
_, err = conn.Write([]byte("HEAD /read-timeout HTTP/1.1\r\n"))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
var n int
|
||||
n, err = conn.Read(buf)
|
||||
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, true, bytes.Contains(buf[:n], []byte("408 Request Timeout")))
|
||||
|
||||
utils.AssertEqual(t, nil, app.Shutdown())
|
||||
}()
|
||||
|
||||
utils.AssertEqual(t, nil, app.Listen(":4004"))
|
||||
}
|
||||
|
||||
// go test -run Test_App_BadRequest
|
||||
func Test_App_BadRequest(t *testing.T) {
|
||||
app := New(&Settings{
|
||||
app := New(Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
|
||||
app.Get("/bad-request", func(c *Ctx) {
|
||||
c.SendString("I should not be sent")
|
||||
app.Get("/bad-request", func(c *Ctx) error {
|
||||
return c.SendString("I should not be sent")
|
||||
})
|
||||
|
||||
go func() {
|
||||
|
@ -941,18 +964,18 @@ func Test_App_BadRequest(t *testing.T) {
|
|||
utils.AssertEqual(t, nil, app.Shutdown())
|
||||
}()
|
||||
|
||||
utils.AssertEqual(t, nil, app.Listen(4005))
|
||||
utils.AssertEqual(t, nil, app.Listen(":4005"))
|
||||
}
|
||||
|
||||
// go test -run Test_App_SmallReadBuffer
|
||||
func Test_App_SmallReadBuffer(t *testing.T) {
|
||||
app := New(&Settings{
|
||||
app := New(Config{
|
||||
ReadBufferSize: 1,
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
|
||||
app.Get("/small-read-buffer", func(c *Ctx) {
|
||||
c.SendString("I should not be sent")
|
||||
app.Get("/small-read-buffer", func(c *Ctx) error {
|
||||
return c.SendString("I should not be sent")
|
||||
})
|
||||
|
||||
go func() {
|
||||
|
@ -965,5 +988,5 @@ func Test_App_SmallReadBuffer(t *testing.T) {
|
|||
utils.AssertEqual(t, nil, app.Shutdown())
|
||||
}()
|
||||
|
||||
utils.AssertEqual(t, nil, app.Listen(4006))
|
||||
utils.AssertEqual(t, nil, app.Listen(":4006"))
|
||||
}
|
||||
|
|
1149
ctx_test.go
1149
ctx_test.go
File diff suppressed because it is too large
Load Diff
10
go.mod
10
go.mod
|
@ -1,12 +1,8 @@
|
|||
module github.com/gofiber/fiber
|
||||
module github.com/gofiber/fiber/v2
|
||||
|
||||
go 1.11
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/gofiber/utils v0.0.10
|
||||
github.com/gorilla/schema v1.1.0
|
||||
github.com/mattn/go-colorable v0.1.7
|
||||
github.com/mattn/go-isatty v0.0.12
|
||||
github.com/valyala/bytebufferpool v1.0.0
|
||||
github.com/valyala/fasthttp v1.16.0
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980
|
||||
)
|
||||
|
|
12
go.sum
12
go.sum
|
@ -1,15 +1,7 @@
|
|||
github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
|
||||
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/gofiber/utils v0.0.10 h1:3Mr7X7JdCUo7CWf/i5sajSaDmArEDtti8bM1JUVso2U=
|
||||
github.com/gofiber/utils v0.0.10/go.mod h1:9J5aHFUIjq0XfknT4+hdSMG6/jzfaAgCu4HEbWDeBlo=
|
||||
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg=
|
||||
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
|
||||
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.16.0 h1:9zAqOYLl8Tuy3E5R6ckzGDJ1g8+pw15oQp2iL9Jl6gQ=
|
||||
|
@ -18,12 +10,12 @@ github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6Jc
|
|||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
59
group.go
59
group.go
|
@ -15,38 +15,51 @@ type Group struct {
|
|||
prefix string
|
||||
}
|
||||
|
||||
// Use registers a middleware route.
|
||||
// Middleware matches requests beginning with the provided prefix.
|
||||
// Providing a prefix is optional, it defaults to "/".
|
||||
// Use registers a middleware route. that will match requests
|
||||
// that contain the provided prefix ( which is optional and defaults to "/" ).
|
||||
//
|
||||
// - group.Use(handler)
|
||||
// - group.Use("/api", handler)
|
||||
// - group.Use("/api", handler, handler)
|
||||
// app.Use(func(c *fiber.Ctx) error {
|
||||
// return c.Next()
|
||||
// })
|
||||
// app.Use("/api", func(c *fiber.Ctx) error {
|
||||
// return c.Next()
|
||||
// })
|
||||
// app.Use("/api", handler(), func(c *fiber.Ctx) error {
|
||||
// return c.Next()
|
||||
// })
|
||||
//
|
||||
// This method will match all HTTP verbs: GET, POST, PUT, HEAD etc...
|
||||
func (grp *Group) Use(args ...interface{}) Router {
|
||||
var path = ""
|
||||
var prefix = ""
|
||||
var handlers []Handler
|
||||
for i := 0; i < len(args); i++ {
|
||||
switch arg := args[i].(type) {
|
||||
case string:
|
||||
path = arg
|
||||
prefix = arg
|
||||
case Handler:
|
||||
handlers = append(handlers, arg)
|
||||
case *App:
|
||||
stack := arg.Stack()
|
||||
for m := range stack {
|
||||
for r := range stack[m] {
|
||||
route := grp.app.copyRoute(stack[m][r])
|
||||
grp.app.addRoute(route.Method, grp.app.addPrefixToRoute(prefix, route))
|
||||
}
|
||||
}
|
||||
return grp.app
|
||||
default:
|
||||
panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf(arg)))
|
||||
}
|
||||
}
|
||||
grp.app.register(methodUse, getGroupPath(grp.prefix, path), handlers...)
|
||||
grp.app.register(methodUse, getGroupPath(grp.prefix, prefix), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Get registers a route for GET methods that requests a representation
|
||||
// of the specified resource. Requests using GET should only retrieve data.
|
||||
func (grp *Group) Get(path string, handlers ...Handler) Router {
|
||||
route := grp.app.register(MethodGet, getGroupPath(grp.prefix, path), handlers...)
|
||||
// Add head route
|
||||
headRoute := route
|
||||
grp.app.addRoute(MethodHead, &headRoute)
|
||||
return grp
|
||||
path = getGroupPath(grp.prefix, path)
|
||||
return grp.app.Add(MethodHead, path, handlers...).Add(MethodGet, path, handlers...)
|
||||
}
|
||||
|
||||
// Head registers a route for HEAD methods that asks for a response identical
|
||||
|
@ -96,31 +109,31 @@ func (grp *Group) Patch(path string, handlers ...Handler) Router {
|
|||
return grp.Add(MethodPatch, path, handlers...)
|
||||
}
|
||||
|
||||
// Add ...
|
||||
// Add allows you to specify a HTTP method to register a route
|
||||
func (grp *Group) Add(method, path string, handlers ...Handler) Router {
|
||||
grp.app.register(method, getGroupPath(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
return grp.app.register(method, getGroupPath(grp.prefix, path), handlers...)
|
||||
}
|
||||
|
||||
// Static ...
|
||||
// Static will create a file server serving static files
|
||||
func (grp *Group) Static(prefix, root string, config ...Static) Router {
|
||||
grp.app.registerStatic(getGroupPath(grp.prefix, prefix), root, config...)
|
||||
return grp
|
||||
return grp.app.registerStatic(getGroupPath(grp.prefix, prefix), root, config...)
|
||||
}
|
||||
|
||||
// All ...
|
||||
// All will register the handler on all HTTP methods
|
||||
func (grp *Group) All(path string, handlers ...Handler) Router {
|
||||
for _, method := range intMethod {
|
||||
grp.Add(method, path, handlers...)
|
||||
_ = grp.Add(method, path, handlers...)
|
||||
}
|
||||
return grp
|
||||
}
|
||||
|
||||
// Group is used for Routes with common prefix to define a new sub-router with optional middleware.
|
||||
// api := app.Group("/api")
|
||||
// api.Get("/users", handler())
|
||||
func (grp *Group) Group(prefix string, handlers ...Handler) Router {
|
||||
prefix = getGroupPath(grp.prefix, prefix)
|
||||
if len(handlers) > 0 {
|
||||
grp.app.register(methodUse, prefix, handlers...)
|
||||
_ = grp.app.register(methodUse, prefix, handlers...)
|
||||
}
|
||||
return grp.app.Group(prefix)
|
||||
}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
## Fiber Core Middleware
|
||||
|
||||
- [middleware/compress](compress.md)
|
||||
Compression middleware for Fiber, it supports `deflate`, `gzip` and `brotli`.
|
||||
- [middleware/favicon](favicon.md)
|
||||
This middleware caches the favicon in memory to improve performance
|
||||
- [middleware/filesystem](filesystem.md)
|
||||
FileServer middleware to allow embedded http.FileSystem
|
||||
- [middleware/logger](logger.md)
|
||||
HTTP request/response logger for Fiber
|
||||
- [middleware/recover](recover.md)
|
||||
Recover middleware recovers from panics anywhere in the stack chain
|
||||
- [middleware/requestid](request_id.md)
|
||||
Adds an indentifier to the response using the `X-Request-ID` header
|
||||
- [middleware/timeout](timeout.md)
|
||||
Wrapper function which provides a handler with a timeout.
|
|
@ -0,0 +1,118 @@
|
|||
# Basic Authentication
|
||||
Basic Authentication middleware for [Fiber](https://github.com/gofiber/fiber) that provides an HTTP basic authentication. It calls the next handler for valid credentials and [401 Unauthorized](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401) or a custom response for missing or invalid credentials.
|
||||
|
||||
### Table of Contents
|
||||
- [Signatures](#signatures)
|
||||
- [Examples](#examples)
|
||||
- [Config](#config)
|
||||
- [Default Config](#default-config)
|
||||
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New(config Config) fiber.Handler
|
||||
```
|
||||
|
||||
### Examples
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/basicauth"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
// Provide a minimal config
|
||||
app.Use(basicauth.New(basicauth.Config{
|
||||
Users: map[string]string{
|
||||
"john": "doe",
|
||||
"admin": "123456",
|
||||
},
|
||||
}))
|
||||
|
||||
// Or extend your config for customization
|
||||
app.Use(basicauth.New(basicauth.Config{
|
||||
Users: map[string]string{
|
||||
"john": "doe",
|
||||
"admin": "123456",
|
||||
},
|
||||
Realm: "Forbidden",
|
||||
Authorizer: func(user, pass string) bool {
|
||||
if user == "john" && pass == "doe" {
|
||||
return true
|
||||
}
|
||||
if user == "admin" && pass == "123456" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
Unauthorized: func(c *fiber.Ctx) error {
|
||||
return c.SendFile("./unauthorized.html")
|
||||
},
|
||||
ContextUsername: "_user",
|
||||
ContextPassword: "_pass",
|
||||
}))
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Users defines the allowed credentials
|
||||
//
|
||||
// Required. Default: map[string]string{}
|
||||
Users map[string]string
|
||||
|
||||
// Realm is a string to define realm attribute of BasicAuth.
|
||||
// the realm identifies the system to authenticate against
|
||||
// and can be used by clients to save credentials
|
||||
//
|
||||
// Optional. Default: "Restricted".
|
||||
Realm string
|
||||
|
||||
// Authorizer defines a function you can pass
|
||||
// to check the credentials however you want.
|
||||
// It will be called with a username and password
|
||||
// and is expected to return true or false to indicate
|
||||
// that the credentials were approved or not.
|
||||
//
|
||||
// Optional. Default: nil.
|
||||
Authorizer func(string, string) bool
|
||||
|
||||
// Unauthorized defines the response body for unauthorized responses.
|
||||
// By default it will return with a 401 Unauthorized and the correct WWW-Auth header
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Unauthorized fiber.Handler
|
||||
|
||||
// ContextUser is the key to store the username in Locals
|
||||
//
|
||||
// Optional. Default: "username"
|
||||
ContextUsername string
|
||||
|
||||
// ContextPass is the key to store the password in Locals
|
||||
//
|
||||
// Optional. Default: "password"
|
||||
ContextPassword string
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Users: map[string]string{},
|
||||
Realm: "Restricted",
|
||||
Authorizer: nil,
|
||||
Unauthorized: nil,
|
||||
ContextUsername: "username",
|
||||
ContextPassword: "password",
|
||||
}
|
||||
```
|
|
@ -0,0 +1,142 @@
|
|||
package basicauth
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
)
|
||||
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Users defines the allowed credentials
|
||||
//
|
||||
// Required. Default: map[string]string{}
|
||||
Users map[string]string
|
||||
|
||||
// Realm is a string to define realm attribute of BasicAuth.
|
||||
// the realm identifies the system to authenticate against
|
||||
// and can be used by clients to save credentials
|
||||
//
|
||||
// Optional. Default: "Restricted".
|
||||
Realm string
|
||||
|
||||
// Authorizer defines a function you can pass
|
||||
// to check the credentials however you want.
|
||||
// It will be called with a username and password
|
||||
// and is expected to return true or false to indicate
|
||||
// that the credentials were approved or not.
|
||||
//
|
||||
// Optional. Default: nil.
|
||||
Authorizer func(string, string) bool
|
||||
|
||||
// Unauthorized defines the response body for unauthorized responses.
|
||||
// By default it will return with a 401 Unauthorized and the correct WWW-Auth header
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Unauthorized fiber.Handler
|
||||
|
||||
// ContextUser is the key to store the username in Locals
|
||||
//
|
||||
// Optional. Default: "username"
|
||||
ContextUsername string
|
||||
|
||||
// ContextPass is the key to store the password in Locals
|
||||
//
|
||||
// Optional. Default: "password"
|
||||
ContextPassword string
|
||||
}
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Users: map[string]string{},
|
||||
Realm: "Restricted",
|
||||
Authorizer: nil,
|
||||
Unauthorized: nil,
|
||||
ContextUsername: "username",
|
||||
ContextPassword: "password",
|
||||
}
|
||||
|
||||
// New creates a new middleware handler
|
||||
func New(config Config) fiber.Handler {
|
||||
cfg := config
|
||||
|
||||
// Set default values
|
||||
if cfg.Next == nil {
|
||||
cfg.Next = ConfigDefault.Next
|
||||
}
|
||||
if cfg.Users == nil {
|
||||
cfg.Users = ConfigDefault.Users
|
||||
}
|
||||
if cfg.Realm == "" {
|
||||
cfg.Realm = ConfigDefault.Realm
|
||||
}
|
||||
if cfg.Authorizer == nil {
|
||||
cfg.Authorizer = func(user, pass string) bool {
|
||||
user, exist := cfg.Users[user]
|
||||
if !exist {
|
||||
return false
|
||||
}
|
||||
return user == pass
|
||||
}
|
||||
}
|
||||
if cfg.Unauthorized == nil {
|
||||
cfg.Unauthorized = func(c *fiber.Ctx) error {
|
||||
c.Set(fiber.HeaderWWWAuthenticate, "basic realm="+cfg.Realm)
|
||||
return c.SendStatus(fiber.StatusUnauthorized)
|
||||
}
|
||||
}
|
||||
if cfg.ContextUsername == "" {
|
||||
cfg.ContextUsername = ConfigDefault.ContextUsername
|
||||
}
|
||||
if cfg.ContextPassword == "" {
|
||||
cfg.ContextPassword = ConfigDefault.ContextPassword
|
||||
}
|
||||
|
||||
// Return new handler
|
||||
return func(c *fiber.Ctx) error {
|
||||
// Don't execute middleware if Next returns true
|
||||
if cfg.Next != nil && cfg.Next(c) {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Get authorization header
|
||||
auth := c.Get(fiber.HeaderAuthorization)
|
||||
|
||||
// Check if header is valid
|
||||
if len(auth) > 6 && strings.ToLower(auth[:5]) == "basic" {
|
||||
|
||||
// Try to decode
|
||||
if raw, err := base64.StdEncoding.DecodeString(auth[6:]); err == nil {
|
||||
|
||||
// Convert to string
|
||||
cred := utils.GetString(raw)
|
||||
|
||||
// Find semicolumn
|
||||
for i := 0; i < len(cred); i++ {
|
||||
if cred[i] == ':' {
|
||||
// Split into user & pass
|
||||
user := cred[:i]
|
||||
pass := cred[i+1:]
|
||||
|
||||
// If exist & match in Users, we let him pass
|
||||
if cfg.Authorizer(user, pass) {
|
||||
c.Locals(cfg.ContextUsername, user)
|
||||
c.Locals(cfg.ContextPassword, pass)
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Authentication failed
|
||||
return cfg.Unauthorized(c)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package basicauth
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
b64 "encoding/base64"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
)
|
||||
|
||||
func Test_Middleware_BasicAuth(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
cfg := Config{
|
||||
Users: map[string]string{
|
||||
"john": "doe",
|
||||
"admin": "123456",
|
||||
},
|
||||
}
|
||||
|
||||
app.Use(New(cfg))
|
||||
|
||||
app.Get("/testauth", func(c *fiber.Ctx) error {
|
||||
username := c.Locals("username").(string)
|
||||
password := c.Locals("password").(string)
|
||||
|
||||
return c.SendString(username + password)
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
url string
|
||||
statusCode int
|
||||
username string
|
||||
password string
|
||||
}{
|
||||
{
|
||||
url: "/testauth",
|
||||
statusCode: 200,
|
||||
username: "john",
|
||||
password: "doe",
|
||||
},
|
||||
{
|
||||
url: "/testauth",
|
||||
statusCode: 200,
|
||||
username: "admin",
|
||||
password: "123456",
|
||||
},
|
||||
{
|
||||
url: "/testauth",
|
||||
statusCode: 401,
|
||||
username: "ee",
|
||||
password: "123456",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
// Base64 encode credentials for http auth header
|
||||
creds := b64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", tt.username, tt.password)))
|
||||
|
||||
req := httptest.NewRequest("GET", "/testauth", nil)
|
||||
req.Header.Add("Authorization", "Basic "+creds)
|
||||
resp, err := app.Test(req)
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, tt.statusCode, resp.StatusCode)
|
||||
|
||||
// Only check body if statusCode is 200
|
||||
if tt.statusCode == 200 {
|
||||
utils.AssertEqual(t, fmt.Sprintf("%s%s", tt.username, tt.password), string(body))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
fiber "github.com/gofiber/fiber"
|
||||
fasthttp "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// CompressConfig defines the config for Compress middleware.
|
||||
type CompressConfig struct {
|
||||
// Next defines a function to skip this middleware if returned true.
|
||||
Next func(ctx *fiber.Ctx) bool
|
||||
// Compression level for brotli, gzip and deflate
|
||||
Level int
|
||||
}
|
||||
|
||||
// Compression levels determine the compression complexity
|
||||
const (
|
||||
CompressLevelDisabled = -1
|
||||
CompressLevelDefault = 0
|
||||
CompressLevelBestSpeed = 1
|
||||
CompressLevelBestCompression = 2
|
||||
)
|
||||
|
||||
// CompressConfigDefault is the default config
|
||||
var CompressConfigDefault = CompressConfig{
|
||||
Next: nil,
|
||||
Level: CompressLevelDefault,
|
||||
}
|
||||
|
||||
var compressHandlers = map[int]fasthttp.RequestHandler{
|
||||
CompressLevelDisabled: fasthttp.CompressHandlerBrotliLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressBrotliNoCompression, fasthttp.CompressNoCompression),
|
||||
CompressLevelDefault: fasthttp.CompressHandlerBrotliLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressBrotliDefaultCompression, fasthttp.CompressDefaultCompression),
|
||||
CompressLevelBestSpeed: fasthttp.CompressHandlerBrotliLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressBrotliBestSpeed, fasthttp.CompressBestSpeed),
|
||||
CompressLevelBestCompression: fasthttp.CompressHandlerBrotliLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressBrotliBestCompression, fasthttp.CompressBestCompression),
|
||||
}
|
||||
|
||||
/*
|
||||
Compress allows the following config arguments in any order:
|
||||
- Compress()
|
||||
- Compress(next func(*fiber.Ctx) bool)
|
||||
- Compress(level int)
|
||||
- Compress(config CompressConfig)
|
||||
*/
|
||||
func Compress(options ...interface{}) fiber.Handler {
|
||||
// Create default config
|
||||
var config = CompressConfigDefault
|
||||
// Assert options if provided to adjust the config
|
||||
if len(options) > 0 {
|
||||
for i := range options {
|
||||
switch opt := options[i].(type) {
|
||||
case func(*fiber.Ctx) bool:
|
||||
config.Next = opt
|
||||
case int:
|
||||
config.Level = opt
|
||||
case CompressConfig:
|
||||
config = opt
|
||||
default:
|
||||
panic("Compress: the following option types are allowed: int, func(*fiber.Ctx) bool, CompressConfig")
|
||||
}
|
||||
}
|
||||
}
|
||||
// Return CompressWithConfig
|
||||
return compress(config)
|
||||
}
|
||||
|
||||
func compress(config CompressConfig) fiber.Handler {
|
||||
// Init middleware settings
|
||||
compressHandler, ok := compressHandlers[config.Level]
|
||||
if !ok {
|
||||
// Use default level if provided level is invalid
|
||||
compressHandler = compressHandlers[CompressLevelDefault]
|
||||
}
|
||||
|
||||
// Return handler
|
||||
return func(c *fiber.Ctx) {
|
||||
// Don't execute the middleware if Next returns false
|
||||
if config.Next != nil && config.Next(c) {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
// Middleware logic...
|
||||
c.Next()
|
||||
// Compress response
|
||||
compressHandler(c.Fasthttp)
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
# Compress
|
||||
Compression middleware for Fiber with support for `deflate`, `gzip` and `brotli`.
|
||||
|
||||
### Example
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
// Default compression config
|
||||
app.Use(middleware.Compress())
|
||||
|
||||
// Provide a custom compression level
|
||||
app.Use(middleware.Compress(middleware.CompressLevelBestSpeed))
|
||||
|
||||
// Provide a full CompressConfig
|
||||
app.Use(middleware.Compress(middleware.CompressConfig{
|
||||
Next: func(c *fiber.Ctx) bool {
|
||||
return c.Path() == "/ignore"
|
||||
},
|
||||
Level: CompressLevelDefault,
|
||||
})
|
||||
```
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func Compress(options ...interface{}) fiber.Handler {}
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
type CompressConfig struct {
|
||||
// Next defines a function to skip this middleware.
|
||||
// Default: nil
|
||||
Next func(*fiber.Ctx) bool
|
||||
|
||||
// Compression level for brotli, gzip and deflate
|
||||
// Default: CompressLevelDefault
|
||||
Level int
|
||||
}
|
||||
```
|
||||
### Compression Levels
|
||||
```go
|
||||
const (
|
||||
CompressLevelDisabled = -1
|
||||
CompressLevelDefault = 0
|
||||
CompressLevelBestSpeed = 1
|
||||
CompressLevelBestCompression = 2
|
||||
)
|
||||
```
|
|
@ -0,0 +1,88 @@
|
|||
# Compress
|
||||
Compression middleware for [Fiber](https://github.com/gofiber/fiber) that will compress the response using `gzip`, `deflate` and `brotli` compression depending on the [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
|
||||
|
||||
- [Signatures](#signatures)
|
||||
- [Examples](#examples)
|
||||
- [Config](#config)
|
||||
- [Default Config](#default-config)
|
||||
- [Constants](#config)
|
||||
|
||||
<!--
|
||||
### Config
|
||||
|
||||
| Signature | Description | Required | Default |
|
||||
| :--- | :--- | ---: | ---: |
|
||||
| `Next func(c *fiber.Ctx) bool` | Defines a function to skip this middleware when returned true. | `✘` | `nil` |
|
||||
| `Level int` | Determines the compression algoritm: `-1`, `0`, `1` or `2` | `✔` | `0` | -->
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New(config ...Config) fiber.Handler
|
||||
```
|
||||
|
||||
### Example
|
||||
Import the compress package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/compress"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
// Default middleware config
|
||||
app.Use(compress.New())
|
||||
|
||||
// Provide a custom compression level
|
||||
app.Use(compress.New(compress.Config{
|
||||
Level: compress.LevelBestSpeed, // 1
|
||||
}))
|
||||
|
||||
// Skip middleware for specific routes
|
||||
app.Use(compress.New(compress.Config{
|
||||
Next: func(c *fiber.Ctx) bool {
|
||||
return c.Path() == "/dont_compress"
|
||||
},
|
||||
Level: compress.LevelBestSpeed, // 1
|
||||
}))
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// CompressLevel determines the compression algoritm
|
||||
//
|
||||
// Optional. Default: LevelDefault
|
||||
// LevelDisabled: -1
|
||||
// LevelDefault: 0
|
||||
// LevelBestSpeed: 1
|
||||
// LevelBestCompression: 2
|
||||
Level int
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Level: LevelDefault,
|
||||
}
|
||||
```
|
||||
|
||||
### Constants
|
||||
```go
|
||||
// Compression levels
|
||||
const (
|
||||
LevelDisabled = -1
|
||||
LevelDefault = 0
|
||||
LevelBestSpeed = 1
|
||||
LevelBestCompression = 2
|
||||
)
|
||||
```
|
|
@ -0,0 +1,99 @@
|
|||
package compress
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// CompressLevel determines the compression algoritm
|
||||
//
|
||||
// Optional. Default: LevelDefault
|
||||
// LevelDisabled: -1
|
||||
// LevelDefault: 0
|
||||
// LevelBestSpeed: 1
|
||||
// LevelBestCompression: 2
|
||||
Level int
|
||||
}
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Level: LevelDefault,
|
||||
}
|
||||
|
||||
// Compression levels
|
||||
const (
|
||||
LevelDisabled = -1
|
||||
LevelDefault = 0
|
||||
LevelBestSpeed = 1
|
||||
LevelBestCompression = 2
|
||||
)
|
||||
|
||||
// New creates a new middleware handler
|
||||
func New(config ...Config) fiber.Handler {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
|
||||
// Set default values
|
||||
if cfg.Next == nil {
|
||||
cfg.Next = ConfigDefault.Next
|
||||
}
|
||||
if cfg.Level < -1 || cfg.Level > 2 {
|
||||
cfg.Level = ConfigDefault.Level
|
||||
}
|
||||
}
|
||||
|
||||
// Setup request handlers
|
||||
var (
|
||||
fctx = func(c *fasthttp.RequestCtx) {}
|
||||
compressor fasthttp.RequestHandler
|
||||
)
|
||||
|
||||
// Setup compression algorithm
|
||||
switch cfg.Level {
|
||||
case 0:
|
||||
// LevelDefault
|
||||
compressor = fasthttp.CompressHandlerBrotliLevel(fctx, fasthttp.CompressBrotliDefaultCompression, fasthttp.CompressDefaultCompression)
|
||||
case 1:
|
||||
// LevelBestSpeed
|
||||
compressor = fasthttp.CompressHandlerBrotliLevel(fctx, fasthttp.CompressBrotliBestSpeed, fasthttp.CompressBestSpeed)
|
||||
case 2:
|
||||
// LevelBestCompression
|
||||
compressor = fasthttp.CompressHandlerBrotliLevel(fctx, fasthttp.CompressBrotliBestCompression, fasthttp.CompressBestCompression)
|
||||
default:
|
||||
// LevelDisabled
|
||||
return func(c *fiber.Ctx) error {
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// Return new handler
|
||||
return func(c *fiber.Ctx) error {
|
||||
// Don't execute middleware if Next returns true
|
||||
if cfg.Next != nil && cfg.Next(c) {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Continue stack
|
||||
if err := c.Next(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Compress response
|
||||
compressor(c.Context())
|
||||
|
||||
// Return from handler
|
||||
return nil
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package compress
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
)
|
||||
|
||||
var filedata []byte
|
||||
|
||||
func init() {
|
||||
dat, err := ioutil.ReadFile("../../.github/README.md")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
filedata = dat
|
||||
}
|
||||
|
||||
// go test -run Test_Compress
|
||||
func Test_Compress_Gzip(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
|
||||
return c.Send(filedata)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Set("Accept-Encoding", "gzip")
|
||||
|
||||
resp, err := app.Test(req)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, "gzip", resp.Header.Get(fiber.HeaderContentEncoding))
|
||||
|
||||
// Validate the file size is shrinked
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
utils.AssertEqual(t, nil, err)
|
||||
}
|
||||
utils.AssertEqual(t, true, len(body) < len(filedata))
|
||||
}
|
||||
|
||||
func Test_Compress_Deflate(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.Send(filedata)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Set("Accept-Encoding", "deflate")
|
||||
|
||||
resp, err := app.Test(req)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, "deflate", resp.Header.Get(fiber.HeaderContentEncoding))
|
||||
|
||||
// Validate the file size is shrinked
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
utils.AssertEqual(t, nil, err)
|
||||
}
|
||||
utils.AssertEqual(t, true, len(body) < len(filedata))
|
||||
}
|
||||
|
||||
func Test_Compress_Brotli(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.Send(filedata)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Set("Accept-Encoding", "br")
|
||||
|
||||
resp, err := app.Test(req)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, "br", resp.Header.Get(fiber.HeaderContentEncoding))
|
||||
|
||||
// Validate the file size is shrinked
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
utils.AssertEqual(t, nil, err)
|
||||
}
|
||||
utils.AssertEqual(t, true, len(body) < len(filedata))
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/utils"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// go test -run Test_Middleware_Compress
|
||||
func Test_Middleware_Compress(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(Compress())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.SendFile(compressFilePath(CompressLevelDefault), true)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Set(fiber.HeaderAcceptEncoding, "gzip")
|
||||
|
||||
resp, err := app.Test(req)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, "gzip", resp.Header.Get(fiber.HeaderContentEncoding))
|
||||
utils.AssertEqual(t, fiber.MIMETextPlainCharsetUTF8, resp.Header.Get(fiber.HeaderContentType))
|
||||
os.Remove(compressFilePath(CompressLevelDefault, true))
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_Compress_Config
|
||||
func Test_Middleware_Compress_Config(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(Compress(CompressConfig{
|
||||
Level: CompressLevelDefault,
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.SendFile(compressFilePath(CompressLevelDefault), true)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Set(fiber.HeaderAcceptEncoding, "gzip")
|
||||
|
||||
resp, err := app.Test(req)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, 200, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, "gzip", resp.Header.Get(fiber.HeaderContentEncoding))
|
||||
utils.AssertEqual(t, fiber.MIMETextPlainCharsetUTF8, resp.Header.Get(fiber.HeaderContentType))
|
||||
os.Remove(compressFilePath(CompressLevelDefault, true))
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_Compress_With_Config
|
||||
func Test_Middleware_Compress_With_Config(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(Compress(CompressConfig{}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.SendFile(compressFilePath(CompressLevelDefault), true)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Set(fiber.HeaderAcceptEncoding, "gzip")
|
||||
|
||||
resp, err := app.Test(req)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, "gzip", resp.Header.Get(fiber.HeaderContentEncoding))
|
||||
utils.AssertEqual(t, fiber.MIMETextPlainCharsetUTF8, resp.Header.Get(fiber.HeaderContentType))
|
||||
os.Remove(compressFilePath(CompressLevelDefault, true))
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_Compress_Level
|
||||
func Test_Middleware_Compress_Level(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
levels := []int{
|
||||
CompressLevelDisabled,
|
||||
CompressLevelDefault,
|
||||
CompressLevelBestSpeed,
|
||||
CompressLevelBestCompression,
|
||||
}
|
||||
|
||||
app := fiber.New()
|
||||
for _, level := range levels {
|
||||
app.Get("/:level", Compress(level), func(c *fiber.Ctx) {
|
||||
c.SendFile(compressFilePath(c.Params("level")), true)
|
||||
})
|
||||
}
|
||||
|
||||
for _, level := range levels {
|
||||
name := strconv.FormatInt(int64(level), 10)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
target := fmt.Sprintf("/%d", level)
|
||||
req := httptest.NewRequest("GET", target, nil)
|
||||
req.Header.Set(fiber.HeaderAcceptEncoding, "br")
|
||||
|
||||
resp, err := app.Test(req, 3000)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, "br", resp.Header.Get(fiber.HeaderContentEncoding))
|
||||
utils.AssertEqual(t, fiber.MIMETextPlainCharsetUTF8, resp.Header.Get(fiber.HeaderContentType))
|
||||
|
||||
os.Remove(compressFilePath(level, true))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_Compress_Skip
|
||||
func Test_Middleware_Compress_Skip(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(Compress(func(c *fiber.Ctx) bool { return true }))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.SendFile(compressFilePath(CompressLevelDefault), true)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Set(fiber.HeaderAcceptEncoding, "br")
|
||||
|
||||
resp, err := app.Test(req, 3000)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, "", resp.Header.Get(fiber.HeaderContentEncoding))
|
||||
utils.AssertEqual(t, fiber.MIMETextPlainCharsetUTF8, resp.Header.Get(fiber.HeaderContentType))
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_Compress_Panic
|
||||
func Test_Middleware_Compress_Panic(t *testing.T) {
|
||||
defer func() {
|
||||
utils.AssertEqual(t,
|
||||
"Compress: the following option types are allowed: int, func(*fiber.Ctx) bool, CompressConfig",
|
||||
fmt.Sprintf("%s", recover()))
|
||||
}()
|
||||
|
||||
Compress("invalid")
|
||||
}
|
||||
|
||||
// go test -v ./... -run=^$ -bench=Benchmark_Middleware_Compress -benchmem -count=4
|
||||
func Benchmark_Middleware_Compress(b *testing.B) {
|
||||
app := fiber.New()
|
||||
app.Use(Compress())
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.SendFile(compressFilePath(CompressLevelDefault), true)
|
||||
})
|
||||
handler := app.Handler()
|
||||
|
||||
c := &fasthttp.RequestCtx{}
|
||||
c.Request.SetRequestURI("/")
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for n := 0; n < b.N; n++ {
|
||||
handler(c)
|
||||
}
|
||||
}
|
||||
|
||||
func compressFilePath(level interface{}, gz ...bool) string {
|
||||
filePath := fmt.Sprintf("./testdata/compress_level_%v.txt", level)
|
||||
if len(gz) > 0 && gz[0] {
|
||||
filePath += ".fiber.gz"
|
||||
}
|
||||
return filePath
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
# Cross-Origin Resource Sharing (CORS)
|
||||
CORS middleware for [Fiber](https://github.com/gofiber/fiber) that that can be used to enable [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) with various options.
|
||||
|
||||
### Table of Contents
|
||||
- [Signatures](#signatures)
|
||||
- [Examples](#examples)
|
||||
- [Config](#config)
|
||||
- [Default Config](#default-config)
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New(config ...Config) fiber.Handler
|
||||
```
|
||||
|
||||
### Examples
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/cors"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
// Default config
|
||||
app.Use(cors.New())
|
||||
|
||||
// Or extend your config for customization
|
||||
app.Use(cors.New(cors.Config{
|
||||
AllowOrigins: "https://gofiber.io, https://gofiber.net",
|
||||
AllowHeader: "Origin, Content-Type, Accept",
|
||||
}))
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// AllowOrigin defines a list of origins that may access the resource.
|
||||
//
|
||||
// Optional. Default value "*"
|
||||
AllowOrigins string
|
||||
|
||||
// AllowMethods defines a list methods allowed when accessing the resource.
|
||||
// This is used in response to a preflight request.
|
||||
//
|
||||
// Optional. Default value "GET,POST,HEAD,PUT,DELETE,PATCH"
|
||||
AllowMethods string
|
||||
|
||||
// AllowHeaders defines a list of request headers that can be used when
|
||||
// making the actual request. This is in response to a preflight request.
|
||||
//
|
||||
// Optional. Default value "".
|
||||
AllowHeaders string
|
||||
|
||||
// AllowCredentials indicates whether or not the response to the request
|
||||
// can be exposed when the credentials flag is true. When used as part of
|
||||
// a response to a preflight request, this indicates whether or not the
|
||||
// actual request can be made using credentials.
|
||||
//
|
||||
// Optional. Default value false.
|
||||
AllowCredentials bool
|
||||
|
||||
// ExposeHeaders defines a whitelist headers that clients are allowed to
|
||||
// access.
|
||||
//
|
||||
// Optional. Default value "".
|
||||
ExposeHeaders string
|
||||
|
||||
// MaxAge indicates how long (in seconds) the results of a preflight request
|
||||
// can be cached.
|
||||
//
|
||||
// Optional. Default value 0.
|
||||
MaxAge int
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
AllowOrigins: "*",
|
||||
AllowMethods: "GET,POST,HEAD,PUT,DELETE,PATCH",
|
||||
AllowHeaders: "",
|
||||
AllowCredentials: false,
|
||||
ExposeHeaders: "",
|
||||
MaxAge: 0,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,177 @@
|
|||
package cors
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// AllowOrigin defines a list of origins that may access the resource.
|
||||
//
|
||||
// Optional. Default value "*"
|
||||
AllowOrigins string
|
||||
|
||||
// AllowMethods defines a list methods allowed when accessing the resource.
|
||||
// This is used in response to a preflight request.
|
||||
//
|
||||
// Optional. Default value "GET,POST,HEAD,PUT,DELETE,PATCH"
|
||||
AllowMethods string
|
||||
|
||||
// AllowHeaders defines a list of request headers that can be used when
|
||||
// making the actual request. This is in response to a preflight request.
|
||||
//
|
||||
// Optional. Default value "".
|
||||
AllowHeaders string
|
||||
|
||||
// AllowCredentials indicates whether or not the response to the request
|
||||
// can be exposed when the credentials flag is true. When used as part of
|
||||
// a response to a preflight request, this indicates whether or not the
|
||||
// actual request can be made using credentials.
|
||||
//
|
||||
// Optional. Default value false.
|
||||
AllowCredentials bool
|
||||
|
||||
// ExposeHeaders defines a whitelist headers that clients are allowed to
|
||||
// access.
|
||||
//
|
||||
// Optional. Default value "".
|
||||
ExposeHeaders string
|
||||
|
||||
// MaxAge indicates how long (in seconds) the results of a preflight request
|
||||
// can be cached.
|
||||
//
|
||||
// Optional. Default value 0.
|
||||
MaxAge int
|
||||
}
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
AllowOrigins: "*",
|
||||
AllowMethods: strings.Join([]string{
|
||||
fiber.MethodGet,
|
||||
fiber.MethodPost,
|
||||
fiber.MethodHead,
|
||||
fiber.MethodPut,
|
||||
fiber.MethodDelete,
|
||||
fiber.MethodPatch,
|
||||
}, ","),
|
||||
AllowHeaders: "",
|
||||
AllowCredentials: false,
|
||||
ExposeHeaders: "",
|
||||
MaxAge: 0,
|
||||
}
|
||||
|
||||
// New creates a new middleware handler
|
||||
func New(config ...Config) fiber.Handler {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
|
||||
// Set default values
|
||||
if cfg.Next == nil {
|
||||
cfg.Next = ConfigDefault.Next
|
||||
}
|
||||
if cfg.AllowOrigins == "" {
|
||||
cfg.AllowOrigins = ConfigDefault.AllowOrigins
|
||||
}
|
||||
if cfg.AllowMethods == "" {
|
||||
cfg.AllowMethods = ConfigDefault.AllowMethods
|
||||
}
|
||||
}
|
||||
|
||||
// Convert string to slice
|
||||
allowOrigins := strings.Split(strings.Replace(cfg.AllowOrigins, " ", "", -1), ",")
|
||||
|
||||
// Strip white spaces
|
||||
allowMethods := strings.Replace(cfg.AllowMethods, " ", "", -1)
|
||||
allowHeaders := strings.Replace(cfg.AllowHeaders, " ", "", -1)
|
||||
exposeHeaders := strings.Replace(cfg.ExposeHeaders, " ", "", -1)
|
||||
|
||||
// Convert int to string
|
||||
maxAge := strconv.Itoa(cfg.MaxAge)
|
||||
|
||||
// Return new handler
|
||||
return func(c *fiber.Ctx) error {
|
||||
// Don't execute middleware if Next returns true
|
||||
if cfg.Next != nil && cfg.Next(c) {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Get origin header
|
||||
origin := c.Get(fiber.HeaderOrigin)
|
||||
allowOrigin := ""
|
||||
|
||||
// Check allowed origins
|
||||
for _, o := range allowOrigins {
|
||||
if o == "*" && cfg.AllowCredentials {
|
||||
allowOrigin = origin
|
||||
break
|
||||
}
|
||||
if o == "*" || o == origin {
|
||||
allowOrigin = o
|
||||
break
|
||||
}
|
||||
if matchSubdomain(origin, o) {
|
||||
allowOrigin = origin
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Simple request
|
||||
if c.Method() != http.MethodOptions {
|
||||
c.Vary(fiber.HeaderOrigin)
|
||||
c.Set(fiber.HeaderAccessControlAllowOrigin, allowOrigin)
|
||||
|
||||
if cfg.AllowCredentials {
|
||||
c.Set(fiber.HeaderAccessControlAllowCredentials, "true")
|
||||
}
|
||||
if exposeHeaders != "" {
|
||||
c.Set(fiber.HeaderAccessControlExposeHeaders, exposeHeaders)
|
||||
}
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Preflight request
|
||||
c.Vary(fiber.HeaderOrigin)
|
||||
c.Vary(fiber.HeaderAccessControlRequestMethod)
|
||||
c.Vary(fiber.HeaderAccessControlRequestHeaders)
|
||||
c.Set(fiber.HeaderAccessControlAllowOrigin, allowOrigin)
|
||||
c.Set(fiber.HeaderAccessControlAllowMethods, allowMethods)
|
||||
|
||||
// Set Allow-Credentials if set to true
|
||||
if cfg.AllowCredentials {
|
||||
c.Set(fiber.HeaderAccessControlAllowCredentials, "true")
|
||||
}
|
||||
|
||||
// Set Allow-Headers if not empty
|
||||
if allowHeaders != "" {
|
||||
c.Set(fiber.HeaderAccessControlAllowHeaders, allowHeaders)
|
||||
} else {
|
||||
h := c.Get(fiber.HeaderAccessControlRequestHeaders)
|
||||
if h != "" {
|
||||
c.Set(fiber.HeaderAccessControlAllowHeaders, h)
|
||||
}
|
||||
}
|
||||
|
||||
// Set MaxAge is set
|
||||
if cfg.MaxAge > 0 {
|
||||
c.Set(fiber.HeaderAccessControlMaxAge, maxAge)
|
||||
}
|
||||
|
||||
// Send 204 No Content
|
||||
return c.SendStatus(fiber.StatusNoContent)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
package cors
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
func Test_CORS_Defaults(t *testing.T) {
|
||||
app := fiber.New()
|
||||
app.Use(New())
|
||||
|
||||
h := app.Handler()
|
||||
|
||||
// Test default GET response headers
|
||||
ctx := &fasthttp.RequestCtx{}
|
||||
ctx.Request.Header.SetMethod(fiber.MethodGet)
|
||||
h(ctx)
|
||||
|
||||
utils.AssertEqual(t, "*", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowOrigin)))
|
||||
utils.AssertEqual(t, "", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowCredentials)))
|
||||
utils.AssertEqual(t, "", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlExposeHeaders)))
|
||||
|
||||
// Test default OPTIONS (preflight) response headers
|
||||
ctx = &fasthttp.RequestCtx{}
|
||||
ctx.Request.Header.SetMethod(fiber.MethodOptions)
|
||||
h(ctx)
|
||||
|
||||
utils.AssertEqual(t, "GET,POST,HEAD,PUT,DELETE,PATCH", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowMethods)))
|
||||
utils.AssertEqual(t, "", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowHeaders)))
|
||||
utils.AssertEqual(t, "", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlMaxAge)))
|
||||
}
|
||||
|
||||
// go test -run -v Test_CORS_Wildcard
|
||||
func Test_CORS_Wildcard(t *testing.T) {
|
||||
// New fiber instance
|
||||
app := fiber.New()
|
||||
// Get handler pointer
|
||||
handler := app.Handler()
|
||||
|
||||
// OPTIONS (preflight) response headers when AllowOrigins is *
|
||||
app.Use(New(Config{AllowOrigins: "*", AllowCredentials: true, MaxAge: 3600}))
|
||||
|
||||
// Make request
|
||||
ctx := &fasthttp.RequestCtx{}
|
||||
ctx.Request.SetRequestURI("/")
|
||||
ctx.Request.Header.Set(fiber.HeaderOrigin, "localhost")
|
||||
ctx.Request.Header.SetMethod(fiber.MethodOptions)
|
||||
|
||||
// Perform request
|
||||
handler(ctx)
|
||||
|
||||
// Check result
|
||||
utils.AssertEqual(t, "localhost", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowOrigin)))
|
||||
utils.AssertEqual(t, "true", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowCredentials)))
|
||||
utils.AssertEqual(t, "3600", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlMaxAge)))
|
||||
}
|
||||
|
||||
// go test -run -v Test_CORS_Subdomain
|
||||
func Test_CORS_Subdomain(t *testing.T) {
|
||||
// New fiber instance
|
||||
app := fiber.New()
|
||||
// Get handler pointer
|
||||
handler := app.Handler()
|
||||
|
||||
// OPTIONS (preflight) response headers when AllowOrigins is set to a subdomain
|
||||
app.Use("/", New(Config{AllowOrigins: "http://*.example.com"}))
|
||||
|
||||
// Make request with disallowed origin
|
||||
ctx := &fasthttp.RequestCtx{}
|
||||
ctx.Request.SetRequestURI("/")
|
||||
ctx.Request.Header.SetMethod(fiber.MethodOptions)
|
||||
ctx.Request.Header.Set(fiber.HeaderOrigin, "http://google.com")
|
||||
|
||||
// Perform request
|
||||
handler(ctx)
|
||||
|
||||
// Allow-Origin header should be "" because http://google.com does not satisfy http://*.example.com
|
||||
utils.AssertEqual(t, "", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowOrigin)))
|
||||
|
||||
ctx.Request.Reset()
|
||||
ctx.Response.Reset()
|
||||
|
||||
// Make request with allowed origin
|
||||
ctx.Request.SetRequestURI("/")
|
||||
ctx.Request.Header.SetMethod(fiber.MethodOptions)
|
||||
ctx.Request.Header.Set(fiber.HeaderOrigin, "http://test.example.com")
|
||||
|
||||
handler(ctx)
|
||||
|
||||
utils.AssertEqual(t, "http://test.example.com", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowOrigin)))
|
||||
}
|
||||
|
||||
func Test_CORS_AllowOriginScheme(t *testing.T) {
|
||||
tests := []struct {
|
||||
reqOrigin, pattern string
|
||||
shouldAllowOrigin bool
|
||||
}{
|
||||
{
|
||||
pattern: "http://example.com",
|
||||
reqOrigin: "http://example.com",
|
||||
shouldAllowOrigin: true,
|
||||
},
|
||||
{
|
||||
pattern: "https://example.com",
|
||||
reqOrigin: "https://example.com",
|
||||
shouldAllowOrigin: true,
|
||||
},
|
||||
{
|
||||
pattern: "http://example.com",
|
||||
reqOrigin: "https://example.com",
|
||||
shouldAllowOrigin: false,
|
||||
},
|
||||
{
|
||||
pattern: "http://*.example.com",
|
||||
reqOrigin: "http://aaa.example.com",
|
||||
shouldAllowOrigin: true,
|
||||
},
|
||||
{
|
||||
pattern: "http://*.example.com",
|
||||
reqOrigin: "http://bbb.aaa.example.com",
|
||||
shouldAllowOrigin: true,
|
||||
},
|
||||
{
|
||||
pattern: "http://*.aaa.example.com",
|
||||
reqOrigin: "http://bbb.aaa.example.com",
|
||||
shouldAllowOrigin: true,
|
||||
},
|
||||
{
|
||||
pattern: "http://*.example.com:8080",
|
||||
reqOrigin: "http://aaa.example.com:8080",
|
||||
shouldAllowOrigin: true,
|
||||
},
|
||||
{
|
||||
pattern: "http://example.com",
|
||||
reqOrigin: "http://gofiber.com",
|
||||
shouldAllowOrigin: false,
|
||||
},
|
||||
{
|
||||
pattern: "http://*.aaa.example.com",
|
||||
reqOrigin: "http://ccc.bbb.example.com",
|
||||
shouldAllowOrigin: false,
|
||||
},
|
||||
{
|
||||
pattern: "http://*.example.com",
|
||||
reqOrigin: `http://1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890\
|
||||
.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890\
|
||||
.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890\
|
||||
.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.1234567890.example.com`,
|
||||
shouldAllowOrigin: false,
|
||||
},
|
||||
{
|
||||
pattern: "http://example.com",
|
||||
reqOrigin: "http://ccc.bbb.example.com",
|
||||
shouldAllowOrigin: false,
|
||||
},
|
||||
{
|
||||
pattern: "https://*--aaa.bbb.com",
|
||||
reqOrigin: "https://prod-preview--aaa.bbb.com",
|
||||
shouldAllowOrigin: false,
|
||||
},
|
||||
{
|
||||
pattern: "http://*.example.com",
|
||||
reqOrigin: "http://ccc.bbb.example.com",
|
||||
shouldAllowOrigin: true,
|
||||
},
|
||||
{
|
||||
pattern: "http://foo.[a-z]*.example.com",
|
||||
reqOrigin: "http://ccc.bbb.example.com",
|
||||
shouldAllowOrigin: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
app := fiber.New()
|
||||
app.Use("/", New(Config{AllowOrigins: tt.pattern}))
|
||||
|
||||
handler := app.Handler()
|
||||
|
||||
ctx := &fasthttp.RequestCtx{}
|
||||
ctx.Request.SetRequestURI("/")
|
||||
ctx.Request.Header.SetMethod(fiber.MethodOptions)
|
||||
ctx.Request.Header.Set(fiber.HeaderOrigin, tt.reqOrigin)
|
||||
|
||||
handler(ctx)
|
||||
|
||||
if tt.shouldAllowOrigin {
|
||||
utils.AssertEqual(t, tt.reqOrigin, string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowOrigin)))
|
||||
} else {
|
||||
utils.AssertEqual(t, "", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowOrigin)))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package cors
|
||||
|
||||
import "strings"
|
||||
|
||||
func matchScheme(domain, pattern string) bool {
|
||||
didx := strings.Index(domain, ":")
|
||||
pidx := strings.Index(pattern, ":")
|
||||
return didx != -1 && pidx != -1 && domain[:didx] == pattern[:pidx]
|
||||
}
|
||||
|
||||
// matchSubdomain compares authority with wildcard
|
||||
func matchSubdomain(domain, pattern string) bool {
|
||||
if !matchScheme(domain, pattern) {
|
||||
return false
|
||||
}
|
||||
didx := strings.Index(domain, "://")
|
||||
pidx := strings.Index(pattern, "://")
|
||||
if didx == -1 || pidx == -1 {
|
||||
return false
|
||||
}
|
||||
domAuth := domain[didx+3:]
|
||||
// to avoid long loop by invalid long domain
|
||||
if len(domAuth) > 253 {
|
||||
return false
|
||||
}
|
||||
patAuth := pattern[pidx+3:]
|
||||
|
||||
domComp := strings.Split(domAuth, ".")
|
||||
patComp := strings.Split(patAuth, ".")
|
||||
for i := len(domComp)/2 - 1; i >= 0; i-- {
|
||||
opp := len(domComp) - 1 - i
|
||||
domComp[i], domComp[opp] = domComp[opp], domComp[i]
|
||||
}
|
||||
for i := len(patComp)/2 - 1; i >= 0; i-- {
|
||||
opp := len(patComp) - 1 - i
|
||||
patComp[i], patComp[opp] = patComp[opp], patComp[i]
|
||||
}
|
||||
|
||||
for i, v := range domComp {
|
||||
if len(patComp) <= i {
|
||||
return false
|
||||
}
|
||||
p := patComp[i]
|
||||
if p == "*" {
|
||||
return true
|
||||
}
|
||||
if p != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
package csrf
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
)
|
||||
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// TokenLookup is a string in the form of "<source>:<key>" that is used
|
||||
// to extract token from the request.
|
||||
//
|
||||
// Optional. Default value "header:X-CSRF-Token".
|
||||
// Possible values:
|
||||
// - "header:<name>"
|
||||
// - "query:<name>"
|
||||
// - "param:<name>"
|
||||
// - "form:<name>"
|
||||
TokenLookup string
|
||||
|
||||
// Cookie
|
||||
//
|
||||
// Optional.
|
||||
Cookie *fiber.Cookie
|
||||
|
||||
// CookieExpires
|
||||
//
|
||||
// Optional. Default: time.Now().Add(24 * time.Hour)
|
||||
CookieExpires time.Time
|
||||
|
||||
// Context key to store generated CSRF token into context.
|
||||
//
|
||||
// Optional. Default value "csrf".
|
||||
ContextKey string
|
||||
}
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
TokenLookup: "header:X-CSRF-Token",
|
||||
ContextKey: "csrf",
|
||||
Cookie: &fiber.Cookie{
|
||||
Name: "_csrf",
|
||||
Domain: "",
|
||||
Path: "",
|
||||
Secure: false,
|
||||
HTTPOnly: false,
|
||||
},
|
||||
}
|
||||
|
||||
// New creates a new middleware handler
|
||||
func New(config ...Config) fiber.Handler {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
|
||||
// Set default values
|
||||
if cfg.TokenLookup == "" {
|
||||
cfg.TokenLookup = ConfigDefault.TokenLookup
|
||||
}
|
||||
if cfg.ContextKey == "" {
|
||||
cfg.ContextKey = ConfigDefault.ContextKey
|
||||
}
|
||||
if cfg.Cookie == nil {
|
||||
cfg.Cookie = ConfigDefault.Cookie
|
||||
}
|
||||
if cfg.CookieExpires.IsZero() {
|
||||
cfg.CookieExpires = ConfigDefault.CookieExpires
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the correct extractor to get the token from the correct location
|
||||
selectors := strings.Split(cfg.TokenLookup, ":")
|
||||
|
||||
// By default we extract from a header
|
||||
extractor := csrfFromHeader(selectors[1])
|
||||
|
||||
switch selectors[0] {
|
||||
case "form":
|
||||
extractor = csrfFromForm(selectors[1])
|
||||
case "query":
|
||||
extractor = csrfFromQuery(selectors[1])
|
||||
case "param":
|
||||
extractor = csrfFromParam(selectors[1])
|
||||
}
|
||||
|
||||
// Return new handler
|
||||
return func(c *fiber.Ctx) error {
|
||||
// Don't execute middleware if Next returns true
|
||||
if cfg.Next != nil && cfg.Next(c) {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Declare empty token and try to get previous generated CSRF from cookie
|
||||
token, key := "", c.Cookies(cfg.Cookie.Name)
|
||||
|
||||
// Check if the cookie had a CSRF token
|
||||
if key == "" {
|
||||
// Create a new CSRF token
|
||||
token = utils.UUID()
|
||||
} else {
|
||||
// Use the server generated token previously to compare
|
||||
// To the extracted token later on
|
||||
token = key
|
||||
}
|
||||
|
||||
// Verify CSRF token on POST requests
|
||||
if c.Method() == fiber.MethodPost {
|
||||
// Extract token from client request i.e. header, query, param or form
|
||||
csrf, err := extractor(c)
|
||||
if err != nil {
|
||||
// We have a problem extracting the csrf token
|
||||
return c.SendStatus(fiber.StatusBadRequest)
|
||||
}
|
||||
// Some magic to compare both cookie and client csrf token
|
||||
if subtle.ConstantTimeCompare(utils.GetBytes(token), utils.GetBytes(csrf)) != 1 {
|
||||
// Comparison failed, return forbidden
|
||||
return c.SendStatus(fiber.StatusForbidden)
|
||||
}
|
||||
}
|
||||
|
||||
// Create new cookie to send new CSRF token
|
||||
cookie := &fiber.Cookie{
|
||||
Name: cfg.Cookie.Name,
|
||||
Value: token,
|
||||
Domain: cfg.Cookie.Domain,
|
||||
Path: cfg.Cookie.Path,
|
||||
Expires: cfg.CookieExpires,
|
||||
Secure: cfg.Cookie.Secure,
|
||||
HTTPOnly: cfg.Cookie.HTTPOnly,
|
||||
}
|
||||
|
||||
// Set cookie to response
|
||||
c.Cookie(cookie)
|
||||
|
||||
// Store token in context
|
||||
c.Locals(cfg.ContextKey, token)
|
||||
|
||||
// Protect clients from caching the response by telling the browser
|
||||
// a new header value is generated
|
||||
c.Vary(fiber.HeaderCookie)
|
||||
|
||||
// Continue stack
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// csrfFromHeader returns a function that extracts token from the request header.
|
||||
func csrfFromHeader(param string) func(c *fiber.Ctx) (string, error) {
|
||||
return func(c *fiber.Ctx) (string, error) {
|
||||
token := c.Get(param)
|
||||
if token == "" {
|
||||
return "", errors.New("missing csrf token in header")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
}
|
||||
|
||||
// csrfcsrfFromQuery returns a function that extracts token from the query string.
|
||||
func csrfFromQuery(param string) func(c *fiber.Ctx) (string, error) {
|
||||
return func(c *fiber.Ctx) (string, error) {
|
||||
token := c.Query(param)
|
||||
if token == "" {
|
||||
return "", errors.New("missing csrf token in query string")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
}
|
||||
|
||||
// csrfFromParam returns a function that extracts token from the url param string.
|
||||
func csrfFromParam(param string) func(c *fiber.Ctx) (string, error) {
|
||||
return func(c *fiber.Ctx) (string, error) {
|
||||
token := c.Params(param)
|
||||
if token == "" {
|
||||
return "", errors.New("missing csrf token in url parameter")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
}
|
||||
|
||||
// csrfFromParam returns a function that extracts token from the url param string.
|
||||
func csrfFromForm(param string) func(c *fiber.Ctx) (string, error) {
|
||||
return func(c *fiber.Ctx) (string, error) {
|
||||
token := c.FormValue(param)
|
||||
if token == "" {
|
||||
return "", errors.New("missing csrf token in form parameter")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
package csrf
|
|
@ -1,50 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
)
|
||||
|
||||
// Favicon adds an UUID indentifier to the request
|
||||
func Favicon(file ...string) fiber.Handler {
|
||||
var err error
|
||||
var icon []byte
|
||||
|
||||
// Set lookup if provided
|
||||
if len(file) > 0 {
|
||||
icon, err = ioutil.ReadFile(file[0])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
// Return handler
|
||||
return func(c *fiber.Ctx) {
|
||||
if len(c.Path()) != 12 || c.Path() != "/favicon.ico" {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
if c.Method() != fiber.MethodGet && c.Method() != fiber.MethodHead {
|
||||
if c.Method() != fiber.MethodOptions {
|
||||
c.Status(405)
|
||||
} else {
|
||||
c.Status(200)
|
||||
}
|
||||
c.Set(fiber.HeaderAllow, "GET, HEAD, OPTIONS")
|
||||
c.Set(fiber.HeaderContentLength, "0")
|
||||
return
|
||||
}
|
||||
|
||||
if len(icon) > 0 {
|
||||
c.Set(fiber.HeaderContentLength, strconv.Itoa(len(icon)))
|
||||
c.Set(fiber.HeaderContentType, "image/x-icon")
|
||||
c.Set(fiber.HeaderCacheControl, "public, max-age=31536000")
|
||||
c.Status(200).SendBytes(icon)
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(204)
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
# Favicon
|
||||
Favicon middleware ignores favicon requests or caches a provided icon in memory to improve performance by skipping disk access. User agents request favicon.ico frequently and indiscriminately, so you may wish to exclude these requests from your logs by using this middleware before your logger middleware.
|
||||
|
||||
**Note** This middleware is exclusively for serving the _default, implicit favicon_, which is `GET /favicon.ico`.
|
||||
|
||||
### Example
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default ignore favicon
|
||||
app.Use(middleware.Favicon())
|
||||
|
||||
// Pass a favicon file that will be cached in memory
|
||||
app.Use(middleware.Favicon("./favicon.ico"))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func Favicon(file ...string) fiber.Handler {}
|
||||
```
|
|
@ -0,0 +1,60 @@
|
|||
# Favicon Authentication
|
||||
Favicon middleware for [Fiber](https://github.com/gofiber/fiber) that ignores favicon requests or caches a provided icon in memory to improve performance by skipping disk access. User agents request favicon.ico frequently and indiscriminately, so you may wish to exclude these requests from your logs by using this middleware before your logger middleware.
|
||||
|
||||
**Note** This middleware is exclusively for serving the default, implicit favicon, which is GET /favicon.ico.
|
||||
|
||||
### Table of Contents
|
||||
- [Signatures](#signatures)
|
||||
- [Examples](#examples)
|
||||
- [Config](#config)
|
||||
- [Default Config](#default-config)
|
||||
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New(config ...Config) fiber.Handler
|
||||
```
|
||||
|
||||
### Examples
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/favicon"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
// Provide a minimal config
|
||||
app.Use(favicon.New())
|
||||
|
||||
// Or extend your config for customization
|
||||
app.Use(favicon.New(favicon.Config{
|
||||
File: "./favicon.ico"
|
||||
}))
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// File holds the path to an actual favicon that will be cached
|
||||
//
|
||||
// Optional. Default: ""
|
||||
File string
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
File: ""
|
||||
}
|
||||
```
|
|
@ -0,0 +1,101 @@
|
|||
package favicon
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// File holds the path to an actual favicon that will be cached
|
||||
//
|
||||
// Optional. Default: ""
|
||||
File string
|
||||
}
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
File: "",
|
||||
}
|
||||
|
||||
const (
|
||||
hType = "image/x-icon"
|
||||
hAllow = "GET, HEAD, OPTIONS"
|
||||
hCache = "public, max-age=31536000"
|
||||
hZero = "0"
|
||||
)
|
||||
|
||||
// New creates a new middleware handler
|
||||
func New(config ...Config) fiber.Handler {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
|
||||
// Set default values
|
||||
if cfg.Next == nil {
|
||||
cfg.Next = ConfigDefault.Next
|
||||
}
|
||||
if cfg.File == "" {
|
||||
cfg.File = ConfigDefault.File
|
||||
}
|
||||
}
|
||||
|
||||
// Load icon if provided
|
||||
var (
|
||||
err error
|
||||
icon []byte
|
||||
iconLen string
|
||||
)
|
||||
if cfg.File != "" {
|
||||
if icon, err = ioutil.ReadFile(cfg.File); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
iconLen = strconv.Itoa(len(icon))
|
||||
}
|
||||
|
||||
// Return new handler
|
||||
return func(c *fiber.Ctx) error {
|
||||
// Don't execute middleware if Next returns true
|
||||
if cfg.Next != nil && cfg.Next(c) {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Only respond to favicon requests
|
||||
if len(c.Path()) != 12 || c.Path() != "/favicon.ico" {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Only allow GET, HEAD and OPTIONS requests
|
||||
if c.Method() != fiber.MethodGet && c.Method() != fiber.MethodHead {
|
||||
if c.Method() != fiber.MethodOptions {
|
||||
c.Status(fiber.StatusMethodNotAllowed)
|
||||
} else {
|
||||
c.Status(fiber.StatusOK)
|
||||
}
|
||||
c.Set(fiber.HeaderAllow, hAllow)
|
||||
c.Set(fiber.HeaderContentLength, hZero)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Serve cached favicon
|
||||
if len(icon) > 0 {
|
||||
c.Set(fiber.HeaderContentLength, iconLen)
|
||||
c.Set(fiber.HeaderContentType, hType)
|
||||
c.Set(fiber.HeaderCacheControl, hCache)
|
||||
return c.Status(fiber.StatusOK).Send(icon)
|
||||
}
|
||||
|
||||
return c.SendStatus(fiber.StatusNoContent)
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
package middleware
|
||||
package favicon
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
|
@ -13,9 +13,11 @@ import (
|
|||
func Test_Middleware_Favicon(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(Favicon())
|
||||
app.Use(New())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {})
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
// Skip Favicon middleware
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
|
@ -44,16 +46,22 @@ func Test_Middleware_Favicon_Not_Found(t *testing.T) {
|
|||
}
|
||||
}()
|
||||
|
||||
fiber.New().Use(Favicon("non-exist.ico"))
|
||||
fiber.New().Use(New(Config{
|
||||
File: "non-exist.ico",
|
||||
}))
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_Favicon_Found
|
||||
func Test_Middleware_Favicon_Found(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(Favicon("./testdata/favicon.ico"))
|
||||
app.Use(New(Config{
|
||||
File: "../../.github/testdata/favicon.ico",
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {})
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/favicon.ico", nil))
|
||||
|
||||
|
@ -65,8 +73,10 @@ func Test_Middleware_Favicon_Found(t *testing.T) {
|
|||
// go test -v -run=^$ -bench=Benchmark_Middleware_Favicon -benchmem -count=4
|
||||
func Benchmark_Middleware_Favicon(b *testing.B) {
|
||||
app := fiber.New()
|
||||
app.Use(Favicon())
|
||||
app.Get("/", func(c *fiber.Ctx) {})
|
||||
app.Use(New())
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return nil
|
||||
})
|
||||
handler := app.Handler()
|
||||
|
||||
c := &fasthttp.RequestCtx{}
|
|
@ -1,221 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
fiber "github.com/gofiber/fiber"
|
||||
)
|
||||
|
||||
// Middleware types
|
||||
type (
|
||||
// FileSystemConfig defines the config for FileSystem middleware.
|
||||
FileSystemConfig struct {
|
||||
// Next defines a function to skip this middleware if returned true.
|
||||
Next func(ctx *fiber.Ctx) bool
|
||||
|
||||
// Root is a FileSystem that provides access
|
||||
// to a collection of files and directories.
|
||||
// Required. Default: nil
|
||||
Root http.FileSystem
|
||||
|
||||
// Index file for serving a directory.
|
||||
// Optional. Default: "index.html"
|
||||
Index string
|
||||
|
||||
// Enable directory browsing.
|
||||
// Optional. Default: false
|
||||
Browse bool
|
||||
}
|
||||
)
|
||||
|
||||
// FileSystemConfigDefault is the default config
|
||||
var FileSystemConfigDefault = FileSystemConfig{
|
||||
Next: nil,
|
||||
Root: nil,
|
||||
Index: "/index.html",
|
||||
Browse: false,
|
||||
}
|
||||
|
||||
/*
|
||||
FileSystem allows the following config arguments in any order:
|
||||
- FileSystem(root http.FileSystem)
|
||||
- FileSystem(index string)
|
||||
- FileSystem(browse bool)
|
||||
- FileSystem(config FileSystem)
|
||||
- FileSystem(next func(*fiber.Ctx) bool)
|
||||
*/
|
||||
func FileSystem(options ...interface{}) fiber.Handler {
|
||||
// Create default config
|
||||
var config = FileSystemConfigDefault
|
||||
// Assert options if provided to adjust the config
|
||||
for i := range options {
|
||||
switch opt := options[i].(type) {
|
||||
case func(*fiber.Ctx) bool:
|
||||
config.Next = opt
|
||||
case http.FileSystem:
|
||||
config.Root = opt
|
||||
case string:
|
||||
config.Index = opt
|
||||
case bool:
|
||||
config.Browse = opt
|
||||
case FileSystemConfig:
|
||||
config = opt
|
||||
default:
|
||||
log.Fatal("FileSystem: the following option types are allowed: string, bool, http.FileSystem, FileSystemConfig")
|
||||
}
|
||||
}
|
||||
// Return fileSystem
|
||||
return fileSystem(config)
|
||||
}
|
||||
|
||||
func fileSystem(config FileSystemConfig) fiber.Handler {
|
||||
// Set config default values
|
||||
if config.Index == "" {
|
||||
config.Index = FileSystemConfigDefault.Index
|
||||
}
|
||||
if !strings.HasPrefix(config.Index, "/") {
|
||||
config.Index = "/" + config.Index
|
||||
}
|
||||
if config.Root == nil {
|
||||
log.Fatal("FileSystem: Root value is missing!")
|
||||
}
|
||||
|
||||
// Middleware settings
|
||||
var prefix string
|
||||
|
||||
// Return handler
|
||||
return func(c *fiber.Ctx) {
|
||||
// Set prefix
|
||||
if len(prefix) == 0 {
|
||||
prefix = c.Route().Path
|
||||
}
|
||||
|
||||
// Strip prefix
|
||||
path := strings.TrimPrefix(c.Path(), prefix)
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
path = "/" + path
|
||||
}
|
||||
|
||||
file, err := config.Root.Open(path)
|
||||
if err != nil {
|
||||
c.Next(err)
|
||||
return
|
||||
}
|
||||
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
c.Next(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Serve index if path is directory
|
||||
if stat.IsDir() {
|
||||
indexPath := strings.TrimSuffix(path, "/") + config.Index
|
||||
index, err := config.Root.Open(indexPath)
|
||||
if err == nil {
|
||||
indexStat, err := index.Stat()
|
||||
if err == nil {
|
||||
file = index
|
||||
stat = indexStat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Browse directory if no index found and browsing is enabled
|
||||
if stat.IsDir() {
|
||||
if config.Browse {
|
||||
if err := dirList(c, file); err != nil {
|
||||
c.Next(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
c.SendStatus(fiber.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
modTime := stat.ModTime()
|
||||
contentLength := int(stat.Size())
|
||||
|
||||
// Set Content Type header
|
||||
c.Type(getFileExtension(stat.Name()))
|
||||
|
||||
// Set Last Modified header
|
||||
if !modTime.IsZero() {
|
||||
c.Set(fiber.HeaderLastModified, modTime.UTC().Format(http.TimeFormat))
|
||||
}
|
||||
|
||||
if c.Method() == fiber.MethodGet {
|
||||
c.Fasthttp.SetBodyStream(file, contentLength)
|
||||
return
|
||||
} else if c.Method() == fiber.MethodHead {
|
||||
c.Fasthttp.ResetBody()
|
||||
c.Fasthttp.Response.SkipBody = true
|
||||
c.Fasthttp.Response.Header.SetContentLength(contentLength)
|
||||
if err := file.Close(); err != nil {
|
||||
c.Next(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func getFileExtension(path string) string {
|
||||
n := strings.LastIndexByte(path, '.')
|
||||
if n < 0 {
|
||||
return ""
|
||||
}
|
||||
return path[n:]
|
||||
}
|
||||
|
||||
func dirList(c *fiber.Ctx, f http.File) error {
|
||||
fileinfos, err := f.Readdir(-1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fm := make(map[string]os.FileInfo, len(fileinfos))
|
||||
filenames := make([]string, 0, len(fileinfos))
|
||||
for _, fi := range fileinfos {
|
||||
name := fi.Name()
|
||||
fm[name] = fi
|
||||
filenames = append(filenames, name)
|
||||
}
|
||||
|
||||
basePathEscaped := html.EscapeString(c.Path())
|
||||
c.Write(fmt.Sprintf("<html><head><title>%s</title><style>.dir { font-weight: bold }</style></head><body>", basePathEscaped))
|
||||
c.Write(fmt.Sprintf("<h1>%s</h1>", basePathEscaped))
|
||||
c.Write("<ul>")
|
||||
|
||||
if len(basePathEscaped) > 1 {
|
||||
parentPathEscaped := html.EscapeString(c.Path() + "/..")
|
||||
c.Write(fmt.Sprintf(`<li><a href="%s" class="dir">..</a></li>`, parentPathEscaped))
|
||||
}
|
||||
|
||||
sort.Strings(filenames)
|
||||
for _, name := range filenames {
|
||||
pathEscaped := html.EscapeString(path.Join(c.Path() + "/" + name))
|
||||
fi := fm[name]
|
||||
auxStr := "dir"
|
||||
className := "dir"
|
||||
if !fi.IsDir() {
|
||||
auxStr = fmt.Sprintf("file, %d bytes", fi.Size())
|
||||
className = "file"
|
||||
}
|
||||
c.Write(fmt.Sprintf(`<li><a href="%s" class="%s">%s</a>, %s, last modified %s</li>`,
|
||||
pathEscaped, className, html.EscapeString(name), auxStr, fi.ModTime()))
|
||||
}
|
||||
c.Write("</ul></body></html>")
|
||||
|
||||
c.Type("html")
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
# FileSystem
|
||||
|
||||
FileSystem middleware for Fiber
|
||||
|
||||
### Example
|
||||
The middleware packages comes with the official Fiber framework.
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
```
|
||||
|
||||
### Signature
|
||||
```go
|
||||
embed.New(config ...embed.Config) func(c *fiber.Ctx)
|
||||
```
|
||||
|
||||
### Config
|
||||
| Property | Type | Description | Default |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| Index | `string` | Index file name | `index.html` |
|
||||
| Browse | `bool` | Enable directory browsing | `false` |
|
||||
| Root | `http.FileSystem` | http.FileSystem to use | `nil` |
|
||||
| ErrorHandler | `func(*fiber.Ctx, error)` | Error handler | `InternalServerError` |
|
||||
|
||||
### pkger
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/middleware/filesystem"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Pass a FileSystem
|
||||
app.Use("/assets", middleware.FileSystem(http.Dir("./assets")))
|
||||
|
||||
// Define the index file for serving a directory
|
||||
app.Use("/assets", middleware.FileSystem(http.Dir("./assets"), "index.html"))
|
||||
|
||||
// Enable directory browsing
|
||||
app.Use("/assets", middleware.FileSystem(http.Dir("./assets"), true))
|
||||
|
||||
// Pass a config
|
||||
app.Use("/assets", middleware.FileSystem(middleware.FileSystemConfig{
|
||||
Root: http.Dir("./assets"),
|
||||
Index: "index.html",
|
||||
Browse: true,
|
||||
}))
|
||||
|
||||
app.Listen(8080)
|
||||
}
|
||||
```
|
||||
|
||||
### packr
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/middleware/filesystem"
|
||||
|
||||
"github.com/gobuffalo/packr/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/assets", middleware.FileSystem(packr.New("Assets Box", "/assets")))
|
||||
|
||||
app.Listen(8080)
|
||||
}
|
||||
```
|
||||
|
||||
### go.rice
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/middleware/filesystem"
|
||||
|
||||
"github.com/GeertJohan/go.rice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/assets", middleware.FileSystem(rice.MustFindBox("assets").HTTPBox()))
|
||||
|
||||
app.Listen(8080)
|
||||
}
|
||||
```
|
||||
|
||||
### fileb0x
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/middleware/filesystem"
|
||||
"<Your go module>/myEmbeddedFiles"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/assets", middleware.FileSystem(myEmbeddedFiles.HTTP))
|
||||
|
||||
app.Listen(8080)
|
||||
}
|
||||
```
|
||||
|
||||
### statik
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/middleware/filesystem"
|
||||
|
||||
"<Your go module>/statik"
|
||||
fs "github.com/rakyll/statik/fs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
statik, err := fs.New()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/", middleware.FileSystem.New(statikFS))
|
||||
|
||||
app.Listen(8080)
|
||||
}
|
||||
```
|
|
@ -0,0 +1,184 @@
|
|||
# Filesystem middleware
|
||||
Filesystem middleware for [Fiber](https://github.com/gofiber/fiber) that enables you to serve files from a directory.
|
||||
|
||||
### Table of Contents
|
||||
- [Signatures](#signatures)
|
||||
- [Examples](#examples)
|
||||
- [Config](#config)
|
||||
- [Default Config](#default-config)
|
||||
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New(config Config) fiber.Handler
|
||||
```
|
||||
|
||||
### Examples
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
// Provide a minimal config
|
||||
app.Use(filesystem.New(filesystem.Config{
|
||||
Root: http.Dir("./assets")
|
||||
}))
|
||||
|
||||
// Or extend your config for customization
|
||||
app.Use(filesystem.New(filesystem.Config{
|
||||
Root: http.Dir("./assets"),
|
||||
Index: "index.html",
|
||||
Browse: true,
|
||||
NotFoundFile: "404.html"
|
||||
}))
|
||||
```
|
||||
|
||||
|
||||
## packr
|
||||
https://github.com/gobuffalo/packr
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
|
||||
"github.com/gobuffalo/packr/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/assets", filesystem.New(filesystem.Config{
|
||||
Root: packr.New("Assets Box", "/assets"),
|
||||
})
|
||||
|
||||
app.Listen(":3000")
|
||||
}
|
||||
```
|
||||
|
||||
## go.rice
|
||||
https://github.com/GeertJohan/go.rice
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
|
||||
"github.com/GeertJohan/go.rice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/assets", filesystem.New(filesystem.Config{
|
||||
Root: rice.MustFindBox("assets").HTTPBox(),
|
||||
})
|
||||
|
||||
app.Listen(":3000")
|
||||
}
|
||||
```
|
||||
|
||||
## fileb0x
|
||||
https://github.com/UnnoTed/fileb0x
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
|
||||
"<Your go module>/myEmbeddedFiles"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/assets", filesystem.New(filesystem.Config{
|
||||
Root: myEmbeddedFiles.HTTP,
|
||||
})
|
||||
|
||||
app.Listen(":3000")
|
||||
}
|
||||
```
|
||||
|
||||
## statik
|
||||
https://github.com/rakyll/statik
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
|
||||
"<Your go module>/statik"
|
||||
fs "github.com/rakyll/statik/fs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
statik, err := fs.New()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/", filesystem.New(filesystem.Config{
|
||||
Root: statikFS,
|
||||
})
|
||||
|
||||
app.Listen(":3000")
|
||||
}
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Root is a FileSystem that provides access
|
||||
// to a collection of files and directories.
|
||||
//
|
||||
// Required. Default: nil
|
||||
Root http.FileSystem
|
||||
|
||||
// Index file for serving a directory.
|
||||
//
|
||||
// Optional. Default: "index.html"
|
||||
Index string
|
||||
|
||||
// Enable directory browsing.
|
||||
//
|
||||
// Optional. Default: false
|
||||
Browse bool
|
||||
|
||||
// File to return if path is not found. Useful for SPA's.
|
||||
//
|
||||
// Optional. Default: ""
|
||||
NotFoundFile string
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Root: nil,
|
||||
Index: "/index.html",
|
||||
Browse: false,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,166 @@
|
|||
package filesystem
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Root is a FileSystem that provides access
|
||||
// to a collection of files and directories.
|
||||
//
|
||||
// Required. Default: nil
|
||||
Root http.FileSystem
|
||||
|
||||
// Index file for serving a directory.
|
||||
//
|
||||
// Optional. Default: "index.html"
|
||||
Index string
|
||||
|
||||
// Enable directory browsing.
|
||||
//
|
||||
// Optional. Default: false
|
||||
Browse bool
|
||||
|
||||
// File to return if path is not found. Useful for SPA's.
|
||||
//
|
||||
// Optional. Default: ""
|
||||
NotFoundFile string
|
||||
}
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Root: nil,
|
||||
Index: "/index.html",
|
||||
Browse: false,
|
||||
}
|
||||
|
||||
// New creates a new middleware handler
|
||||
func New(config Config) fiber.Handler {
|
||||
// Set config
|
||||
cfg := config
|
||||
|
||||
// Set default values
|
||||
if cfg.Next == nil {
|
||||
cfg.Next = ConfigDefault.Next
|
||||
}
|
||||
if cfg.Index == "" {
|
||||
cfg.Index = ConfigDefault.Index
|
||||
}
|
||||
if !strings.HasPrefix(cfg.Index, "/") {
|
||||
cfg.Index = "/" + cfg.Index
|
||||
}
|
||||
if cfg.Root == nil {
|
||||
log.Fatal("filesystem: Root cannot be nil")
|
||||
}
|
||||
|
||||
var once sync.Once
|
||||
var prefix string
|
||||
|
||||
// Return new handler
|
||||
return func(c *fiber.Ctx) error {
|
||||
// Don't execute middleware if Next returns true
|
||||
if cfg.Next != nil && cfg.Next(c) {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
method := c.Method()
|
||||
|
||||
// We only serve static assets on GET or HEAD methods
|
||||
if method != fiber.MethodGet && method != fiber.MethodHead {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Set prefix once
|
||||
once.Do(func() {
|
||||
prefix = c.Route().Path
|
||||
})
|
||||
|
||||
// Strip prefix
|
||||
path := strings.TrimPrefix(c.Path(), prefix)
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
path = "/" + path
|
||||
}
|
||||
|
||||
file, err := cfg.Root.Open(path)
|
||||
if err != nil && os.IsNotExist(err) && cfg.NotFoundFile != "" {
|
||||
file, err = cfg.Root.Open(cfg.NotFoundFile)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return c.Status(fiber.StatusNotFound).Next()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Serve index if path is directory
|
||||
if stat.IsDir() {
|
||||
indexPath := strings.TrimSuffix(path, "/") + cfg.Index
|
||||
index, err := cfg.Root.Open(indexPath)
|
||||
if err == nil {
|
||||
indexStat, err := index.Stat()
|
||||
if err == nil {
|
||||
file = index
|
||||
stat = indexStat
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Browse directory if no index found and browsing is enabled
|
||||
if stat.IsDir() {
|
||||
if cfg.Browse {
|
||||
if err := dirList(c, file); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return fiber.ErrForbidden
|
||||
}
|
||||
|
||||
modTime := stat.ModTime()
|
||||
contentLength := int(stat.Size())
|
||||
|
||||
// Set Content Type header
|
||||
c.Type(getFileExtension(stat.Name()))
|
||||
|
||||
// Set Last Modified header
|
||||
if !modTime.IsZero() {
|
||||
c.Set(fiber.HeaderLastModified, modTime.UTC().Format(http.TimeFormat))
|
||||
}
|
||||
|
||||
if method == fiber.MethodGet {
|
||||
c.Response().SetBodyStream(file, contentLength)
|
||||
return nil
|
||||
}
|
||||
if method == fiber.MethodHead {
|
||||
c.Request().ResetBody()
|
||||
// Fasthttp should skipbody by default if HEAD?
|
||||
c.Response().SkipBody = true
|
||||
c.Response().Header.SetContentLength(contentLength)
|
||||
if err := file.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return c.Next()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package filesystem
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
)
|
||||
|
||||
// go test -run Test_FileSystem
|
||||
func Test_FileSystem(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/test", New(Config{
|
||||
Root: http.Dir("../../.github/testdata/fs"),
|
||||
}))
|
||||
|
||||
app.Use("/dir", New(Config{
|
||||
Root: http.Dir("../../.github/testdata/fs"),
|
||||
Browse: true,
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, World!")
|
||||
})
|
||||
|
||||
app.Use("/spatest", New(Config{
|
||||
Root: http.Dir("../../.github/testdata/fs"),
|
||||
NotFoundFile: "index.html",
|
||||
}))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
url string
|
||||
statusCode int
|
||||
contentType string
|
||||
modifiedTime string
|
||||
}{
|
||||
{
|
||||
name: "Should be returns status 200 with suitable content-type",
|
||||
url: "/test/index.html",
|
||||
statusCode: 200,
|
||||
contentType: "text/html",
|
||||
},
|
||||
{
|
||||
name: "Should be returns status 200 with suitable content-type",
|
||||
url: "/test",
|
||||
statusCode: 200,
|
||||
contentType: "text/html",
|
||||
},
|
||||
{
|
||||
name: "Should be returns status 200 with suitable content-type",
|
||||
url: "/test/css/style.css",
|
||||
statusCode: 200,
|
||||
contentType: "text/css",
|
||||
},
|
||||
{
|
||||
name: "Should be returns status 404",
|
||||
url: "/test/nofile.js",
|
||||
statusCode: 404,
|
||||
},
|
||||
{
|
||||
name: "Should be returns status 404",
|
||||
url: "/test/nofile",
|
||||
statusCode: 404,
|
||||
},
|
||||
{
|
||||
name: "Should be returns status 200",
|
||||
url: "/",
|
||||
statusCode: 200,
|
||||
contentType: "text/plain; charset=utf-8",
|
||||
},
|
||||
{
|
||||
name: "Should be returns status 403",
|
||||
url: "/test/img",
|
||||
statusCode: 403,
|
||||
},
|
||||
{
|
||||
name: "Should list the directory contents",
|
||||
url: "/dir/img",
|
||||
statusCode: 200,
|
||||
contentType: "text/html",
|
||||
},
|
||||
{
|
||||
name: "Should be returns status 200",
|
||||
url: "/dir/img/fiber.png",
|
||||
statusCode: 200,
|
||||
contentType: "image/png",
|
||||
},
|
||||
{
|
||||
name: "Should be return status 200",
|
||||
url: "/spatest/doesnotexist",
|
||||
statusCode: 200,
|
||||
contentType: "text/html",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
req, _ := http.NewRequest("GET", tt.url, nil)
|
||||
resp, err := app.Test(req)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, tt.statusCode, resp.StatusCode)
|
||||
|
||||
if tt.contentType != "" {
|
||||
ct := resp.Header.Get("Content-Type")
|
||||
utils.AssertEqual(t, tt.contentType, ct)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package filesystem
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func getFileExtension(path string) string {
|
||||
n := strings.LastIndexByte(path, '.')
|
||||
if n < 0 {
|
||||
return ""
|
||||
}
|
||||
return path[n:]
|
||||
}
|
||||
|
||||
func dirList(c *fiber.Ctx, f http.File) error {
|
||||
fileinfos, err := f.Readdir(-1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fm := make(map[string]os.FileInfo, len(fileinfos))
|
||||
filenames := make([]string, 0, len(fileinfos))
|
||||
for _, fi := range fileinfos {
|
||||
name := fi.Name()
|
||||
fm[name] = fi
|
||||
filenames = append(filenames, name)
|
||||
}
|
||||
|
||||
basePathEscaped := html.EscapeString(c.Path())
|
||||
fmt.Fprintf(c, "<html><head><title>%s</title><style>.dir { font-weight: bold }</style></head><body>", basePathEscaped)
|
||||
fmt.Fprintf(c, "<h1>%s</h1>", basePathEscaped)
|
||||
fmt.Fprint(c, "<ul>")
|
||||
|
||||
if len(basePathEscaped) > 1 {
|
||||
parentPathEscaped := html.EscapeString(c.Path() + "/..")
|
||||
fmt.Fprintf(c, `<li><a href="%s" class="dir">..</a></li>`, parentPathEscaped)
|
||||
}
|
||||
|
||||
sort.Strings(filenames)
|
||||
for _, name := range filenames {
|
||||
pathEscaped := html.EscapeString(path.Join(c.Path() + "/" + name))
|
||||
fi := fm[name]
|
||||
auxStr := "dir"
|
||||
className := "dir"
|
||||
if !fi.IsDir() {
|
||||
auxStr = fmt.Sprintf("file, %d bytes", fi.Size())
|
||||
className = "file"
|
||||
}
|
||||
fmt.Fprintf(c, `<li><a href="%s" class="%s">%s</a>, %s, last modified %s</li>`,
|
||||
pathEscaped, className, html.EscapeString(name), auxStr, fi.ModTime())
|
||||
}
|
||||
fmt.Fprint(c, "</ul></body></html>")
|
||||
|
||||
c.Type("html")
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
package middleware
|
|
@ -0,0 +1,96 @@
|
|||
# Limiter
|
||||
Limiter middleware for [Fiber](https://github.com/gofiber/fiber) used to limit repeated requests to public APIs and/or endpoints such as password reset etc. Also useful for API clients, web crawling, or other tasks that need to be throttled.
|
||||
|
||||
**Note: this module does not share state with other processes/servers by default.**
|
||||
|
||||
### Table of Contents
|
||||
- [Signatures](#signatures)
|
||||
- [Examples](#examples)
|
||||
- [Config](#config)
|
||||
- [Default Config](#default-config)
|
||||
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New(config ...Config) fiber.Handler
|
||||
```
|
||||
|
||||
### Examples
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/limiter"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
// Default middleware config
|
||||
app.Use(limiter.New())
|
||||
|
||||
// Or extend your config for customization
|
||||
app.Use(limiter.New(limiter.Config{
|
||||
Next: func(c *fiber.Ctx) bool {
|
||||
return c.IP() == "127.0.0.1"
|
||||
},
|
||||
Max: 20,
|
||||
Duration: 30 * time.Second,
|
||||
Key: func(c *fiber.Ctx) string {
|
||||
return c.Get("x-forwarded-for")
|
||||
},
|
||||
LimitReached: func(c *fiber.Ctx) error {
|
||||
return c.SendFile("./toofast.html")
|
||||
},
|
||||
}))
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Max number of recent connections during `Duration` seconds before sending a 429 response
|
||||
//
|
||||
// Default: 5
|
||||
Max int
|
||||
|
||||
// Duration is the time on how long to keep records of requests in memory
|
||||
//
|
||||
// Default: time.Minute
|
||||
Duration time.Duration
|
||||
|
||||
// Key allows you to generate custom keys, by default c.IP() is used
|
||||
//
|
||||
// Default: func(c *fiber.Ctx) string {
|
||||
// return c.IP()
|
||||
// }
|
||||
Key func(*fiber.Ctx) string
|
||||
|
||||
// LimitReached is called when a request hits the limit
|
||||
//
|
||||
// Default: func(c *fiber.Ctx) error {
|
||||
// return c.SendStatus(fiber.StatusTooManyRequests)
|
||||
// }
|
||||
LimitReached fiber.Handler
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Max: 5,
|
||||
Duration: time.Minute,
|
||||
Key: func(c *fiber.Ctx) string {
|
||||
return c.IP()
|
||||
},
|
||||
LimitReached: func(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusTooManyRequests)
|
||||
},
|
||||
}
|
||||
```
|
|
@ -0,0 +1,154 @@
|
|||
package limiter
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Max number of recent connections during `Duration` seconds before sending a 429 response
|
||||
//
|
||||
// Default: 5
|
||||
Max int
|
||||
|
||||
// Duration is the time on how long to keep records of requests in memory
|
||||
//
|
||||
// Default: time.Minute
|
||||
Duration time.Duration
|
||||
|
||||
// Key allows you to generate custom keys, by default c.IP() is used
|
||||
//
|
||||
// Default: func(c *fiber.Ctx) string {
|
||||
// return c.IP()
|
||||
// }
|
||||
Key func(*fiber.Ctx) string
|
||||
|
||||
// LimitReached is called when a request hits the limit
|
||||
//
|
||||
// Default: func(c *fiber.Ctx) error {
|
||||
// return c.SendStatus(fiber.StatusTooManyRequests)
|
||||
// }
|
||||
LimitReached fiber.Handler
|
||||
}
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Max: 5,
|
||||
Duration: time.Minute,
|
||||
Key: func(c *fiber.Ctx) string {
|
||||
return c.IP()
|
||||
},
|
||||
LimitReached: func(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusTooManyRequests)
|
||||
},
|
||||
}
|
||||
|
||||
// X-RateLimit-* headers
|
||||
const (
|
||||
xRateLimitLimit = "X-RateLimit-Limit"
|
||||
xRateLimitRemaining = "X-RateLimit-Remaining"
|
||||
xRateLimitReset = "X-RateLimit-Reset"
|
||||
)
|
||||
|
||||
// New creates a new middleware handler
|
||||
func New(config ...Config) fiber.Handler {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
|
||||
// Set default values
|
||||
if cfg.Next == nil {
|
||||
cfg.Next = ConfigDefault.Next
|
||||
}
|
||||
if cfg.Max <= 0 {
|
||||
cfg.Max = ConfigDefault.Max
|
||||
}
|
||||
if int(cfg.Duration.Seconds()) <= 0 {
|
||||
cfg.Duration = ConfigDefault.Duration
|
||||
}
|
||||
if cfg.Key == nil {
|
||||
cfg.Key = ConfigDefault.Key
|
||||
}
|
||||
if cfg.LimitReached == nil {
|
||||
cfg.LimitReached = ConfigDefault.LimitReached
|
||||
}
|
||||
}
|
||||
|
||||
// Limiter settings
|
||||
var max = strconv.Itoa(cfg.Max)
|
||||
var hits = make(map[string]int)
|
||||
var reset = make(map[string]int)
|
||||
var timestamp = int(time.Now().Unix())
|
||||
var duration = int(cfg.Duration.Seconds())
|
||||
|
||||
// mutex for parallel read and write access
|
||||
mux := &sync.Mutex{}
|
||||
|
||||
// Return new handler
|
||||
return func(c *fiber.Ctx) error {
|
||||
// Don't execute middleware if Next returns true
|
||||
if cfg.Next != nil && cfg.Next(c) {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Get key (default is the remote IP)
|
||||
key := cfg.Key(c)
|
||||
|
||||
// Lock map
|
||||
mux.Lock()
|
||||
|
||||
// Set unix timestamp if not exist
|
||||
if reset[key] == 0 {
|
||||
reset[key] = timestamp + duration
|
||||
} else if timestamp >= reset[key] {
|
||||
hits[key] = 0
|
||||
reset[key] = timestamp + duration
|
||||
}
|
||||
|
||||
// Increment key hits
|
||||
hits[key]++
|
||||
|
||||
// Get current hits
|
||||
hitCount := hits[key]
|
||||
|
||||
// Calculate when it resets in seconds
|
||||
resetTime := reset[key] - timestamp
|
||||
|
||||
// Unlock map
|
||||
mux.Unlock()
|
||||
|
||||
// Set how many hits we have left
|
||||
remaining := cfg.Max - hitCount
|
||||
|
||||
// Check if hits exceed the cfg.Max
|
||||
if remaining < 0 {
|
||||
// Return response with Retry-After header
|
||||
// https://tools.ietf.org/html/rfc6584
|
||||
c.Set(fiber.HeaderRetryAfter, strconv.Itoa(resetTime))
|
||||
|
||||
// Call LimitReached handler
|
||||
return cfg.LimitReached(c)
|
||||
}
|
||||
|
||||
// We can continue, update RateLimit headers
|
||||
c.Set(xRateLimitLimit, max)
|
||||
c.Set(xRateLimitRemaining, strconv.Itoa(remaining))
|
||||
c.Set(xRateLimitReset, strconv.Itoa(resetTime))
|
||||
|
||||
// Continue stack
|
||||
return c.Next()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package limiter
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// go test -run Test_Limiter_Concurrency -race -v
|
||||
func Test_Limiter_Concurrency(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 100,
|
||||
Duration: 1 * time.Minute,
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
// random delay between the requests
|
||||
time.Sleep(time.Duration(rand.Intn(10000)) * time.Microsecond)
|
||||
return c.SendString("Hello tester!")
|
||||
})
|
||||
|
||||
var wg sync.WaitGroup
|
||||
singleRequest := func(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
resp, err := app.Test(httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("Unexpected status code %v", resp.StatusCode)
|
||||
}
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil || "Hello tester!" != string(body) {
|
||||
t.Fatalf("Unexpected body %v", string(body))
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i <= 50; i++ {
|
||||
wg.Add(1)
|
||||
go singleRequest(&wg)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// go test -v -run=^$ -bench=Benchmark_Limiter -benchmem -count=4
|
||||
func Benchmark_Limiter(b *testing.B) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(New(Config{
|
||||
Max: 100,
|
||||
Duration: 60 * time.Second,
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, World!")
|
||||
})
|
||||
|
||||
h := app.Handler()
|
||||
|
||||
fctx := &fasthttp.RequestCtx{}
|
||||
fctx.Request.Header.SetMethod("GET")
|
||||
fctx.Request.SetRequestURI("/")
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
h(fctx)
|
||||
}
|
||||
|
||||
utils.AssertEqual(b, "100", string(fctx.Response.Header.Peek("X-RateLimit-Limit")))
|
||||
}
|
|
@ -1,464 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
fiber "github.com/gofiber/fiber"
|
||||
utils "github.com/gofiber/utils"
|
||||
colorable "github.com/mattn/go-colorable"
|
||||
isatty "github.com/mattn/go-isatty"
|
||||
bytebufferpool "github.com/valyala/bytebufferpool"
|
||||
)
|
||||
|
||||
// Middleware types
|
||||
type (
|
||||
// LoggerConfig defines the config for Logger middleware.
|
||||
LoggerConfig struct {
|
||||
// Next defines a function to skip this middleware if returned true.
|
||||
Next func(*fiber.Ctx) bool
|
||||
|
||||
// Format defines the logging tags
|
||||
//
|
||||
// - pid
|
||||
// - time
|
||||
// - ip
|
||||
// - ips
|
||||
// - url
|
||||
// - host
|
||||
// - method
|
||||
// - methodColored
|
||||
// - path
|
||||
// - protocol
|
||||
// - route
|
||||
// - referer
|
||||
// - ua
|
||||
// - latency
|
||||
// - status
|
||||
// - statusColored
|
||||
// - body
|
||||
// - error
|
||||
// - bytesSent
|
||||
// - bytesReceived
|
||||
// - header:<key>
|
||||
// - query:<key>
|
||||
// - form:<key>
|
||||
// - cookie:<key>
|
||||
//
|
||||
// Optional. Default: #${pid} - ${time} ${status} - ${latency} ${method} ${path}\n
|
||||
Format string
|
||||
|
||||
// TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html
|
||||
//
|
||||
// Optional. Default: 2006/01/02 15:04:05
|
||||
TimeFormat string
|
||||
|
||||
// TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc
|
||||
//
|
||||
// Optional. Default: Local
|
||||
TimeZone string
|
||||
|
||||
// Output is a writter where logs are written
|
||||
//
|
||||
// Default: os.Stderr
|
||||
Output io.Writer
|
||||
|
||||
// Colors are only supported if no custom Output is given
|
||||
enableColors bool
|
||||
|
||||
// timeZoneLocation holds the compiled timezone
|
||||
timeZoneLocation *time.Location
|
||||
}
|
||||
)
|
||||
|
||||
// Logger variables
|
||||
const (
|
||||
LoggerTagPid = "pid"
|
||||
LoggerTagTime = "time"
|
||||
LoggerTagReferer = "referer"
|
||||
LoggerTagProtocol = "protocol"
|
||||
LoggerTagIP = "ip"
|
||||
LoggerTagIPs = "ips"
|
||||
LoggerTagHost = "host"
|
||||
LoggerTagMethod = "method"
|
||||
LoggerTagPath = "path"
|
||||
LoggerTagURL = "url"
|
||||
LoggerTagUA = "ua"
|
||||
LoggerTagLatency = "latency"
|
||||
LoggerTagStatus = "status"
|
||||
LoggerTagBody = "body"
|
||||
LoggerTagBytesSent = "bytesSent"
|
||||
LoggerTagBytesReceived = "bytesReceived"
|
||||
LoggerTagRoute = "route"
|
||||
LoggerTagError = "error"
|
||||
LoggerTagHeader = "header:"
|
||||
LoggerTagQuery = "query:"
|
||||
LoggerTagForm = "form:"
|
||||
LoggerTagCookie = "cookie:"
|
||||
LoggerTagColorBlack = "black"
|
||||
LoggerTagColorRed = "red"
|
||||
LoggerTagColorGreen = "green"
|
||||
LoggerTagColorYellow = "yellow"
|
||||
LoggerTagColorBlue = "blue"
|
||||
LoggerTagColorMagenta = "magenta"
|
||||
LoggerTagColorCyan = "cyan"
|
||||
LoggerTagColorWhite = "white"
|
||||
LoggerTagColorReset = "resetColor"
|
||||
// LoggerTagStatusColor = "statusColor"
|
||||
// LoggerTagMethodColor = "methodColor"
|
||||
)
|
||||
|
||||
// NEW : Color variables
|
||||
const (
|
||||
cBlack = "\u001b[90m"
|
||||
cRed = "\u001b[91m"
|
||||
cGreen = "\u001b[92m"
|
||||
cYellow = "\u001b[93m"
|
||||
cBlue = "\u001b[94m"
|
||||
cMagenta = "\u001b[95m"
|
||||
cCyan = "\u001b[96m"
|
||||
cWhite = "\u001b[97m"
|
||||
cReset = "\u001b[0m"
|
||||
)
|
||||
|
||||
// for colorizing response status and request method
|
||||
var (
|
||||
statusColor string
|
||||
responseStatus int
|
||||
methodColor string
|
||||
requestMethod string
|
||||
)
|
||||
|
||||
// LoggerConfigDefault is the default config
|
||||
var LoggerConfigDefault = LoggerConfig{
|
||||
Next: nil,
|
||||
Format: "#${pid} - ${time} ${status} - ${latency} ${method} ${path}\n",
|
||||
TimeFormat: "2006/01/02 15:04:05",
|
||||
TimeZone: "Local",
|
||||
Output: os.Stderr,
|
||||
}
|
||||
|
||||
/*
|
||||
Logger allows the following config arguments in any order:
|
||||
- Logger()
|
||||
- Logger(next func(*fiber.Ctx) bool)
|
||||
- Logger(output io.Writer)
|
||||
- Logger(format string)
|
||||
- Logger(timeZone string)
|
||||
- Logger(timeFormat string)
|
||||
- Logger(config LoggerConfig)
|
||||
*/
|
||||
func Logger(options ...interface{}) fiber.Handler {
|
||||
// Create default config
|
||||
var config = LoggerConfig{}
|
||||
// Assert options if provided to adjust the config
|
||||
if len(options) > 0 {
|
||||
for i := range options {
|
||||
switch opt := options[i].(type) {
|
||||
case func(*fiber.Ctx) bool:
|
||||
config.Next = opt
|
||||
case string:
|
||||
if strings.Contains(opt, "${") {
|
||||
config.Format = opt
|
||||
} else if tzl := getTimeZoneLocation(opt); tzl != nil {
|
||||
config.TimeZone = opt
|
||||
config.timeZoneLocation = tzl
|
||||
} else {
|
||||
config.TimeFormat = opt
|
||||
}
|
||||
case io.Writer:
|
||||
config.Output = opt
|
||||
case LoggerConfig:
|
||||
config = opt
|
||||
default:
|
||||
panic("Logger: the following option types are allowed: string, io.Writer, LoggerConfig")
|
||||
}
|
||||
}
|
||||
}
|
||||
// Return logger
|
||||
return logger(config)
|
||||
}
|
||||
|
||||
func logger(config LoggerConfig) fiber.Handler {
|
||||
// Set config default values
|
||||
if config.Format == "" {
|
||||
config.Format = LoggerConfigDefault.Format
|
||||
}
|
||||
if config.TimeZone == "" {
|
||||
config.TimeZone = LoggerConfigDefault.TimeZone
|
||||
}
|
||||
if config.TimeFormat == "" {
|
||||
config.TimeFormat = LoggerConfigDefault.TimeFormat
|
||||
}
|
||||
if config.Output == nil {
|
||||
// Check if colors should be disabled
|
||||
if os.Getenv("TERM") == "dumb" ||
|
||||
(!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) {
|
||||
config.Output = LoggerConfigDefault.Output
|
||||
} else {
|
||||
config.enableColors = true
|
||||
config.Output = colorable.NewColorableStderr()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var tmpl loggerTemplate
|
||||
tmpl.new(config.Format, "${", "}")
|
||||
|
||||
var timestamp atomic.Value
|
||||
timestamp.Store(nowTimeString(config.timeZoneLocation, config.TimeFormat))
|
||||
// Update date/time every 750 milliseconds in a separate go routine
|
||||
if strings.Contains(config.Format, "${time}") {
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(750 * time.Millisecond)
|
||||
timestamp.Store(nowTimeString(config.timeZoneLocation, config.TimeFormat))
|
||||
}
|
||||
}()
|
||||
}
|
||||
pid := fmt.Sprintf("%-5s", strconv.Itoa(os.Getpid()))
|
||||
// Return handler
|
||||
return func(c *fiber.Ctx) {
|
||||
// Don't execute the middleware if Next returns true
|
||||
if config.Next != nil && config.Next(c) {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
// Middleware logic...
|
||||
start := time.Now()
|
||||
// handle request
|
||||
c.Next()
|
||||
// build log
|
||||
stop := time.Now()
|
||||
// Get new buffer
|
||||
buf := bytebufferpool.Get()
|
||||
_, err := tmpl.executeFunc(buf, func(w io.Writer, tag string) (int, error) {
|
||||
switch tag {
|
||||
case LoggerTagTime:
|
||||
return buf.WriteString(timestamp.Load().(string))
|
||||
case LoggerTagReferer:
|
||||
return buf.WriteString(c.Get(fiber.HeaderReferer))
|
||||
case LoggerTagProtocol:
|
||||
return buf.WriteString(c.Protocol())
|
||||
case LoggerTagPid:
|
||||
return buf.WriteString(pid)
|
||||
case LoggerTagIP:
|
||||
return buf.WriteString(c.IP())
|
||||
case LoggerTagIPs:
|
||||
return buf.WriteString(c.Get(fiber.HeaderXForwardedFor))
|
||||
case LoggerTagHost:
|
||||
return buf.WriteString(c.Hostname())
|
||||
case LoggerTagPath:
|
||||
return buf.WriteString(c.Path())
|
||||
case LoggerTagURL:
|
||||
return buf.WriteString(c.OriginalURL())
|
||||
case LoggerTagUA:
|
||||
return buf.WriteString(c.Get(fiber.HeaderUserAgent))
|
||||
case LoggerTagLatency:
|
||||
return buf.WriteString(fmt.Sprintf("%-6s", stop.Sub(start).Round(1*time.Millisecond)))
|
||||
// return buf.WriteString(stop.Sub(start).String())
|
||||
case LoggerTagBody:
|
||||
return buf.WriteString(c.Body())
|
||||
case LoggerTagBytesReceived:
|
||||
return buf.WriteString(strconv.Itoa(len(c.Fasthttp.Request.Body())))
|
||||
case LoggerTagBytesSent:
|
||||
return buf.WriteString(strconv.Itoa(len(c.Fasthttp.Response.Body())))
|
||||
case LoggerTagRoute:
|
||||
return buf.WriteString(c.Route().Path)
|
||||
case LoggerTagError:
|
||||
if c.Error() != nil {
|
||||
return buf.WriteString(c.Error().Error())
|
||||
}
|
||||
case LoggerTagColorBlack:
|
||||
return buf.WriteString(cBlack)
|
||||
case LoggerTagColorRed:
|
||||
return buf.WriteString(cRed)
|
||||
case LoggerTagColorGreen:
|
||||
return buf.WriteString(cGreen)
|
||||
case LoggerTagColorYellow:
|
||||
return buf.WriteString(cYellow)
|
||||
case LoggerTagColorBlue:
|
||||
return buf.WriteString(cBlue)
|
||||
case LoggerTagColorMagenta:
|
||||
return buf.WriteString(cMagenta)
|
||||
case LoggerTagColorCyan:
|
||||
return buf.WriteString(cCyan)
|
||||
case LoggerTagColorWhite:
|
||||
return buf.WriteString(cWhite)
|
||||
case LoggerTagColorReset:
|
||||
return buf.WriteString(cReset)
|
||||
case LoggerTagStatus:
|
||||
responseStatus = c.Fasthttp.Response.StatusCode()
|
||||
if !config.enableColors {
|
||||
return buf.WriteString(strconv.Itoa(responseStatus))
|
||||
}
|
||||
switch {
|
||||
case responseStatus >= 200 && responseStatus < 300:
|
||||
statusColor = cGreen
|
||||
case responseStatus >= 300 && responseStatus < 400:
|
||||
statusColor = cBlue
|
||||
case responseStatus >= 400 && responseStatus < 500:
|
||||
statusColor = cYellow
|
||||
default:
|
||||
statusColor = cRed
|
||||
}
|
||||
return buf.WriteString(statusColor + strconv.Itoa(responseStatus) + cReset)
|
||||
case LoggerTagMethod:
|
||||
requestMethod = c.Method()
|
||||
if !config.enableColors {
|
||||
return buf.WriteString(requestMethod)
|
||||
}
|
||||
switch requestMethod {
|
||||
case fiber.MethodGet:
|
||||
methodColor = cGreen
|
||||
case fiber.MethodPost:
|
||||
methodColor = cCyan
|
||||
case fiber.MethodPut:
|
||||
methodColor = cYellow
|
||||
case fiber.MethodDelete:
|
||||
methodColor = cRed
|
||||
case fiber.MethodPatch:
|
||||
methodColor = cBlue
|
||||
case fiber.MethodHead:
|
||||
methodColor = cMagenta
|
||||
case fiber.MethodOptions:
|
||||
methodColor = cBlack
|
||||
default:
|
||||
methodColor = cReset
|
||||
}
|
||||
return buf.WriteString(fmt.Sprintf("%s%7s%s", methodColor, requestMethod, cReset))
|
||||
//return buf.WriteString(methodColor + requestMethod + cReset)
|
||||
default:
|
||||
switch {
|
||||
case strings.HasPrefix(tag, LoggerTagHeader):
|
||||
return buf.WriteString(c.Get(tag[7:]))
|
||||
case strings.HasPrefix(tag, LoggerTagQuery):
|
||||
return buf.WriteString(c.Query(tag[6:]))
|
||||
case strings.HasPrefix(tag, LoggerTagForm):
|
||||
return buf.WriteString(c.FormValue(tag[5:]))
|
||||
case strings.HasPrefix(tag, LoggerTagCookie):
|
||||
return buf.WriteString(c.Cookies(tag[7:]))
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
})
|
||||
if err != nil {
|
||||
_, _ = buf.WriteString(err.Error())
|
||||
}
|
||||
if _, err := config.Output.Write(buf.Bytes()); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
bytebufferpool.Put(buf)
|
||||
}
|
||||
}
|
||||
|
||||
func nowTimeString(tzl *time.Location, layout string) string {
|
||||
// This is different from Golang's time package which returns UTC, and Local is better than it
|
||||
if tzl == nil {
|
||||
return time.Now().Format(layout)
|
||||
}
|
||||
return time.Now().In(tzl).Format(layout)
|
||||
}
|
||||
|
||||
// Use Golang's time package to determine whether the TimeZone is available
|
||||
func getTimeZoneLocation(name string) *time.Location {
|
||||
tz, _ := time.LoadLocation(name)
|
||||
return tz
|
||||
}
|
||||
|
||||
// MIT License fasttemplate
|
||||
// Copyright (c) 2015 Aliaksandr Valialkin
|
||||
// https://github.com/valyala/fasttemplate/blob/master/LICENSE
|
||||
|
||||
type (
|
||||
loggerTemplate struct {
|
||||
template string
|
||||
startTag string
|
||||
endTag string
|
||||
texts [][]byte
|
||||
tags []string
|
||||
}
|
||||
loggerTagFunc func(w io.Writer, tag string) (int, error)
|
||||
)
|
||||
|
||||
func (t *loggerTemplate) new(template, startTag, endTag string) {
|
||||
t.template = template
|
||||
t.startTag = startTag
|
||||
t.endTag = endTag
|
||||
t.texts = t.texts[:0]
|
||||
t.tags = t.tags[:0]
|
||||
|
||||
if len(startTag) == 0 {
|
||||
panic("startTag cannot be empty")
|
||||
}
|
||||
if len(endTag) == 0 {
|
||||
panic("endTag cannot be empty")
|
||||
}
|
||||
|
||||
s := utils.GetBytes(template)
|
||||
a := utils.GetBytes(startTag)
|
||||
b := utils.GetBytes(endTag)
|
||||
|
||||
tagsCount := bytes.Count(s, a)
|
||||
if tagsCount == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if tagsCount+1 > cap(t.texts) {
|
||||
t.texts = make([][]byte, 0, tagsCount+1)
|
||||
}
|
||||
if tagsCount > cap(t.tags) {
|
||||
t.tags = make([]string, 0, tagsCount)
|
||||
}
|
||||
|
||||
for {
|
||||
n := bytes.Index(s, a)
|
||||
if n < 0 {
|
||||
t.texts = append(t.texts, s)
|
||||
break
|
||||
}
|
||||
t.texts = append(t.texts, s[:n])
|
||||
|
||||
s = s[n+len(a):]
|
||||
n = bytes.Index(s, b)
|
||||
if n < 0 {
|
||||
panic(fmt.Errorf("cannot find end tag=%q in the template=%q starting from %q", endTag, template, s))
|
||||
}
|
||||
|
||||
t.tags = append(t.tags, utils.GetString(s[:n]))
|
||||
s = s[n+len(b):]
|
||||
}
|
||||
}
|
||||
|
||||
func (t *loggerTemplate) executeFunc(w io.Writer, f loggerTagFunc) (int64, error) {
|
||||
var nn int64
|
||||
|
||||
n := len(t.texts) - 1
|
||||
if n == -1 {
|
||||
ni, err := w.Write(utils.GetBytes(t.template))
|
||||
return int64(ni), err
|
||||
}
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
ni, err := w.Write(t.texts[i])
|
||||
nn += int64(ni)
|
||||
if err != nil {
|
||||
return nn, err
|
||||
}
|
||||
|
||||
ni, err = f(w, t.tags[i])
|
||||
nn += int64(ni)
|
||||
if err != nil {
|
||||
return nn, err
|
||||
}
|
||||
}
|
||||
ni, err := w.Write(t.texts[n])
|
||||
nn += int64(ni)
|
||||
return nn, err
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
# Logger
|
||||
HTTP request/response logger for Fiber
|
||||
|
||||
### Example
|
||||
The middleware packages comes with the official Fiber framework.
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// ...
|
||||
|
||||
// Default Logger
|
||||
app.Use(middleware.Logger())
|
||||
|
||||
// Pass a custom output
|
||||
app.Use(middleware.Logger(os.Stdout))
|
||||
|
||||
// Pass a custom time zone
|
||||
app.Use(middleware.Logger("UTC"))
|
||||
|
||||
// Pass a custom timeformat
|
||||
app.Use(middleware.Logger("15:04:05"))
|
||||
|
||||
// Pass a custom format
|
||||
app.Use(middleware.Logger("${time} ${method} ${path}"))
|
||||
|
||||
// Pass a custom output + timeformat + format
|
||||
app.Use(middleware.Logger(os.Stdout, "15:04:05", "${time} ${method} ${path}"))
|
||||
|
||||
// Order does not matter
|
||||
app.Use(middleware.Logger("${time} ${method} ${path}", os.Stdout, "15:04:05"))
|
||||
|
||||
// Pass a custom config
|
||||
app.Use(middleware.Logger(middleware.LoggerConfig{
|
||||
Format: "${time} ${method} ${path}",
|
||||
TimeFormat: "15:04:05",
|
||||
TimeZone: "Asia/Chongqing",
|
||||
Output: os.Stdout,
|
||||
}))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Signature
|
||||
```go
|
||||
func Logger(options ...interface{}) fiber.Handler {}
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
type LoggerConfig struct {
|
||||
// Next defines a function to skip this middleware.
|
||||
Next func(ctx *fiber.Ctx) bool
|
||||
|
||||
// Format defines the logging tags
|
||||
//
|
||||
// - time
|
||||
// - ip
|
||||
// - ips
|
||||
// - url
|
||||
// - host
|
||||
// - method
|
||||
// - methodColor
|
||||
// - path
|
||||
// - protocol
|
||||
// - route
|
||||
// - referer
|
||||
// - ua
|
||||
// - latency
|
||||
// - status
|
||||
// - statusColor
|
||||
// - body
|
||||
// - error
|
||||
// - bytesSent
|
||||
// - bytesReceived
|
||||
// - header:<key>
|
||||
// - query:<key>
|
||||
// - form:<key>
|
||||
// - cookie:<key>
|
||||
// - <color> - e.g. black, red, blue, yellow, cyan, magenta, white, resetColor
|
||||
//
|
||||
// Optional. Default: ${time} ${method} ${path} - ${ip} - ${status} - ${latency}\n
|
||||
Format string
|
||||
|
||||
// TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html
|
||||
//
|
||||
// Optional. Default: 15:04:05
|
||||
TimeFormat string
|
||||
|
||||
// TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc
|
||||
//
|
||||
// Optional. Default: Local
|
||||
TimeZone string
|
||||
|
||||
// Output is a writter where logs are written
|
||||
//
|
||||
// Default: os.Stderr
|
||||
Output io.Writer
|
||||
}
|
||||
```
|
|
@ -0,0 +1,116 @@
|
|||
# Logger
|
||||
Logger middleware for [Fiber](https://github.com/gofiber/fiber) that logs HTTP request/response details.
|
||||
|
||||
### Table of Contents
|
||||
- [Signatures](#signatures)
|
||||
- [Examples](#examples)
|
||||
- [Config](#config)
|
||||
- [Default Config](#default-config)
|
||||
- [Constants](#constants)
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New(config ...Config) fiber.Handler
|
||||
```
|
||||
|
||||
### Examples
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
// Default middleware config
|
||||
app.Use(logger.New())
|
||||
|
||||
// Or extend your config for customization
|
||||
app.Use(logger.New(logger.Config{
|
||||
Format: "${pid} ${status} - ${method} ${path}\n",
|
||||
TimeFormat: "02-Jan-2006",
|
||||
TimeZone: "America/New_York",
|
||||
Output: os.Stdout,
|
||||
}))
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Format defines the logging tags
|
||||
//
|
||||
// Optional. Default: [${time}] ${status} - ${latency} ${method} ${path}\n
|
||||
Format string
|
||||
|
||||
// TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html
|
||||
//
|
||||
// Optional. Default: 15:04:05
|
||||
TimeFormat string
|
||||
|
||||
// TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc
|
||||
//
|
||||
// Optional. Default: "Local"
|
||||
TimeZone string
|
||||
// Output is a writter where logs are written
|
||||
//
|
||||
// Default: os.Stderr
|
||||
Output io.Writer
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Format: "[${time}] ${status} - ${latency} ${method} ${path}\n",
|
||||
TimeFormat: "15:04:05",
|
||||
TimeZone: "Local",
|
||||
Output: os.Stderr,
|
||||
}
|
||||
```
|
||||
|
||||
### Constants
|
||||
```go
|
||||
// Logger variables
|
||||
const (
|
||||
TagPid = "pid"
|
||||
TagTime = "time"
|
||||
TagReferer = "referer"
|
||||
TagProtocol = "protocol"
|
||||
TagIP = "ip"
|
||||
TagIPs = "ips"
|
||||
TagHost = "host"
|
||||
TagMethod = "method"
|
||||
TagPath = "path"
|
||||
TagURL = "url"
|
||||
TagUA = "ua"
|
||||
TagLatency = "latency"
|
||||
TagStatus = "status"
|
||||
TagBody = "body"
|
||||
TagBytesSent = "bytesSent"
|
||||
TagBytesReceived = "bytesReceived"
|
||||
TagRoute = "route"
|
||||
TagError = "error"
|
||||
TagHeader = "header:"
|
||||
TagQuery = "query:"
|
||||
TagForm = "form:"
|
||||
TagCookie = "cookie:"
|
||||
TagBlack = "black"
|
||||
TagRed = "red"
|
||||
TagGreen = "green"
|
||||
TagYellow = "yellow"
|
||||
TagBlue = "blue"
|
||||
TagMagenta = "magenta"
|
||||
TagCyan = "cyan"
|
||||
TagWhite = "white"
|
||||
TagReset = "reset"
|
||||
)
|
||||
```
|
|
@ -0,0 +1,277 @@
|
|||
package logger
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils/bytebufferpool"
|
||||
"github.com/gofiber/fiber/v2/utils/fasttemplate"
|
||||
)
|
||||
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Format defines the logging tags
|
||||
//
|
||||
// Optional. Default: [${time}] ${status} - ${latency} ${method} ${path}\n
|
||||
Format string
|
||||
|
||||
// TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html
|
||||
//
|
||||
// Optional. Default: 15:04:05
|
||||
TimeFormat string
|
||||
|
||||
// TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc
|
||||
//
|
||||
// Optional. Default: "Local"
|
||||
TimeZone string
|
||||
// Output is a writter where logs are written
|
||||
//
|
||||
// Default: os.Stderr
|
||||
Output io.Writer
|
||||
|
||||
haveLatency bool
|
||||
timeZoneLocation *time.Location
|
||||
}
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Format: "[${time}] ${status} - ${latency} ${method} ${path}\n",
|
||||
TimeFormat: "15:04:05",
|
||||
TimeZone: "Local",
|
||||
Output: os.Stderr,
|
||||
}
|
||||
|
||||
// Logger variables
|
||||
const (
|
||||
TagPid = "pid"
|
||||
TagTime = "time"
|
||||
TagReferer = "referer"
|
||||
TagProtocol = "protocol"
|
||||
TagIP = "ip"
|
||||
TagIPs = "ips"
|
||||
TagHost = "host"
|
||||
TagMethod = "method"
|
||||
TagPath = "path"
|
||||
TagURL = "url"
|
||||
TagUA = "ua"
|
||||
TagLatency = "latency"
|
||||
TagStatus = "status"
|
||||
TagBody = "body"
|
||||
TagBytesSent = "bytesSent"
|
||||
TagBytesReceived = "bytesReceived"
|
||||
TagRoute = "route"
|
||||
TagError = "error"
|
||||
TagHeader = "header:"
|
||||
TagQuery = "query:"
|
||||
TagForm = "form:"
|
||||
TagCookie = "cookie:"
|
||||
TagBlack = "black"
|
||||
TagRed = "red"
|
||||
TagGreen = "green"
|
||||
TagYellow = "yellow"
|
||||
TagBlue = "blue"
|
||||
TagMagenta = "magenta"
|
||||
TagCyan = "cyan"
|
||||
TagWhite = "white"
|
||||
TagReset = "reset"
|
||||
)
|
||||
|
||||
// Color values
|
||||
const (
|
||||
cBlack = "\u001b[90m"
|
||||
cRed = "\u001b[91m"
|
||||
cGreen = "\u001b[92m"
|
||||
cYellow = "\u001b[93m"
|
||||
cBlue = "\u001b[94m"
|
||||
cMagenta = "\u001b[95m"
|
||||
cCyan = "\u001b[96m"
|
||||
cWhite = "\u001b[97m"
|
||||
cReset = "\u001b[0m"
|
||||
)
|
||||
|
||||
// New creates a new middleware handler
|
||||
func New(config ...Config) fiber.Handler {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
|
||||
// Set default values
|
||||
if cfg.Next == nil {
|
||||
cfg.Next = ConfigDefault.Next
|
||||
}
|
||||
if cfg.Format == "" {
|
||||
cfg.Format = ConfigDefault.Format
|
||||
}
|
||||
if cfg.TimeZone == "" {
|
||||
cfg.TimeZone = ConfigDefault.TimeZone
|
||||
}
|
||||
if cfg.TimeFormat == "" {
|
||||
cfg.TimeFormat = ConfigDefault.TimeFormat
|
||||
}
|
||||
if cfg.Output == nil {
|
||||
cfg.Output = ConfigDefault.Output
|
||||
}
|
||||
}
|
||||
|
||||
// Get timezone location
|
||||
tz, err := time.LoadLocation(cfg.TimeZone)
|
||||
if err != nil || tz == nil {
|
||||
cfg.timeZoneLocation = time.Local
|
||||
} else {
|
||||
cfg.timeZoneLocation = tz
|
||||
}
|
||||
|
||||
// Check if format contains latency
|
||||
cfg.haveLatency = strings.Contains(cfg.Format, "${latency}")
|
||||
|
||||
// Create template parser
|
||||
tmpl := fasttemplate.New(cfg.Format, "${", "}")
|
||||
|
||||
// Create correct timeformat
|
||||
var timestamp atomic.Value
|
||||
timestamp.Store(time.Now().In(cfg.timeZoneLocation).Format(cfg.TimeFormat))
|
||||
|
||||
// Update date/time every 750 milliseconds in a separate go routine
|
||||
if strings.Contains(cfg.Format, "${time}") {
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(750 * time.Millisecond)
|
||||
timestamp.Store(time.Now().In(cfg.timeZoneLocation).Format(cfg.TimeFormat))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Set PID once
|
||||
pid := strconv.Itoa(os.Getpid())
|
||||
|
||||
// Set start and stop
|
||||
var start, stop time.Time
|
||||
|
||||
// Return new handler
|
||||
return func(c *fiber.Ctx) (err error) {
|
||||
// Don't execute middleware if Next returns true
|
||||
if cfg.Next != nil && cfg.Next(c) {
|
||||
return c.Next()
|
||||
}
|
||||
// Set latency start time
|
||||
if cfg.haveLatency {
|
||||
start = time.Now()
|
||||
}
|
||||
// Handle request, store err for logging
|
||||
err = c.Next()
|
||||
|
||||
// Set latency stop time
|
||||
if cfg.haveLatency {
|
||||
stop = time.Now()
|
||||
}
|
||||
|
||||
// Get new buffer
|
||||
buf := bytebufferpool.Get()
|
||||
|
||||
// Loop over template tags to replace it with the correct value
|
||||
_, err = tmpl.ExecuteFunc(buf, func(w io.Writer, tag string) (int, error) {
|
||||
switch tag {
|
||||
case TagTime:
|
||||
return buf.WriteString(timestamp.Load().(string))
|
||||
case TagReferer:
|
||||
return buf.WriteString(c.Get(fiber.HeaderReferer))
|
||||
case TagProtocol:
|
||||
return buf.WriteString(c.Protocol())
|
||||
case TagPid:
|
||||
return buf.WriteString(pid)
|
||||
case TagIP:
|
||||
return buf.WriteString(c.IP())
|
||||
case TagIPs:
|
||||
return buf.WriteString(c.Get(fiber.HeaderXForwardedFor))
|
||||
case TagHost:
|
||||
return buf.WriteString(c.Hostname())
|
||||
case TagPath:
|
||||
return buf.WriteString(c.Path())
|
||||
case TagURL:
|
||||
return buf.WriteString(c.OriginalURL())
|
||||
case TagUA:
|
||||
return buf.WriteString(c.Get(fiber.HeaderUserAgent))
|
||||
case TagLatency:
|
||||
return buf.WriteString(stop.Sub(start).String())
|
||||
case TagBody:
|
||||
return buf.Write(c.Body())
|
||||
case TagBytesReceived:
|
||||
return buf.WriteString(strconv.Itoa(len(c.Request().Body())))
|
||||
case TagBytesSent:
|
||||
return buf.WriteString(strconv.Itoa(len(c.Request().Body())))
|
||||
case TagRoute:
|
||||
return buf.WriteString(c.Route().Path)
|
||||
case TagStatus:
|
||||
return buf.WriteString(strconv.Itoa(c.Response().StatusCode()))
|
||||
case TagMethod:
|
||||
return buf.WriteString(c.Method())
|
||||
case TagBlack:
|
||||
return buf.WriteString(cBlack)
|
||||
case TagRed:
|
||||
return buf.WriteString(cRed)
|
||||
case TagGreen:
|
||||
return buf.WriteString(cGreen)
|
||||
case TagYellow:
|
||||
return buf.WriteString(cYellow)
|
||||
case TagBlue:
|
||||
return buf.WriteString(cBlue)
|
||||
case TagMagenta:
|
||||
return buf.WriteString(cMagenta)
|
||||
case TagCyan:
|
||||
return buf.WriteString(cCyan)
|
||||
case TagWhite:
|
||||
return buf.WriteString(cWhite)
|
||||
case TagReset:
|
||||
return buf.WriteString(cReset)
|
||||
case TagError:
|
||||
if err != nil {
|
||||
return buf.WriteString(err.Error())
|
||||
}
|
||||
return buf.WriteString("-")
|
||||
default:
|
||||
// Check if we have a value tag i.e.: "header:x-key"
|
||||
switch {
|
||||
case strings.HasPrefix(tag, TagHeader):
|
||||
return buf.WriteString(c.Get(tag[7:]))
|
||||
case strings.HasPrefix(tag, TagQuery):
|
||||
return buf.WriteString(c.Query(tag[6:]))
|
||||
case strings.HasPrefix(tag, TagForm):
|
||||
return buf.WriteString(c.FormValue(tag[5:]))
|
||||
case strings.HasPrefix(tag, TagCookie):
|
||||
return buf.WriteString(c.Cookies(tag[7:]))
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
})
|
||||
// Also write errors to the buffer
|
||||
if err != nil {
|
||||
_, _ = buf.WriteString(err.Error())
|
||||
}
|
||||
// Write buffer to output
|
||||
if _, err := cfg.Output.Write(buf.Bytes()); err != nil {
|
||||
// Write error to output
|
||||
if _, err := cfg.Output.Write([]byte(err.Error())); err != nil {
|
||||
// There is something wrong with the given io.Writer
|
||||
// TODO: What should we do here?
|
||||
}
|
||||
}
|
||||
// Put buffer back to pool
|
||||
bytebufferpool.Put(buf)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package logger
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"github.com/gofiber/fiber/v2/utils/bytebufferpool"
|
||||
)
|
||||
|
||||
// go test -run Test_Logger
|
||||
func Test_Logger(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
buf := bytebufferpool.Get()
|
||||
defer bytebufferpool.Put(buf)
|
||||
|
||||
app.Use(New(Config{
|
||||
Format: "${error}",
|
||||
Output: buf,
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return errors.New("some random error")
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusInternalServerError, resp.StatusCode)
|
||||
utils.AssertEqual(t, "some random error", buf.String())
|
||||
}
|
|
@ -1,218 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/utils"
|
||||
"github.com/valyala/bytebufferpool"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// go test -run Test_Middleware_Logger
|
||||
func Test_Middleware_Logger(t *testing.T) {
|
||||
format := "${ip}-${ips}-${url}-${host}-${method}-${path}-${protocol}-${route}-${referer}-${ua}-${status}-${body}-${error}-${bytesSent}-${bytesReceived}-${header:header}-${query:query}-${form:form}-${cookie:cookie}-${black}-${red}-${green}-${yellow}-${blue}-${magenta}-${cyan}-${white}-${resetColor}"
|
||||
expect := "0.0.0.0--/test?query=query-example.com-POST-/test-http-/test-ref-ua-500-form=form-error-5-9-header-query-form-cookie-\u001b[90m-\u001b[91m-\u001b[92m-\u001b[93m-\u001b[94m-\u001b[95m-\u001b[96m-\u001b[97m-\u001b[0m"
|
||||
|
||||
buf := bytebufferpool.Get()
|
||||
defer bytebufferpool.Put(buf)
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(Logger(LoggerConfig{
|
||||
Format: format,
|
||||
Output: buf,
|
||||
}))
|
||||
|
||||
app.Post("/test", func(ctx *fiber.Ctx) {
|
||||
ctx.Next(errors.New("error"))
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("POST", "/test?query=query", strings.NewReader("form=form"))
|
||||
req.Header.Set("header", "header")
|
||||
req.Header.Set("Cookie", "cookie=cookie")
|
||||
req.Header.Set("User-Agent", "ua")
|
||||
req.Header.Set("Referer", "ref")
|
||||
req.Header.Set("Content-type", "application/x-www-form-urlencoded")
|
||||
|
||||
resp, err := app.Test(req)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusInternalServerError, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, expect, buf.String())
|
||||
|
||||
}
|
||||
|
||||
func Test_Middleware_Logger_WithDefaultFormat(t *testing.T) {
|
||||
// fake output
|
||||
buf := bytebufferpool.Get()
|
||||
defer bytebufferpool.Put(buf)
|
||||
|
||||
LoggerConfigDefault.Output = buf
|
||||
config := LoggerConfigDefault
|
||||
config.Output = nil
|
||||
|
||||
app := fiber.New(&fiber.Settings{DisableStartupMessage: true})
|
||||
app.Use(Logger(config))
|
||||
|
||||
app.Get("/", func(ctx *fiber.Ctx) {
|
||||
ctx.SendStatus(fiber.StatusOK)
|
||||
})
|
||||
|
||||
_, err := app.Test(httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
res := buf.String()
|
||||
utils.AssertEqual(t, 48, len(res), fmt.Sprintf("Has length: %v, expected: %v, raw: %s", len(res), 48, res))
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_Logger_Skip
|
||||
func Test_Middleware_Logger_Skip(t *testing.T) {
|
||||
buf := bytebufferpool.Get()
|
||||
defer bytebufferpool.Put(buf)
|
||||
|
||||
LoggerConfigDefault.Output = buf
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(Logger(func(_ *fiber.Ctx) bool {
|
||||
return true
|
||||
}))
|
||||
|
||||
app.Get("/", func(_ *fiber.Ctx) {})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, 0, buf.Len(), "buf.Len()")
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_Logger_Options_And_WithConfig
|
||||
func Test_Middleware_Logger_Options_And_WithConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
buf := bytebufferpool.Get()
|
||||
defer bytebufferpool.Put(buf)
|
||||
|
||||
LoggerConfigDefault.Output = buf
|
||||
|
||||
loggers := []fiber.Handler{
|
||||
Logger(buf),
|
||||
Logger("15:04:05"),
|
||||
Logger("${time} ${method} ${path} - ${ip} - ${status} - ${latency}\n"),
|
||||
Logger(LoggerConfig{Output: buf}),
|
||||
Logger("UTC"),
|
||||
}
|
||||
|
||||
for i, logger := range loggers {
|
||||
buf.Reset()
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(logger)
|
||||
|
||||
app.Get("/", func(_ *fiber.Ctx) {})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
res := buf.String()
|
||||
|
||||
if i == 0 {
|
||||
utils.AssertEqual(t, 48, len(res), fmt.Sprintf("Has length: %v, expected: %v, raw: %s", len(res), 48, res))
|
||||
} else if i == 1 {
|
||||
utils.AssertEqual(t, 37, len(res), fmt.Sprintf("Has length: %v, expected: %v, raw: %s", len(res), 37, res))
|
||||
} else if i == 2 {
|
||||
utils.AssertEqual(t, 51, len(res), fmt.Sprintf("Has length: %v, expected: %v, raw: %s", len(res), 51, res))
|
||||
} else if i == 3 {
|
||||
utils.AssertEqual(t, 48, len(res), fmt.Sprintf("Has length: %v, expected: %v, raw: %s", len(res), 48, res))
|
||||
} else if i == 4 {
|
||||
utils.AssertEqual(t, 48, len(res), fmt.Sprintf("Has length: %v, expected: %v, raw: %s", len(res), 48, res))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_Logger_Panic
|
||||
func Test_Middleware_Logger_Panic(t *testing.T) {
|
||||
defer func() {
|
||||
utils.AssertEqual(t,
|
||||
"Logger: the following option types are allowed: string, io.Writer, LoggerConfig",
|
||||
fmt.Sprintf("%s", recover()))
|
||||
}()
|
||||
|
||||
Logger(0)
|
||||
}
|
||||
|
||||
func Test_isTimeZone(t *testing.T) {
|
||||
type args struct {
|
||||
name string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
"Empty",
|
||||
args{""},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Local",
|
||||
args{name: "Local"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"UTC",
|
||||
args{name: "UTC"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"America/New_York",
|
||||
args{name: "America/New_York"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Asia/Chongqing",
|
||||
args{"Asia/Chongqing"},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Time format",
|
||||
args{name: "2006-01-02 15:04:05"},
|
||||
false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
utils.AssertEqual(t, getTimeZoneLocation(tt.args.name) != nil, tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// go test -v -run=^$ -bench=Benchmark_Middleware_Logger -benchmem -count=4
|
||||
func Benchmark_Middleware_Logger(b *testing.B) {
|
||||
|
||||
buf := bytebufferpool.Get()
|
||||
defer bytebufferpool.Put(buf)
|
||||
|
||||
app := fiber.New()
|
||||
app.Use(Logger(LoggerConfig{
|
||||
Output: buf,
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {})
|
||||
handler := app.Handler()
|
||||
|
||||
c := &fasthttp.RequestCtx{}
|
||||
c.Request.SetRequestURI("/")
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for n := 0; n < b.N; n++ {
|
||||
handler(c)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
# Pprof
|
||||
Pprof middleware for [Fiber](https://github.com/gofiber/fiber) that serves via its HTTP server runtime profiling data in the format expected by the pprof visualization tool. The package is typically only imported for the side effect of registering its HTTP handlers. The handled paths all begin with /debug/pprof/.
|
||||
|
||||
- [Signatures](#signatures)
|
||||
- [Examples](#examples)
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New() fiber.Handler
|
||||
```
|
||||
|
||||
### Example
|
||||
Import the compress package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/pprof"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
// Default middleware
|
||||
app.Use(pprof.New())
|
||||
```
|
|
@ -1,11 +1,11 @@
|
|||
package middleware
|
||||
package pprof
|
||||
|
||||
import (
|
||||
"net/http/pprof"
|
||||
"strings"
|
||||
|
||||
fiber "github.com/gofiber/fiber"
|
||||
fasthttpadaptor "github.com/valyala/fasthttp/fasthttpadaptor"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/valyala/fasthttp/fasthttpadaptor"
|
||||
)
|
||||
|
||||
// Set pprof adaptors
|
||||
|
@ -23,44 +23,44 @@ var (
|
|||
pprofThreadcreate = fasthttpadaptor.NewFastHTTPHandlerFunc(pprof.Handler("threadcreate").ServeHTTP)
|
||||
)
|
||||
|
||||
// Pprof will enabling profiling
|
||||
func Pprof() fiber.Handler {
|
||||
// Return handler
|
||||
return func(c *fiber.Ctx) {
|
||||
// New creates a new middleware handler
|
||||
func New() fiber.Handler {
|
||||
// Return new handler
|
||||
return func(c *fiber.Ctx) error {
|
||||
path := c.Path()
|
||||
// We are only interested in /debug/pprof routes
|
||||
if len(path) < 12 || !strings.HasPrefix(path, "/debug/pprof") {
|
||||
c.Next()
|
||||
return
|
||||
return c.Next()
|
||||
}
|
||||
// Switch to original path without stripped slashes
|
||||
switch path {
|
||||
case "/debug/pprof/":
|
||||
c.Fasthttp.SetContentType(fiber.MIMETextHTML)
|
||||
pprofIndex(c.Fasthttp)
|
||||
c.Context().SetContentType(fiber.MIMETextHTML)
|
||||
pprofIndex(c.Context())
|
||||
case "/debug/pprof/cmdline":
|
||||
pprofCmdline(c.Fasthttp)
|
||||
pprofCmdline(c.Context())
|
||||
case "/debug/pprof/profile":
|
||||
pprofProfile(c.Fasthttp)
|
||||
pprofProfile(c.Context())
|
||||
case "/debug/pprof/symbol":
|
||||
pprofSymbol(c.Fasthttp)
|
||||
pprofSymbol(c.Context())
|
||||
case "/debug/pprof/trace":
|
||||
pprofTrace(c.Fasthttp)
|
||||
pprofTrace(c.Context())
|
||||
case "/debug/pprof/allocs":
|
||||
pprofAllocs(c.Fasthttp)
|
||||
pprofAllocs(c.Context())
|
||||
case "/debug/pprof/block":
|
||||
pprofBlock(c.Fasthttp)
|
||||
pprofBlock(c.Context())
|
||||
case "/debug/pprof/goroutine":
|
||||
pprofGoroutine(c.Fasthttp)
|
||||
pprofGoroutine(c.Context())
|
||||
case "/debug/pprof/heap":
|
||||
pprofHeap(c.Fasthttp)
|
||||
pprofHeap(c.Context())
|
||||
case "/debug/pprof/mutex":
|
||||
pprofMutex(c.Fasthttp)
|
||||
pprofMutex(c.Context())
|
||||
case "/debug/pprof/threadcreate":
|
||||
pprofThreadcreate(c.Fasthttp)
|
||||
pprofThreadcreate(c.Context())
|
||||
default:
|
||||
// pprof index only works with trailing slash
|
||||
c.Redirect("/debug/pprof/", 302)
|
||||
return c.Redirect("/debug/pprof/", 302)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
# Proxy
|
||||
Proxy middleware for [Fiber](https://github.com/gofiber/fiber) that allows you to proxy requests to multiple hosts.
|
||||
|
||||
### Table of Contents
|
||||
- [Signatures](#signatures)
|
||||
- [Examples](#examples)
|
||||
- [Config](#config)
|
||||
- [Default Config](#default-config)
|
||||
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New(config Config) fiber.Handler
|
||||
```
|
||||
|
||||
### Examples
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/proxy"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
// Minimal config
|
||||
app.Use(proxy.New(proxy.Config{
|
||||
Hosts: "gofiber.io:8080, gofiber.io:8081",
|
||||
}))
|
||||
|
||||
// Or extend your config for customization
|
||||
app.Use(proxy.New(proxy.Config{
|
||||
Hosts: "gofiber.io:8080, gofiber.io:8081",
|
||||
Before: func(c *fiber.Ctx) error {
|
||||
c.Set("X-Real-IP", c.IP())
|
||||
return nil
|
||||
},
|
||||
}))
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Comma-separated list of upstream HTTP server host addresses,
|
||||
// which are passed to Dial in a round-robin manner.
|
||||
//
|
||||
// Each address may contain port if default dialer is used.
|
||||
// For example,
|
||||
//
|
||||
// - foobar.com:80
|
||||
// - foobar.com:443
|
||||
// - foobar.com:8080
|
||||
Hosts string
|
||||
|
||||
// Before allows you to alter the request
|
||||
Before fiber.Handler
|
||||
|
||||
// After allows you to alter the response
|
||||
After fiber.Handler
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Hosts: "",
|
||||
Before: nil,
|
||||
After: nil,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,99 @@
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Comma-separated list of upstream HTTP server host addresses,
|
||||
// which are passed to Dial in a round-robin manner.
|
||||
//
|
||||
// Each address may contain port if default dialer is used.
|
||||
// For example,
|
||||
//
|
||||
// - foobar.com:80
|
||||
// - foobar.com:443
|
||||
// - foobar.com:8080
|
||||
Hosts string
|
||||
|
||||
// Before allows you to alter the request
|
||||
Before fiber.Handler
|
||||
|
||||
// After allows you to alter the response
|
||||
After fiber.Handler
|
||||
}
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
}
|
||||
|
||||
// New creates a new middleware handler
|
||||
func New(config Config) fiber.Handler {
|
||||
// Override config if provided
|
||||
cfg := config
|
||||
|
||||
// Set default values
|
||||
if cfg.Next == nil {
|
||||
cfg.Next = ConfigDefault.Next
|
||||
}
|
||||
if cfg.Hosts == "" {
|
||||
return func(c *fiber.Ctx) error {
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// Create host client
|
||||
// https://godoc.org/github.com/valyala/fasthttp#HostClient
|
||||
hostClient := fasthttp.HostClient{
|
||||
Addr: cfg.Hosts,
|
||||
NoDefaultUserAgentHeader: true,
|
||||
}
|
||||
|
||||
// Return new handler
|
||||
return func(c *fiber.Ctx) (err error) {
|
||||
// Don't execute middleware if Next returns true
|
||||
if cfg.Next != nil && cfg.Next(c) {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Set request and response
|
||||
req := c.Request()
|
||||
res := c.Response()
|
||||
|
||||
// Don't proxy "Connection" header
|
||||
req.Header.Del(fiber.HeaderConnection)
|
||||
|
||||
// Modify request
|
||||
if cfg.Before != nil {
|
||||
if err = cfg.Before(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Forward request
|
||||
if err = hostClient.Do(req, res); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Don't proxy "Connection" header
|
||||
res.Header.Del(fiber.HeaderConnection)
|
||||
|
||||
// Modify response
|
||||
if cfg.After != nil {
|
||||
if err = cfg.After(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Return nil to end proxying if no error
|
||||
return nil
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
)
|
||||
|
||||
// go test -run Test_Proxy_Empty_Host
|
||||
func Test_Proxy_Empty_Host(t *testing.T) {
|
||||
app := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
app.Use(New(
|
||||
Config{Hosts: ""},
|
||||
))
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Proxy_Next
|
||||
func Test_Proxy_Next(t *testing.T) {
|
||||
app := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
app.Use(New(Config{
|
||||
Hosts: "next",
|
||||
Next: func(_ *fiber.Ctx) bool {
|
||||
return true
|
||||
},
|
||||
}))
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Proxy
|
||||
func Test_Proxy(t *testing.T) {
|
||||
target := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
|
||||
target.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusTeapot)
|
||||
})
|
||||
|
||||
go func() {
|
||||
utils.AssertEqual(t, nil, target.Listen(":3001"))
|
||||
}()
|
||||
|
||||
resp, err := target.Test(httptest.NewRequest("GET", "/", nil), 2000)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusTeapot, resp.StatusCode)
|
||||
|
||||
app := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
|
||||
host := "localhost:3001"
|
||||
|
||||
app.Use(New(Config{
|
||||
Hosts: host,
|
||||
}))
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Host = host
|
||||
resp, err = app.Test(req)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusTeapot, resp.StatusCode)
|
||||
}
|
||||
|
||||
// go test -run Test_Proxy_Before_With_Error
|
||||
func Test_Proxy_Before_With_Error(t *testing.T) {
|
||||
app := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
|
||||
errStr := "error after Before"
|
||||
|
||||
app.Use(
|
||||
New(Config{
|
||||
Hosts: "host",
|
||||
Before: func(c *fiber.Ctx) error {
|
||||
return fmt.Errorf(errStr)
|
||||
},
|
||||
}))
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusInternalServerError, resp.StatusCode)
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, errStr, string(b))
|
||||
}
|
||||
|
||||
// go test -run Test_Proxy_After_With_Error
|
||||
func Test_Proxy_After_With_Error(t *testing.T) {
|
||||
target := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
|
||||
target.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusTeapot)
|
||||
})
|
||||
|
||||
go func() {
|
||||
utils.AssertEqual(t, nil, target.Listen(":3002"))
|
||||
}()
|
||||
|
||||
resp, err := target.Test(httptest.NewRequest("GET", "/", nil), 2000)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusTeapot, resp.StatusCode)
|
||||
|
||||
app := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
|
||||
host := "localhost:3001"
|
||||
errStr := "error after After"
|
||||
|
||||
app.Use(New(Config{
|
||||
Hosts: host,
|
||||
After: func(ctx *fiber.Ctx) error {
|
||||
utils.AssertEqual(t, fiber.StatusTeapot, ctx.Response().StatusCode())
|
||||
return fmt.Errorf(errStr)
|
||||
},
|
||||
}))
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Host = host
|
||||
resp, err = app.Test(req)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusInternalServerError, resp.StatusCode)
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, errStr, string(b))
|
||||
}
|
||||
|
||||
// go test -run Test_Proxy_Do_With_Error
|
||||
func Test_Proxy_Do_With_Error(t *testing.T) {
|
||||
app := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
|
||||
app.Use(
|
||||
New(Config{
|
||||
Hosts: "localhost:90000",
|
||||
}))
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusInternalServerError, resp.StatusCode)
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, true, strings.Contains(string(b), "127.0.0.1:90000"))
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
)
|
||||
|
||||
// Recover will recover from panics and calls the ErrorHandler
|
||||
func Recover() fiber.Handler {
|
||||
return func(ctx *fiber.Ctx) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err, ok := r.(error)
|
||||
if !ok {
|
||||
err = fmt.Errorf("%v", r)
|
||||
}
|
||||
ctx.Next(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
# Recover
|
||||
Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized [ErrorHandler](https://docs.gofiber.io/error-handling).
|
||||
|
||||
### Example
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default recover
|
||||
app.Use(middleware.Recover())
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func Recover() fiber.Handler {}
|
||||
```
|
|
@ -0,0 +1,52 @@
|
|||
# Recover
|
||||
Recover middleware for [Fiber](https://github.com/gofiber/fiber) that recovers from panics anywhere in the stack chain and handles the control to the centralized [ErrorHandler](https://docs.gofiber.io/error-handling).
|
||||
|
||||
### Table of Contents
|
||||
- [Signatures](#signatures)
|
||||
- [Examples](#examples)
|
||||
- [Config](#config)
|
||||
- [Default Config](#default-config)
|
||||
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New(config ...Config) fiber.Handler
|
||||
```
|
||||
|
||||
### Examples
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/recover"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
// Default middleware config
|
||||
app.Use(recover.New())
|
||||
|
||||
// This panic will be catch by the middleware
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
panic("I'm an error")
|
||||
})
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,58 @@
|
|||
package recover
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
}
|
||||
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
}
|
||||
|
||||
// New creates a new middleware handler
|
||||
func New(config ...Config) fiber.Handler {
|
||||
// Set default config
|
||||
cfg := ConfigDefault
|
||||
|
||||
// Override config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
|
||||
// Set default values
|
||||
if cfg.Next == nil {
|
||||
cfg.Next = ConfigDefault.Next
|
||||
}
|
||||
}
|
||||
|
||||
// Return new handler
|
||||
return func(c *fiber.Ctx) (err error) {
|
||||
// Don't execute middleware if Next returns true
|
||||
if cfg.Next != nil && cfg.Next(c) {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Catch panics
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
var ok bool
|
||||
if err, ok = r.(error); !ok {
|
||||
// Set error that will call the global error handler
|
||||
err = fmt.Errorf("%v", r)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Return err if exist, else move to next handler
|
||||
return c.Next()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package recover
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
)
|
||||
|
||||
// go test -run Test_Recover
|
||||
func Test_Recover(t *testing.T) {
|
||||
app := fiber.New(fiber.Config{
|
||||
ErrorHandler: func(c *fiber.Ctx, err error) error {
|
||||
utils.AssertEqual(t, "Hi, I'm an error!", err.Error())
|
||||
return c.SendStatus(fiber.StatusTeapot)
|
||||
},
|
||||
})
|
||||
|
||||
app.Use(New())
|
||||
|
||||
app.Get("/panic", func(c *fiber.Ctx) error {
|
||||
panic("Hi, I'm an error!")
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/panic", nil))
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, fiber.StatusTeapot, resp.StatusCode)
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/utils"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// go test -run Test_Middleware_Recover
|
||||
func Test_Middleware_Recover(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(Recover())
|
||||
|
||||
app.Get("/panic", func(ctx *fiber.Ctx) {
|
||||
ctx.Set("dummy", "this should be here")
|
||||
panic("Hi, I'm an error!")
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/panic", nil))
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, 500, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, "this should be here", resp.Header.Get("dummy"))
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, "Hi, I'm an error!", string(body))
|
||||
}
|
||||
|
||||
// go test -v -run=^$ -bench=Benchmark_Middleware_Recover -benchmem -count=4
|
||||
func Benchmark_Middleware_Recover(b *testing.B) {
|
||||
|
||||
app := fiber.New()
|
||||
app.Use(Recover())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {})
|
||||
handler := app.Handler()
|
||||
|
||||
c := &fasthttp.RequestCtx{}
|
||||
c.Request.SetRequestURI("/")
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for n := 0; n < b.N; n++ {
|
||||
handler(c)
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
fiber "github.com/gofiber/fiber"
|
||||
utils "github.com/gofiber/utils"
|
||||
)
|
||||
|
||||
// Middleware types
|
||||
type (
|
||||
// RequestIDConfig defines the config for Logger middleware.
|
||||
RequestIDConfig struct {
|
||||
// Next defines a function to skip this middleware.
|
||||
Next func(ctx *fiber.Ctx) bool
|
||||
|
||||
// Header is the header key where to get/set the unique ID
|
||||
// Optional. Default: X-Request-ID
|
||||
Header string
|
||||
|
||||
// Generator defines a function to generate the unique identifier.
|
||||
// Optional. Default: func() string {
|
||||
// return utils.UUID()
|
||||
// }
|
||||
Generator func() string
|
||||
}
|
||||
)
|
||||
|
||||
// RequestIDConfigDefault is the default config
|
||||
var RequestIDConfigDefault = RequestIDConfig{
|
||||
Next: nil,
|
||||
Header: fiber.HeaderXRequestID,
|
||||
Generator: func() string {
|
||||
return utils.UUID()
|
||||
},
|
||||
}
|
||||
|
||||
// RequestID adds an UUID indentifier to the request
|
||||
/*
|
||||
RequestID adds an UUID indentifier to the request, the following config arguments in any order:
|
||||
- RequestID()
|
||||
- RequestID(next func(*fiber.Ctx) bool)
|
||||
- RequestID(header string)
|
||||
- RequestID(generator func() string)
|
||||
- RequestID(config RequestIDConfig)
|
||||
*/
|
||||
func RequestID(options ...interface{}) fiber.Handler {
|
||||
// Create default config
|
||||
var config = RequestIDConfigDefault
|
||||
// Assert options if provided to adjust the config
|
||||
if len(options) > 0 {
|
||||
for i := range options {
|
||||
switch opt := options[i].(type) {
|
||||
case func(*fiber.Ctx) bool:
|
||||
config.Next = opt
|
||||
case string:
|
||||
config.Header = opt
|
||||
case func() string:
|
||||
config.Generator = opt
|
||||
case RequestIDConfig:
|
||||
config = opt
|
||||
default:
|
||||
panic("RequestID: the following option types are allowed: `string`, `func() string`, `func(*fiber.Ctx) bool`, `RequestIDConfig`")
|
||||
}
|
||||
}
|
||||
}
|
||||
// Return requestID
|
||||
return requestID(config)
|
||||
}
|
||||
|
||||
func requestID(config RequestIDConfig) fiber.Handler {
|
||||
// Set default values
|
||||
if config.Header == "" {
|
||||
config.Header = RequestIDConfigDefault.Header
|
||||
}
|
||||
if config.Generator == nil {
|
||||
config.Generator = RequestIDConfigDefault.Generator
|
||||
}
|
||||
|
||||
// Return handler
|
||||
return func(ctx *fiber.Ctx) {
|
||||
// Don't execute the middleware if Next returns true
|
||||
if config.Next != nil && config.Next(ctx) {
|
||||
ctx.Next()
|
||||
return
|
||||
}
|
||||
// Get id from request
|
||||
rid := ctx.Get(config.Header)
|
||||
// Create new UUID if empty
|
||||
if len(rid) <= 0 {
|
||||
rid = config.Generator()
|
||||
}
|
||||
// Set new id to response header
|
||||
ctx.Set(config.Header, rid)
|
||||
// Continue stack
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
# RequestID
|
||||
Adds an indentifier to the response using the `X-Request-ID` header
|
||||
|
||||
### Example
|
||||
Import the middleware package that is part of the Fiber web framework
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Default RequestID
|
||||
app.Use(middleware.RequestID())
|
||||
|
||||
// Custom Header
|
||||
app.Use(middleware.RequestID("X-Custom-Header"))
|
||||
|
||||
// Custom ID generator
|
||||
app.Use(middleware.RequestID(func() string {
|
||||
return "1234567890"
|
||||
}))
|
||||
|
||||
// Custom Config
|
||||
app.Use(middleware.RequestID(middleware.RequestIDConfig{
|
||||
Next: func(ctx *fiber.Ctx) bool {
|
||||
return ctx.Method() != fiber.MethodPost
|
||||
},
|
||||
Header: "X-Custom-Header",
|
||||
Generator: func() string {
|
||||
return "1234567890"
|
||||
},
|
||||
}))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func RequestID(options ...interface{}) fiber.Handler {}
|
||||
```
|
||||
|
||||
### Config
|
||||
```go
|
||||
type RequestIDConfig struct {
|
||||
// Next defines a function to skip this middleware.
|
||||
Next func(ctx *fiber.Ctx) bool
|
||||
|
||||
// Header is the header key where to get/set the unique ID
|
||||
// Optiona. Defaults: X-Request-ID
|
||||
Header string
|
||||
|
||||
// Generator defines a function to generate the unique identifier.
|
||||
// Optional. Default: func() string {
|
||||
// return utils.UUID()
|
||||
// }
|
||||
Generator func() string
|
||||
}
|
||||
```
|
|
@ -1,184 +0,0 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/utils"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
var (
|
||||
UUIDLen = 36
|
||||
)
|
||||
|
||||
// go test -run Test_Middleware_RequestID
|
||||
func Test_Middleware_RequestID(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(RequestID())
|
||||
|
||||
app.Get("/", func(ctx *fiber.Ctx) {
|
||||
ctx.Send("Hello?")
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
reqid := resp.Header.Get(fiber.HeaderXRequestID)
|
||||
utils.AssertEqual(t, UUIDLen, len(reqid))
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Add(fiber.HeaderXRequestID, reqid)
|
||||
|
||||
resp, err = app.Test(req)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, reqid, resp.Header.Get(fiber.HeaderXRequestID))
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_RequestID_Header
|
||||
func Test_Middleware_RequestID_Header(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(RequestID("X-Test-header"))
|
||||
|
||||
app.Get("/", func(ctx *fiber.Ctx) {
|
||||
ctx.Send("Hello?")
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
reqid := resp.Header.Get("X-Test-header")
|
||||
utils.AssertEqual(t, UUIDLen, len(reqid))
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Add("X-Test-header", reqid)
|
||||
|
||||
resp, err = app.Test(req)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, reqid, resp.Header.Get("X-Test-header"))
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_RequestID_Options_And_WithConfig
|
||||
func Test_Middleware_RequestID_Options_And_WithConfig(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
idLen int
|
||||
header string
|
||||
handler fiber.Handler
|
||||
}{
|
||||
{
|
||||
idLen: UUIDLen,
|
||||
header: "X-Test-header",
|
||||
handler: RequestID("X-Test-header"),
|
||||
},
|
||||
{
|
||||
idLen: 7,
|
||||
header: RequestIDConfigDefault.Header,
|
||||
handler: RequestID(func() string { return "fake-id" }),
|
||||
},
|
||||
{
|
||||
idLen: UUIDLen,
|
||||
header: RequestIDConfigDefault.Header,
|
||||
handler: RequestID(RequestIDConfig{}),
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(testCase.handler)
|
||||
|
||||
app.Get("/", func(ctx *fiber.Ctx) {
|
||||
ctx.Send("Hello?")
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
reqid := resp.Header.Get(testCase.header)
|
||||
utils.AssertEqual(t, testCase.idLen, len(reqid))
|
||||
}
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_RequestID_Config
|
||||
func Test_Middleware_RequestID_Config(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(RequestID(RequestIDConfig{
|
||||
Header: "X-Test-Header",
|
||||
Generator: func() string {
|
||||
return "johndoe"
|
||||
},
|
||||
}))
|
||||
|
||||
app.Get("/", func(ctx *fiber.Ctx) {
|
||||
ctx.Send("Hello?")
|
||||
})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
reqid := resp.Header.Get("X-Test-Header")
|
||||
utils.AssertEqual(t, "johndoe", reqid)
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Add(fiber.HeaderXRequestID, reqid)
|
||||
|
||||
resp, err = app.Test(req)
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, reqid, resp.Header.Get("X-Test-Header"))
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_RequestID_Skip
|
||||
func Test_Middleware_RequestID_Skip(t *testing.T) {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(RequestID(func(_ *fiber.Ctx) bool {
|
||||
return true
|
||||
}))
|
||||
|
||||
app.Get("/", func(ctx *fiber.Ctx) {})
|
||||
|
||||
resp, err := app.Test(httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
utils.AssertEqual(t, nil, err, "app.Test(req)")
|
||||
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode, "Status code")
|
||||
utils.AssertEqual(t, "", resp.Header.Get(RequestIDConfigDefault.Header), RequestIDConfigDefault.Header)
|
||||
}
|
||||
|
||||
// go test -run Test_Middleware_RequestID_Panic
|
||||
func Test_Middleware_RequestID_Panic(t *testing.T) {
|
||||
defer func() {
|
||||
utils.AssertEqual(t,
|
||||
"RequestID: the following option types are allowed: `string`, `func() string`, `func(*fiber.Ctx) bool`, `RequestIDConfig`",
|
||||
fmt.Sprintf("%s", recover()))
|
||||
}()
|
||||
|
||||
RequestID(0)
|
||||
}
|
||||
|
||||
// go test -v -run=^$ -bench=Benchmark_Middleware_RequestID -benchmem -count=4
|
||||
func Benchmark_Middleware_RequestID(b *testing.B) {
|
||||
|
||||
app := fiber.New()
|
||||
app.Use(RequestID())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {})
|
||||
handler := app.Handler()
|
||||
|
||||
c := &fasthttp.RequestCtx{}
|
||||
c.Request.SetRequestURI("/")
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for n := 0; n < b.N; n++ {
|
||||
handler(c)
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue