diff --git a/sidebars.js b/default_sidebars.js similarity index 84% rename from sidebars.js rename to default_sidebars.js index f52b5d1839b..f273fb3137d 100644 --- a/sidebars.js +++ b/default_sidebars.js @@ -12,10 +12,10 @@ // @ts-check /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const sidebars = { - tutorialSidebar: [ +const default_sidebars = { + left_sidebar: [ {type: 'autogenerated', dirName: '.'} ], }; -module.exports = sidebars; +module.exports = default_sidebars; diff --git a/docs/recipes/404-handler/README.md b/docs/recipes/404-handler/README.md new file mode 100644 index 00000000000..e46e7ec61cb --- /dev/null +++ b/docs/recipes/404-handler/README.md @@ -0,0 +1,73 @@ +# Custom 404 Not Found Handler Example + +This example demonstrates how to implement a custom 404 Not Found handler using the [Fiber](https://gofiber.io) web framework in Go. The purpose of this example is to show how to handle requests to undefined routes gracefully by returning a 404 status code. + +## Description + +In web applications, it's common to encounter requests to routes that do not exist. Handling these requests properly is important to provide a good user experience and to inform the user that the requested resource is not available. This example sets up a simple Fiber application with a custom 404 handler to manage such cases. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [Git](https://git-scm.com/downloads) + +## Running the Example + +To run the example, use the following command: +```bash +go run main.go +``` + +The server will start and listen on `localhost:3000`. + +## Example Routes + +- **GET /hello**: Returns a simple greeting message. +- **Undefined Routes**: Any request to a route not defined will trigger the custom 404 handler. + +## Custom 404 Handler + +The custom 404 handler is defined to catch all undefined routes and return a 404 status code with a "Not Found" message. + +## Code Overview + +### `main.go` + +```go +package main + +import ( + "log" + "github.com/gofiber/fiber/v2" +) + +func main() { + // Fiber instance + app := fiber.New() + + // Routes + app.Get("/hello", hello) + + // 404 Handler + app.Use(func(c *fiber.Ctx) error { + return c.SendStatus(404) // => 404 "Not Found" + }) + + // Start server + log.Fatal(app.Listen(":3000")) +} + +// Handler +func hello(c *fiber.Ctx) error { + return c.SendString("I made a โ˜• for you!") +} +``` + +## Conclusion + +This example provides a basic setup for handling 404 Not Found errors in a Fiber application. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Fiber Documentation](https://docs.gofiber.io) +- [GitHub Repository](https://github.com/gofiber/fiber) diff --git a/docs/recipes/README.md b/docs/recipes/README.md new file mode 100644 index 00000000000..f39f2ecae36 --- /dev/null +++ b/docs/recipes/README.md @@ -0,0 +1,85 @@ +--- +id: welcome +title: ๐Ÿ‘‹ Overview +sidebar_position: 1 +--- + +# ๐Ÿณ Examples for [Fiber](https://github.com/gofiber/fiber) + +**Welcome to the official Fiber cookbook**! + +Here you can find the most **delicious** recipes to cook delicious meals using our web framework. + +## ๐ŸŒฝ Table of contents + +- [Amazon Web Services (AWS) Elastic Beanstalk](./aws-eb) +- [AWS SAM](./aws-sam) +- [Certificates from Let's Encrypt](./autocert) +- [Clean Architecture](./clean-architecture) +- [Cloud Run](./cloud-run) +- [Colly Scraping using Fiber and PostgreSQL](./fiber-colly-gorm) +- [CSRF-with-Session](./csrf-with-session) +- [CSRF](./csrf) +- [Custom 404 Not Found](./404-handler) +- [Dependency Injection (with Parsley)](./parsley) +- [Docker MariaDB Clean Architecture](./docker-mariadb-clean-arch) +- [Docker Nginx Loadbalancer](./docker-nginx-loadbalancer) +- [Docker Postgres-JWT](./auth-docker-postgres-jwt) +- [DummyJson](./dummyjson/) +- [Enable HTTPS/TLS using PKCS12 store](./https-pkcs12-tls) +- [Enable HTTPS/TLS](./https-tls) +- [Enable Preforking](./prefork) +- [Ent Mysql Example](./ent-mysql) +- [Entgo Sveltekit](./entgo-sveltekit) +- [Firebase Functions](./firebase-functions) +- [GeoIP (with MaxMind databases)](./geoip-maxmind) +- [GeoIP](./geoip) +- [GORM Mysql Example](./gorm-mysql) +- [GORM](./gorm) +- [Graceful shutdown](./graceful-shutdown) +- [GraphQL](./graphql) +- [Hello, World!](./hello-world) +- [Heroku App](./heroku) +- [Hexagonal Architecture](./hexagonal) +- [i18n](./i18n) +- [JWT](./jwt) +- [Kubernetes](./k8s) +- [Listen on Multiple Ports](./multiple-ports) +- [Live Reloading (Air)](./air) +- [Memgraph](./memgraph) +- [MinIO](./minio) +- [MongoDB](./mongodb) +- [MVC Application Bootstrap](./fiber-bootstrap) +- [Netlify Functions](fiber-svelte-netlify) +- [OAuth2 Google](./oauth2-google) +- [PostgreSQL](./postgresql) +- [RabbitMQ](rabbitmq) +- [React Router](./react-router) +- [Recover from panic](./recover) +- [RSS feed](./rss-feed) +- [Serve Static Files](./file-server) +- [Server Timing](./server-timing) +- [Server-Sent Events](./sse) +- [Sessions-SQLite3](./sessions-sqlite3) +- [Single Page Application Example](./spa) +- [Socket.io](./socketio) +- [Sqlboiler](./sqlboiler) +- [Sqlc](./sqlc) +- [Streaming of the Request Body](./stream-request-body) +- [Sveltekit Embed](./sveltekit-embed) +- [Tableflip (Graceful updates)](./tableflip) +- [Template Asset Bundling](./template-asset-bundling) +- [Unit Test Example](./unit-test) +- [Upload Multiple Files](./upload-file/multiple) +- [Upload Single File](./upload-file/single) +- [URL shortener API](./url-shortener-api) +- [User Auth with JWT](./auth-jwt) +- [Validation](./validation) +- [Vercel](./vercel) +- [WebSocket Chat Example](./websocket-chat) +- [WebSockets](./websocket) + +## ๐Ÿ‘ฉโ€๐Ÿณ Have a delicious recipe? + +If you have found an amazing recipe for **Fiber** โ€” share it with others! +We are ready to accept your [PR](https://github.com/gofiber/recipes/pulls) and add your recipe to the cookbook (both on [website](https://docs.gofiber.io) and this repository). diff --git a/docs/recipes/air/README.md b/docs/recipes/air/README.md new file mode 100644 index 00000000000..fc0411d15ac --- /dev/null +++ b/docs/recipes/air/README.md @@ -0,0 +1,91 @@ +# Live Reloading with Air Example + +This example demonstrates how to set up live reloading for a Go application using the [Air](https://github.com/cosmtrek/air) tool. The purpose of this example is to show how to automatically reload your application during development whenever you make changes to the source code. + +## Description + +Live reloading is a useful feature during development as it saves time by automatically restarting the application whenever changes are detected. This example sets up a simple Fiber application and configures Air to watch for changes and reload the application. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [Git](https://git-scm.com/downloads) +- [Air](https://github.com/cosmtrek/air) + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/air + ``` + +2. Install the dependencies: + ```bash + go mod download + ``` + +3. Install Air: + ```bash + go install github.com/cosmtrek/air@latest + ``` + +## Configuration + +Air is configured using the `air/.air.conf` file. This file specifies the build command, binary name, and directories to watch for changes. The configuration files for different operating systems are provided: + +- `air/.air.windows.conf` for Windows +- `air/.air.linux.conf` for Linux + +## Running the Example + +To run the example with live reloading, use the following command: +```bash +air -c .air.linux.conf +``` +or for Windows: +```bash +air -c .air.windows.conf +``` + +The server will start and listen on `localhost:3000`. Any changes to the source code will automatically trigger a rebuild and restart of the application. + +## Example Routes + +- **GET /**: Returns a simple greeting message. + +## Code Overview + +### `main.go` + +```go +package main + +import ( + "log" + "github.com/gofiber/fiber/v2" +) + +func main() { + // Create new Fiber instance + app := fiber.New() + + // Create new GET route on path "/" + app.Get("/", func(c *fiber.Ctx) error { + return c.SendString("Hello, World!") + }) + + // Start server on http://localhost:3000 + log.Fatal(app.Listen(":3000")) +} +``` + +## Conclusion + +This example provides a basic setup for live reloading a Go application using Air. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Air Documentation](https://github.com/cosmtrek/air) +- [Fiber Documentation](https://docs.gofiber.io) +- [GitHub Repository](https://github.com/gofiber/fiber) diff --git a/docs/recipes/auth-docker-postgres-jwt/README.md b/docs/recipes/auth-docker-postgres-jwt/README.md new file mode 100644 index 00000000000..6027a0d7968 --- /dev/null +++ b/docs/recipes/auth-docker-postgres-jwt/README.md @@ -0,0 +1,87 @@ +# Auth Docker Postgres JWT Example + +This example demonstrates a boilerplate setup for a Go Fiber application that uses Docker, PostgreSQL, and JWT for authentication. + +## Description + +This project provides a starting point for building a web application with user authentication using JWT. It leverages Docker for containerization and PostgreSQL as the database. + +## Requirements + +- [Docker](https://www.docker.com/get-started) +- [Docker Compose](https://docs.docker.com/compose/install/) +- [Go](https://golang.org/dl/) 1.18 or higher + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/auth-docker-postgres-jwt + ``` + +2. Set the environment variables in a `.env` file: + ```env + DB_PORT=5432 + DB_USER=example_user + DB_PASSWORD=example_password + DB_NAME=example_db + SECRET=example_secret + ``` + +3. Build and start the Docker containers: + ```bash + docker-compose build + docker-compose up + ``` + +The API and the database should now be running. + +## Database Management + +You can manage the database via `psql` with the following command: +```bash +docker-compose exec db psql -U +``` + +Replace `` with the value from your `.env` file. + +## API Endpoints + +The following endpoints are available in the API: + +- **POST /api/auth/register**: Register a new user. +- **POST /api/auth/login**: Authenticate a user and return a JWT. +- **GET /api/user/:id**: Get a user (requires a valid JWT). +- **PATCH /api/user/:id**: Update a user (requires a valid JWT). +- **DELETE /api/user/:id**: Delete a user (requires a valid JWT). + +## Example Usage + +1. Register a new user: + ```bash + curl -X POST http://localhost:3000/api/auth/register -d '{"username":"testuser", "password":"testpassword"}' -H "Content-Type: application/json" + ``` + +2. Login to get a JWT: + ```bash + curl -X POST http://localhost:3000/api/auth/login -d '{"username":"testuser", "password":"testpassword"}' -H "Content-Type: application/json" + ``` + +3. Access a protected route: + ```bash + curl -H "Authorization: Bearer " http://localhost:3000/api/user/1 + ``` + +Replace `` with the token received from the login endpoint. + +## Conclusion + +This example provides a basic setup for a Go Fiber application with Docker, PostgreSQL, and JWT authentication. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Fiber Documentation](https://docs.gofiber.io) +- [Docker Documentation](https://docs.docker.com) +- [PostgreSQL Documentation](https://www.postgresql.org/docs/) +- [JWT Documentation](https://jwt.io/introduction/) diff --git a/docs/recipes/auth-jwt/README.md b/docs/recipes/auth-jwt/README.md new file mode 100644 index 00000000000..4be19a3e948 --- /dev/null +++ b/docs/recipes/auth-jwt/README.md @@ -0,0 +1,94 @@ +# Auth JWT Example + +This example demonstrates a boilerplate setup for a Go Fiber application that uses JWT for authentication. + +## Description + +This project provides a starting point for building a web application with user authentication using JWT. It leverages Fiber for the web framework and GORM for ORM. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [Git](https://git-scm.com/downloads) + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/auth-jwt + ``` + +2. Set the environment variables in a `.env` file: + ```env + DB_PORT=5432 + DB_USER=example_user + DB_PASSWORD=example_password + DB_NAME=example_db + SECRET=example_secret + ``` + +3. Install the dependencies: + ```bash + go mod download + ``` + +4. Run the application: + ```bash + go run main.go + ``` + +The API should now be running on `http://localhost:3000`. + +## Database Management + +You can manage the database via `psql` with the following command: +```bash +psql -U -d -h localhost -p +``` + +Replace ``, ``, and `` with the values from your `.env` file. + +## API Endpoints + +The following endpoints are available in the API: + +- **POST /api/auth/register**: Register a new user. +- **POST /api/auth/login**: Authenticate a user and return a JWT. +- **GET /api/user/:id**: Get a user (requires a valid JWT). +- **POST /api/user**: Create a new user. +- **PATCH /api/user/:id**: Update a user (requires a valid JWT). +- **DELETE /api/user/:id**: Delete a user (requires a valid JWT). +- **GET /api/product**: Get all products. +- **GET /api/product/:id**: Get a product. +- **POST /api/product**: Create a new product (requires a valid JWT). +- **DELETE /api/product/:id**: Delete a product (requires a valid JWT). + +## Example Usage + +1. Register a new user: + ```bash + curl -X POST http://localhost:3000/api/auth/register -d '{"username":"testuser", "password":"testpassword", "email":"test@example.com"}' -H "Content-Type: application/json" + ``` + +2. Login to get a JWT: + ```bash + curl -X POST http://localhost:3000/api/auth/login -d '{"username":"testuser", "password":"testpassword"}' -H "Content-Type: application/json" + ``` + +3. Access a protected route: + ```bash + curl -H "Authorization: Bearer " http://localhost:3000/api/user/1 + ``` + +Replace `` with the token received from the login endpoint. + +## Conclusion + +This example provides a basic setup for a Go Fiber application with JWT authentication. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Fiber Documentation](https://docs.gofiber.io) +- [GORM Documentation](https://gorm.io/docs/) +- [JWT Documentation](https://jwt.io/introduction/) diff --git a/docs/recipes/autocert/README.md b/docs/recipes/autocert/README.md new file mode 100644 index 00000000000..b2f2dec5da1 --- /dev/null +++ b/docs/recipes/autocert/README.md @@ -0,0 +1,57 @@ +# Autocert Example + +This example demonstrates how to set up a secure Go Fiber application using Let's Encrypt for automatic TLS certificate management with `autocert`. + +## Description + +This project provides a starting point for building a secure web application with automatic TLS certificate management using Let's Encrypt. It leverages Fiber for the web framework and `autocert` for certificate management. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [Git](https://git-scm.com/downloads) + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/autocert + ``` + +2. Install the dependencies: + ```bash + go mod download + ``` + +3. Update the `HostPolicy` in `main.go` with your domain: + ```go + m := &autocert.Manager{ + Prompt: autocert.AcceptTOS, + HostPolicy: autocert.HostWhitelist("yourdomain.com"), // Replace with your domain + Cache: autocert.DirCache("./certs"), + } + ``` + +4. Run the application: + ```bash + go run main.go + ``` + +The application should now be running on `https://localhost`. + +## Example Usage + +1. Open your browser and navigate to `https://yourdomain.com` (replace with your actual domain). + +2. You should see the message: `This is a secure server ๐Ÿ‘ฎ`. + +## Conclusion + +This example provides a basic setup for a Go Fiber application with automatic TLS certificate management using Let's Encrypt. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Fiber Documentation](https://docs.gofiber.io) +- [Let's Encrypt Documentation](https://letsencrypt.org/docs/) +- [Autocert Documentation](https://pkg.go.dev/golang.org/x/crypto/acme/autocert) diff --git a/docs/recipes/aws-eb/README.md b/docs/recipes/aws-eb/README.md new file mode 100644 index 00000000000..5fb8e770b8a --- /dev/null +++ b/docs/recipes/aws-eb/README.md @@ -0,0 +1,110 @@ +# AWS Elastic Beanstalk Example + +This example demonstrates how to deploy a Go Fiber application to AWS Elastic Beanstalk. + +## Description + +This project provides a starting point for deploying a Go Fiber application to AWS Elastic Beanstalk. It includes necessary configuration files and scripts to build and deploy the application. + +## Requirements + +- [AWS CLI](https://aws.amazon.com/cli/) +- [Elastic Beanstalk CLI](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install.html) +- [Go](https://golang.org/dl/) 1.18 or higher +- [Git](https://git-scm.com/downloads) + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/aws-eb + ``` + +2. Initialize Elastic Beanstalk: + ```bash + eb init + ``` + +3. Create an Elastic Beanstalk environment: + ```bash + eb create + ``` + +4. Deploy the application: + ```bash + eb deploy + ``` + +## Build Process + +The build process is defined in the `Buildfile` and `build.sh` scripts. + +- `Buildfile`: + ```ruby + make: ./build.sh + ``` + +- `build.sh`: + ```bash + #!/bin/bash -xe + # Get dependencies + go get -u github.com/gofiber/fiber/v2 + + # Build the binary + go build -o application application.go + + # Modify permissions to make the binary executable. + chmod +x application + ``` + +## Application Code + +The main application code is in `application.go`: +```go +package main + +import ( + "log" + "os" + + "github.com/gofiber/fiber/v2" +) + +func main() { + // Initialize the application + app := fiber.New() + + // Hello, World! + app.Get("/", func(c *fiber.Ctx) error { + return c.SendString("Hello, World!") + }) + + // Listen and Serve on 0.0.0.0:$PORT + port := os.Getenv("PORT") + if port == "" { + port = "5000" + } + + log.Fatal(app.Listen(":" + port)) +} +``` + +## .gitignore + +The `.gitignore` file includes configurations to ignore Elastic Beanstalk specific files: +```plaintext +# Elastic Beanstalk Files +.elasticbeanstalk/* +!.elasticbeanstalk/*.cfg.yml +!.elasticbeanstalk/*.global.yml +``` + +## Conclusion + +This example provides a basic setup for deploying a Go Fiber application to AWS Elastic Beanstalk. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [AWS Elastic Beanstalk Documentation](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/Welcome.html) +- [Fiber Documentation](https://docs.gofiber.io) diff --git a/docs/recipes/aws-sam-container/README.md b/docs/recipes/aws-sam-container/README.md new file mode 100644 index 00000000000..4d715970255 --- /dev/null +++ b/docs/recipes/aws-sam-container/README.md @@ -0,0 +1,123 @@ +# app + +This is a sample template for app - Below is a brief explanation of what we have generated for you: + +```bash +. +โ”œโ”€โ”€ README.md <-- This instructions file +โ”œโ”€โ”€ app <-- Source code for a lambda function +โ”‚ โ”œโ”€โ”€ main.go <-- Lambda function code +โ”‚ โ””โ”€โ”€ Dockerfile <-- Dockerfile +โ”œโ”€โ”€ samconfig.toml <-- SAM CLI configuration file +โ””โ”€โ”€ template.yaml +``` + +## Features + +- [x] Use distroless image to build, The image size is only a few MB. +- [x] Migrate to AWS SAM without changing your faber code using [aws-lambda-adapter](https://github.com/awslabs/aws-lambda-web-adapter). + +## Requirements + +* AWS CLI already configured with Administrator permission +* [Docker installed](https://www.docker.com/community-edition) +* SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) + +You may need the following for local testing. +* [Golang](https://golang.org) + +## Setup process + +### Installing dependencies & building the target + +In this example we use the built-in `sam build` to build a docker image from a Dockerfile and then copy the source of your application inside the Docker image. +Read more about [SAM Build here](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-build.html) + +### Local development + +**Invoking function locally through local API Gateway** + +```bash +docker run -it -p 80:3000 lambdafunction + +curl http://localhost +Hello, World! +``` + +## Packaging and deployment + +```bash +sam deploy --guided +``` + +The command will package and deploy your application to AWS, with a series of prompts: + +* **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. +* **AWS Region**: The AWS region you want to deploy your app to. +* **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. +* **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. +* **Save arguments to samconfig.toml**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application. + +You can find your API Gateway Endpoint URL in the output values displayed after deployment. + +## Add Permission to the Lambda Function for Public Access + +After deploying your Lambda function with an associated function URL, you might encounter a scenario where the function URL is not accessible due to missing permissions for public access. This is common when the authentication type for the function URL is set to "None," indicating that the function is intended to be publicly accessible without authentication. + +To ensure your Lambda function URL can be invoked publicly, you need to add the necessary permission that allows unauthenticated requests. This step is crucial when your function URL's authentication type is "None" but lacks the requisite permissions for public invocation. + +Manually Configuring Permissions +You can manually configure permissions through the AWS Lambda console by creating a resource-based policy that grants the lambda:invokeFunctionUrl permission to all principals (*). This approach is straightforward but not suitable for automation within deployment pipelines. + +Automating Permission Configuration +For a more automated approach, especially useful in CI/CD pipelines, you can use the AWS CLI or SDKs to add the necessary permissions after deploying your Lambda function. This can be incorporated into your deployment scripts or CI/CD workflows. + +Here is an example AWS CLI command that adds the required permission for public access to your Lambda function URL: + +```shell +aws lambda add-permission \ + --function-name \ + --action lambda:InvokeFunctionUrl \ + --principal "*" \ + --function-url-auth-type "NONE" \ + --statement-id unique-statement-id +``` + +This command grants permission to all principals (*) to invoke your Lambda function URL, enabling public access as intended. + +# Appendix + +### Golang installation + +Please ensure Go 1.x (where 'x' is the latest version) is installed as per the instructions on the official golang website: https://golang.org/doc/install + +A quickstart way would be to use Homebrew, chocolatey or your linux package manager. + +#### Homebrew (Mac) + +Issue the following command from the terminal: + +```shell +brew install golang +``` + +If it's already installed, run the following command to ensure it's the latest version: + +```shell +brew update +brew upgrade golang +``` + +#### Chocolatey (Windows) + +Issue the following command from the powershell: + +```shell +choco install golang +``` + +If it's already installed, run the following command to ensure it's the latest version: + +```shell +choco upgrade golang +``` \ No newline at end of file diff --git a/docs/recipes/aws-sam/README.md b/docs/recipes/aws-sam/README.md new file mode 100644 index 00000000000..7f4fd36c53b --- /dev/null +++ b/docs/recipes/aws-sam/README.md @@ -0,0 +1,147 @@ +# sam-app + +This is a sample template for sam-app - Below is a brief explanation of what we have generated for you: + +```bash +. +โ”œโ”€โ”€ README.md <-- This instructions file +โ”œโ”€โ”€ app <-- Source code for a lambda function +โ”‚ โ””โ”€โ”€ main.go <-- Lambda function code +โ””โ”€โ”€ template.yaml +``` + +## Requirements + +* AWS CLI already configured with Administrator permission +* [Docker installed](https://www.docker.com/community-edition) +* [Golang](https://golang.org) +* SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) + +## Setup process + +### Installing dependencies & building the target + +In this example we use the built-in `sam build` to automatically download all the dependencies and package our build target. +Read more about [SAM Build here](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-build.html) + +```shell +sam build --use-container +``` + +### Local development + +**Invoking function locally through local lambda invoke** + +```bash +sam local start-api + +curl -XPOST "http://localhost:3001/2015-03-31/functions/sam-app/invocations" +{"statusCode":200,"headers":null,"multiValueHeaders":{"Content-Type":["application/json"]},"body":"{\"message\":\"Hello World\"}"}% +``` + + + + +## Packaging and deployment + +AWS Lambda Golang runtime requires a flat folder with the executable generated on build step. SAM will use `CodeUri` property to know where to look up for the application: + +```yaml +... + FirstFunction: + Type: AWS::Serverless::Function + Properties: + CodeUri: app/ + ... +``` + +To deploy your application for the first time, run the following in your shell: + +```bash +sam deploy --guided +``` + +The command will package and deploy your application to AWS, with a series of prompts: + +* **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. +* **AWS Region**: The AWS region you want to deploy your app to. +* **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. +* **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. +* **Save arguments to samconfig.toml**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application. + +You can find your API Gateway Endpoint URL in the output values displayed after deployment. + + +## Add Permission to the Lambda Function for Public Access + +After deploying your Lambda function with an associated function URL, you might encounter a scenario where the function URL is not accessible due to missing permissions for public access. This is common when the authentication type for the function URL is set to "None," indicating that the function is intended to be publicly accessible without authentication. + +To ensure your Lambda function URL can be invoked publicly, you need to add the necessary permission that allows unauthenticated requests. This step is crucial when your function URL's authentication type is "None" but lacks the requisite permissions for public invocation. + +Manually Configuring Permissions +You can manually configure permissions through the AWS Lambda console by creating a resource-based policy that grants the lambda:invokeFunctionUrl permission to all principals (*). This approach is straightforward but not suitable for automation within deployment pipelines. + +Automating Permission Configuration +For a more automated approach, especially useful in CI/CD pipelines, you can use the AWS CLI or SDKs to add the necessary permissions after deploying your Lambda function. This can be incorporated into your deployment scripts or CI/CD workflows. + +Here is an example AWS CLI command that adds the required permission for public access to your Lambda function URL: + +```shell +aws lambda add-permission \ + --function-name \ + --action lambda:InvokeFunctionUrl \ + --principal "*" \ + --function-url-auth-type "NONE" \ + --statement-id unique-statement-id +``` + +This command grants permission to all principals (*) to invoke your Lambda function URL, enabling public access as intended. + +# Appendix + +### Golang installation + +Please ensure Go 1.x (where 'x' is the latest version) is installed as per the instructions on the official golang website: https://golang.org/doc/install + +A quickstart way would be to use Homebrew, chocolatey or your linux package manager. + +#### Homebrew (Mac) + +Issue the following command from the terminal: + +```shell +brew install golang +``` + +If it's already installed, run the following command to ensure it's the latest version: + +```shell +brew update +brew upgrade golang +``` + +#### Chocolatey (Windows) + +Issue the following command from the powershell: + +```shell +choco install golang +``` + +If it's already installed, run the following command to ensure it's the latest version: + +```shell +choco upgrade golang +``` + +## Bringing to the next level + +Here are a few ideas that you can use to get more acquainted as to how this overall process works: + +* Create an additional API resource (e.g. `/hello/{proxy+}`) and return the name requested through this new path +* Update unit test to capture that +* Package & Deploy + +Next, you can use the following resources to know more about beyond hello world samples and how others structure their Serverless applications: + +* [AWS Serverless Application Repository](https://aws.amazon.com/serverless/serverlessrepo/) diff --git a/docs/recipes/clean-architecture/README.md b/docs/recipes/clean-architecture/README.md new file mode 100644 index 00000000000..18692b840e0 --- /dev/null +++ b/docs/recipes/clean-architecture/README.md @@ -0,0 +1,201 @@ +# Clean Architecture Example + +This example demonstrates a Go Fiber application following the principles of Clean Architecture. + +## Description + +This project provides a starting point for building a web application with a clean architecture. It leverages Fiber for the web framework, MongoDB for the database, and follows the Clean Architecture principles to separate concerns and improve maintainability. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [MongoDB](https://www.mongodb.com/try/download/community) +- [Git](https://git-scm.com/downloads) + +## Project Structure + +- `api/`: Contains the HTTP handlers, routes, and presenters. +- `pkg/`: Contains the core business logic and entities. +- `cmd/`: Contains the main application entry point. + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/clean-architecture + ``` + +2. Set the environment variables in a `.env` file: + ```env + DB_URI=mongodb://localhost:27017 + DB_NAME=example_db + ``` + +3. Install the dependencies: + ```bash + go mod download + ``` + +4. Run the application: + ```bash + go run cmd/main.go + ``` + +The API should now be running on `http://localhost:3000`. + +## API Endpoints + +The following endpoints are available in the API: + +- **GET /books**: List all books. +- **POST /books**: Add a new book. +- **PUT /books**: Update an existing book. +- **DELETE /books**: Remove a book. + +## Example Usage + +1. Add a new book: + ```bash + curl -X POST http://localhost:3000/books -d '{"title":"Book Title", "author":"Author Name"}' -H "Content-Type: application/json" + ``` + +2. List all books: + ```bash + curl http://localhost:3000/books + ``` + +3. Update a book: + ```bash + curl -X PUT http://localhost:3000/books -d '{"id":"", "title":"Updated Title", "author":"Updated Author"}' -H "Content-Type: application/json" + ``` + +4. Remove a book: + ```bash + curl -X DELETE http://localhost:3000/books -d '{"id":""}' -H "Content-Type: application/json" + ``` + +Replace `` with the actual ID of the book. + +## Clean Architecture Principles + +Clean Architecture is a software design philosophy that emphasizes the separation of concerns, making the codebase more maintainable, testable, and scalable. In this example, the Go Fiber application follows Clean Architecture principles by organizing the code into distinct layers, each with its own responsibility. + +### Layers in Clean Architecture + +1. **Entities (Core Business Logic)** + - Located in the `pkg/entities` directory. + - Contains the core business logic and domain models, which are independent of any external frameworks or technologies. + +2. **Use Cases (Application Logic)** + - Located in the `pkg/book` directory. + - Contains the application-specific business rules and use cases. This layer orchestrates the flow of data to and from the entities. + +3. **Interface Adapters (Adapters and Presenters)** + - Located in the `api` directory. + - Contains the HTTP handlers, routes, and presenters. This layer is responsible for converting data from the use cases into a format suitable for the web framework (Fiber in this case). + +4. **Frameworks and Drivers (External Interfaces)** + - Located in the `cmd` directory. + - Contains the main application entry point and any external dependencies like the web server setup. + +### Example Breakdown + +- **Entities**: The `entities.Book` struct represents the core business model for a book. +- **Use Cases**: The `book.Service` interface defines the methods for interacting with books, such as `InsertBook`, `UpdateBook`, `RemoveBook`, and `FetchBooks`. +- **Interface Adapters**: The `handlers` package contains the HTTP handlers that interact with the `book.Service` to process HTTP requests and responses. +- **Frameworks and Drivers**: The `cmd/main.go` file initializes the Fiber application and sets up the routes using the `routes.BookRouter` function. + +### Code Example + +#### `entities/book.go` +```go +package entities + +import "go.mongodb.org/mongo-driver/bson/primitive" + +type Book struct { + ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` + Title string `json:"title"` + Author string `json:"author"` +} +``` + +#### `pkg/book/service.go` +```go +package book + +import "clean-architecture/pkg/entities" + +type Service interface { + InsertBook(book *entities.Book) (*entities.Book, error) + UpdateBook(book *entities.Book) (*entities.Book, error) + RemoveBook(id primitive.ObjectID) error + FetchBooks() ([]*entities.Book, error) +} +``` + +#### `api/handlers/book_handler.go` +```go +package handlers + +import ( + "clean-architecture/pkg/book" + "clean-architecture/pkg/entities" + "clean-architecture/api/presenter" + "github.com/gofiber/fiber/v2" + "net/http" + "errors" +) + +func AddBook(service book.Service) fiber.Handler { + return func(c *fiber.Ctx) error { + var requestBody entities.Book + err := c.BodyParser(&requestBody) + if err != nil { + c.Status(http.StatusBadRequest) + return c.JSON(presenter.BookErrorResponse(err)) + } + if requestBody.Author == "" || requestBody.Title == "" { + c.Status(http.StatusInternalServerError) + return c.JSON(presenter.BookErrorResponse(errors.New("Please specify title and author"))) + } + result, err := service.InsertBook(&requestBody) + if err != nil { + c.Status(http.StatusInternalServerError) + return c.JSON(presenter.BookErrorResponse(err)) + } + return c.JSON(presenter.BookSuccessResponse(result)) + } +} +``` + +#### `cmd/main.go` +```go +package main + +import ( + "clean-architecture/api/routes" + "clean-architecture/pkg/book" + "github.com/gofiber/fiber/v2" +) + +func main() { + app := fiber.New() + bookService := book.NewService() // Assume NewService is a constructor for the book service + routes.BookRouter(app, bookService) + app.Listen(":3000") +} +``` + +By following Clean Architecture principles, this example ensures that each layer is independent and can be modified or replaced without affecting the other layers, leading to a more maintainable and scalable application. + +## Conclusion + +This example provides a basic setup for a Go Fiber application following Clean Architecture principles. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Fiber Documentation](https://docs.gofiber.io) +- [MongoDB Documentation](https://docs.mongodb.com/) +- [Clean Architecture](https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html) diff --git a/docs/recipes/cloud-run/README.md b/docs/recipes/cloud-run/README.md new file mode 100644 index 00000000000..8461d15e44a --- /dev/null +++ b/docs/recipes/cloud-run/README.md @@ -0,0 +1,109 @@ +# Cloud Run Example + +This example demonstrates how to deploy a Go Fiber application to Google Cloud Run. + +## Description + +This project provides a starting point for deploying a Go Fiber application to Google Cloud Run. It includes necessary configuration files and scripts to build and deploy the application using Docker and Google Cloud Build. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [Docker](https://www.docker.com/get-started) +- [Google Cloud SDK](https://cloud.google.com/sdk/docs/install) +- [Git](https://git-scm.com/downloads) + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/cloud-run + ``` + +2. Install the dependencies: + ```bash + go mod download + ``` + +3. Build the Docker image: + ```bash + docker build -t cloud-run-example . + ``` + +4. Run the Docker container: + ```bash + docker run -p 3000:3000 cloud-run-example + ``` + +The application should now be running on `http://localhost:3000`. + +## Deploy to Google Cloud Run + +1. Set up Google Cloud SDK and authenticate: + ```bash + gcloud auth login + gcloud config set project [YOUR_PROJECT_ID] + ``` + +2. Build and push the Docker image using Google Cloud Build: + ```bash + gcloud builds submit --tag gcr.io/[YOUR_PROJECT_ID]/cloud-run-example + ``` + +3. Deploy the image to Cloud Run: + ```bash + gcloud run deploy cloud-run-example --image gcr.io/[YOUR_PROJECT_ID]/cloud-run-example --platform managed --region [YOUR_REGION] --allow-unauthenticated + ``` + +Replace `[YOUR_PROJECT_ID]` and `[YOUR_REGION]` with your Google Cloud project ID and desired region. + +## Cloud Build Configuration + +The `cloudbuild.yaml` file defines the steps to build and deploy the application using Google Cloud Build: + +```yaml +steps: + - name: 'gcr.io/kaniko-project/executor:latest' + id: 'build-and-push' + args: + - '--destination=asia.gcr.io/$PROJECT_ID/$_SERVICE_NAME:$SHORT_SHA' + - '--destination=asia.gcr.io/$PROJECT_ID/$_SERVICE_NAME:latest' + - '--dockerfile=Dockerfile' + - '--context=.' + - '--cache=true' + - '--cache-ttl=120h' + + - id: 'Deploy to Cloud Run' + name: 'gcr.io/cloud-builders/gcloud' + entrypoint: 'bash' + args: + - '-c' + - | + gcloud run deploy $_SERVICE_NAME \ + --image=asia.gcr.io/$PROJECT_ID/$_SERVICE_NAME:$SHORT_SHA \ + --region=$_REGION --platform managed --allow-unauthenticated \ + --port=3000 +options: + substitutionOption: ALLOW_LOOSE + +substitutions: + _SERVICE_NAME: cloud-run-example + _REGION: asia-southeast1 +``` + +## Example Usage + +1. Open your browser and navigate to the Cloud Run service URL provided after deployment. + +2. You should see the message: `Hello, World!`. + +## Conclusion + +This example provides a basic setup for deploying a Go Fiber application to Google Cloud Run. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Google Cloud Run Documentation](https://cloud.google.com/run/docs) +- [Fiber Documentation](https://docs.gofiber.io) +- [Docker Documentation](https://docs.docker.com/) diff --git a/docs/recipes/csrf-with-session/README.md b/docs/recipes/csrf-with-session/README.md new file mode 100644 index 00000000000..6d79710c849 --- /dev/null +++ b/docs/recipes/csrf-with-session/README.md @@ -0,0 +1,118 @@ +# CSRF-with-session Example + +Example GoFiber web app using Cross Site Request Forgery (CSRF) middleware with session. + +This example impliments multiple best-practices for CSRF protection: + +- CSRF Tokens are linked to the user's session. +- Pre-sessions are used, so that CSRF tokens are always available, even for anonymous users (eg for login forms). +- Cookies are set with a defense-in-depth approach: + - Secure: true + - HttpOnly: true + - SameSite: Lax + - Expiration: 30 minutes (of inactivity) + - Cookie names are prefixed with "__Host-" (see [MDN-Set-Cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) for more information)) + +## Requirements + +* [git](https://git-scm.com/downloads) +* [Golang](https://golang.org/) + + +## Install Go Modules + +Like any golang project, you will need to download and install the required modules for the project to run. Change into the "csrf-with-session" directory: +```bash +cd csrf-with-session +``` + +And then: +```bash +go mod vendor && go mod download && go mod tidy +``` +This command installs the golang dependencies needed to run the project in a new directory named `vendor`. + +Once the modules have finished installing, you can run the project like this: +```bash +go run main.go +``` + +You should see the following if everything is OK: +``` +Server started and listening at 127.0.0.1:8443 +``` + +## Try the demo + +Start the server by running: +```bash +go run main.go +``` +Open your browser to and navigate to [127.0.0.1:8443](http://127.0.0.1:8443). + + +### Accept the self-signed certificate warning and visit the site. + +In Chrome: + +- Click on "Advanced" +- Click on "Proceed to 127.0.0.1:8443 (unsafe)" + +In Firefox: + +- Click on "Advanced" +- Click on "Accept the Risk and Continue" + +In Safari: + +- Click on "Show Details" +- Click on "visit this website" + + +### Try to access the /protected page + +Login using one of the test accounts: +* Username: `user1` +* Password: `password1` +OR +* Username: `user2` +* Password: `password2` + +Once logged in, you will be able to see the /protected page. + + +### Submit the form on the /protected page + +Once logged in, you will be able to see the /protected page. The /protected page contains a form that submits to the /protected page. If you try to submit the form without a valid CSRF token, you will get a 403 Forbidden error. + + +## CSRF Protection + +All methods except GET, HEAD, OPTIONS, and TRACE are checked for the CSRF token. If the token is not present or does not match the token in the session, the request is aborted with a 403 Forbidden error. + + +## Token Lifecycle + +The CSRF token is generated when the user visits any page on the site. The token is stored in the session and is valid for until it expires, or the authorization scope changes (e.g. the user logs in, or logs out). + +It is important that CSRF tokens do not persist beyond the scope of the user's session, that a new session is created when the user logs in, and that the session is destroyed when the user logs out. + +The CSRF middleware has a `SingleUseToken` configuration option that can be used to generate a new token for each request. This is useful for some applications, but is not used in this example. Single use tokens have usability implications in scenarios where the user has multiple tabs open, or when the user uses the back button in their browser. + + +## Session Storage + +Sessions are stored in memory for this example, but you can use any session store you like. See the [Fiber session documentation](https://docs.gofiber.io/api/middleware/session) for more information. + + +### Note on pre-sessions + +GoFiber's CSRF middleware will automatically create a session if one does not exist. That means that we always have pre-sessions when using the CSRF middleware. In this example we set a session variable `loggedIn` +to `true` when the user logs in, in order to distinguish between logged in and logged out users. + + +## Going further + +Here are some useful links where you can learn more about this topic: +* https://en.wikipedia.org/wiki/Cross-site_request_forgery +* https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) diff --git a/docs/recipes/csrf/README.md b/docs/recipes/csrf/README.md new file mode 100644 index 00000000000..6f2b38596d0 --- /dev/null +++ b/docs/recipes/csrf/README.md @@ -0,0 +1,72 @@ +# CSRF Examples + +Example Cross Site Request Forgery (CSRF) vulnerabilities in action. + + +## Requirements + +* [git](https://git-scm.com/downloads) +* [Golang](https://golang.org/) + + +## Install Go Modules + +Like any golang project, you will need to download and install the required modules for the project to run. Change into the "csrf" directory: +```bash +cd csrf +``` + +And then: +```bash +go mod vendor && go mod download && go mod tidy +``` +This command installs the golang dependencies needed to run the project in a new directory named `vendor`. + +Once the modules have finished installing, you can run the project like this: +```bash +go run main.go +``` +OR +```bash +go run main.go withoutCsrf +``` + +You should see the following if everything is OK: +``` +Server started and listening at localhost:3000 +``` + +## Try the demo + +Start the server without csrf, to see the dangers of these attacks +```bash +go run main.go withoutCsrf +``` +Open your browser to and navigate to [localhost:3000](http://localhost:3000). + +Login using the test account: +* Username: `bob` +* Password: `test` + +In a new tab, navigate to [localhost:3001](http://localhost:3001) to view some examples of CSRF exploits. You will notice that the balance goes down everytime you load that page. This is because the page is successfully exploiting a CSRF vulnerability. + + +## See the "fixed" version + +To see the csrf version of this demo, just stop the server by pressing __CTRL + C__ to kill the server process and then run +```bash +go run main.go +``` + +Navigate again to [localhost:3000](http://localhost:3000) and login to the test account. + +And once more try the page with the CSRF exploits: [localhost:3001](http://localhost:3001). + +You will notice now that the account balance is unchanged. + + +## Going further + +Here are some useful links where you can learn more about this topic: +* https://en.wikipedia.org/wiki/Cross-site_request_forgery +* https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) diff --git a/docs/recipes/docker-mariadb-clean-arch/README.md b/docs/recipes/docker-mariadb-clean-arch/README.md new file mode 100644 index 00000000000..4dcec90b2af --- /dev/null +++ b/docs/recipes/docker-mariadb-clean-arch/README.md @@ -0,0 +1,193 @@ +# Docker MariaDB Clean Architecture + +A slightly complex REST application with Fiber to showcase Clean Architecture with MariaDB as a dependency with Docker. + +## Prerequisites + +- Docker Compose for running the application. +- Shell that supports `sh`, `make`, and `curl` for end-to-end testing. UNIX systems or WSL should work fine. +- Postman if you want to test this API with GUI. + +## Application + +This application is a slightly complex example of a REST API that have four major endpoints. A public user can access the `User`, `Auth`, and `Misc` major endpoints, but they cannot access the `City` endpoint (as it is protected). If one wants to access said endpoint, they have to log in first via the `Auth` endpoint, and only after that they can access the `City` endpoint. + +This application uses MariaDB as a database (dockerized), and JWT as an authentication mechanism. This application also showcases how to perform 1-to-many relational mapping in Clean Architecture (one user can have multiple cities), and also the implementation of `JOIN` SQL clause in Go in general. + +## Clean Architecture + +![Clean Architecture](./assets/CleanArchitecture.jpg) + +Clean Architecture is a concept introduced by Robert C. Martin or also known as Uncle Bob. Simply put, the purpose of this architecture is to perform complete separation of concerns. Systems made this way can be independent of frameworks, testable (easy to write unit tests), independent of UI, independent of database, and independent of any external agency. When you use this architecture, it is simple to change the UI, the database, or the business logic. + +One thing that you should keep in mind when using this architecture is about Dependency Rule. In Clean Architecture, source code dependency can only point inwards. This means that the 'inner circle' of the system cannot know at all about the outside world. For example, in the diagram above, use-cases knows about entities, but entities cannot know about use-cases. Data formats used in outer circle should not be used by an inner circle. + +Because of this, when you change something that is located the innermost of the circle (entities for example), usually you have to change the outer circles. However, if you change something that is not the innermost of the circle (controllers for example), you do not need to change the use-cases and the entities (you may have to change the frameworks and drivers as they are dependent on each other). + +If you want to learn more about Clean Architecture, please see the articles that I have attached below as references. + +## System Architecture + +For the sake of clearness, here is the diagram that showcases the system architecture of this API. + +![System Architecture](./assets/SystemArchitecture.png) + +Please refer to below table for terminologies / filenames for each layers that are used in this application. The project structure is referred from [this project](https://github.com/golang-standards/project-layout). In the `internal` package, there are packages that are grouped according to their functional responsibilities. If you open the package, you will see the files that represents the Clean Architecture layers. + +For the dependency graph, it is straightforward: handler/middleware depends on service, service depends on repository, and repository depends on domain and the database (via dependency injection). All of the layers are implemented with the said infrastructure (Fiber, MariaDB, and Authentication Service) in above image. + +I have slightly modified the layers in this application to conform to my own taste of Clean Architecture. + +| Architecture Layer | Equivalent Layer | Filename | +| :-----------------: | :--------------------: | :------------------------------: | +| External Interfaces | Presenters and Drivers | `middleware.go` and `handler.go` | +| Controllers | Business Logic | `service.go` | +| Use Cases | Repositories | `repository.go` | +| Entities | Entities | `domain.go` | + +Basically, a request will have to go through `handler.go` (and `middleware.go`) first. After that, the program will call a repository or a use-case that is requested with `service.go`. That controller (`service.go`) will call `repository.go` that conforms to the `domain.go` in order to fulfill the request that the `service.go` asked for. The result of the request will be returned back to the user by `handler.go`. + +In short: + +- `handler.go` and `middleware.go` is used to receive and send requests. +- `service.go` is business-logic or controller (some might have different opinions, but this is my subjective opinion). +- `repository.go` is used to interact to the database (use-case). +- `domain.go` is the 'shape' of the data models that the program use. + +For the sake of completeness, here are the functional responsibilities of the project structure. + +- `internal/auth` is used to manage authentication. +- `internal/city` is used to manage cities. This endpoint **is protected**. +- `internal/infrastructure` is used to manage infrastructure of the application, such as MariaDB and Fiber. +- `internal/misc` is used to manage miscellaneous endpoints. +- `internal/user` is used to manage users. This endpoint is **not protected**. + +Please refer to the code itself for further details. I commented everything in the code, so I hope it is clear enough! + +## API Endpoints / Features + +This API is divided into four 'major endpoints', which are miscellaneous, users, authentication, and cities. + +### Miscellaneous + +Endpoints classified here are miscellaneous endpoints. + +- `GET /api/v1` for health check. + +### Users + +Endpoints classified here are endpoints to perform operation on 'User' domain. + +- `GET /api/v1/users` to get all users. +- `POST /api/v1/users` to create a user. +- `GET /api/v1/users/` to get a user. +- `PUT /api/v1/users/` to update a user. +- `DELETE /api/v1/users/` to delete a user. + +### Authentication + +Endpoints classified here are endpoints to perform authentication. In my opinion, this is framework-layer / implementation detail, so there is no 'domain' regarding this endpoint and you can use this endpoint as an enhancement to other endpoints. Authentication in this API is done using JSON Web Tokens. + +- `POST /api/v1/auth/login` to log in as the user with ID of 1 in the database. Will return JWT and said JWT will be stored in a cookie. +- `POST /api/v1/auth/logout` to log out. This route removes the JWT from the cookie. +- `GET /api/v1/auth/private` to access a private route which displays information about the current (valid) JWT. + +### Cities + +Endpoints classified here are endpoints to perform operation on `City` domain. **Endpoints here are protected via JWT in the cookie**, so if you are going to use this endpoint, make sure you are logged in first (or at least have a valid JWT). + +- `GET /api/v1/cities` to get all cities. +- `POST /api/v1/cities` to create a new city. +- `GET /api/v1/cities/` to get a city. +- `PUT /api/v1/cities/` to update a city. +- `DELETE /api/v1/cities/` to delete a city. + +## Installation + +In order to run this application, you just need to do the following commands. + +- Clone the repository. + +```bash +git clone git@github.com:gofiber/recipes.git +``` + +- Switch to this repository. + +```bash +cd recipes/docker-mariadb-clean-arch +``` + +- Run immediately with Docker. After you run this command, migration script will be automatically run to populate your dockerized MariaDB. + +```bash +make start +``` + +- Test with Postman (set the request URL to `localhost:8080`) or with the created end-to-end testing script. Keep in mind that the end-to-end script is only available for the first run. If you are trying to run it the second time, you might not be able to get all of the perfect results (because of the auto-increment in the MariaDB). Please run `make stop` and `make start` first if you want to run the test suite again. + +```bash +make test +``` + +- Teardown or stop the container. This will also delete the Docker volume created and will also delete the created image. + +```bash +make stop +``` + +You're done! + +## FAQ + +Some frequently asked questions that I found scattered on the Internet. Keep in mind that the answers are mostly subjective. + +**Q: Is this the right way to do Clean Architecture?** + +A: Nope. There are many ways to perform clean architecture - this example being one of them. Some projects might be better than this example. + +**Q: Why is authentication an implementation detail?** + +A: Authentication is an implementation detail because it does not interact with the use-case or the repository / interface layer. Authentication is a bit strange that it can be implemented in any other routes as a middleware. Keep in mind that this is my subjective opinion. + +**Q: Is this the recommended way to structure Fiber projects?** + +A: Nope. Just like any other Gophers, I recommend you to start your project by using a single `main.go` file. Some projects do not require complicated architectures. After you start seeing the need to branch out, I recommend you to [split your code based on functional responsibilities](https://rakyll.org/style-packages/). If you need an even more strict structure, then you can try to adapt Clean Architecture or any other architectures that you see fit, such as Onion, Hexagonal, etcetera. + +**Q: Is this only for Fiber?** + +A: Nope. You can simply adjust `handler.go` and `middleware.go` files in order to change the external interfaces / presenters and drivers layer to something else. You can use `net/http`, `gin-gonic`, `echo`, and many more. If you want to change or add your database, you just need to adjust the `repository.go` file accordingly. If you want to change your business logic, simply change the `service.go` file. As long as you the separation of concerns is done well, you should have no need to change a lot of things. + +**Q: Is this production-ready?** + +A: I try to make this as production-ready as possible ๐Ÿ˜‰ + +## Improvements + +Several further improvements that could be implemented in this project: + +- Add more tests and mocks, especially unit tests (Clean Architecture is the best for performing unit tests). +- Add more API endpoints. +- Add a caching mechanism to the repository layer, such as Redis. +- Add transaction support. +- Maybe try to integrate S3 backend to the repository layer (MinIO is a good choice). +- Maybe add a `domain` folder in the `internal` package where we can leave the entities there? + +## Discussion + +Feel free to create an issue in this repository (or maybe ask in Fiber's Discord Server) in order to discuss this together! + +## References + +Thanks to articles and their writers that I have read and found inspiration in! + +- [Clean Architecture by Angad Sharma](https://medium.com/gdg-vit/clean-architecture-the-right-way-d83b81ecac6) +- [Clean Architecture by Uncle Bob](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) +- [Clean Architecture with Go by Elton Minetto](https://dev.to/eminetto/clean-architecture-using-golang-5791) +- [Clean Architecture with Go Part 2 by Elton Minetto](https://dev.to/eminetto/clean-architecture-2-years-later-4een) +- [Creating Clean Architecture using Go by @namkount](https://hackernoon.com/creating-clean-architecture-using-golang-9h5i3wgr) +- [Dive to Clean Architecture with Go by Kenta Takeuchi](https://dev.to/bmf_san/dive-to-clean-architecture-with-golang-cd4) +- [Go and Clean Architecture by Reshef Sharvit](https://itnext.io/golang-and-clean-architecture-19ae9aae5683) +- [Go Microservices with Clean Architecture by Jin Feng](https://medium.com/@jfeng45/go-microservice-with-clean-architecture-application-design-68f48802c8f) +- [Go Project Layout Repository](https://github.com/golang-standards/project-layout) +- [Trying Clean Architecture on Go by Imam Tumorang](https://hackernoon.com/golang-clean-archithecture-efd6d7c43047) diff --git a/docs/recipes/docker-mariadb-clean-arch/assets/CleanArchitecture.jpg b/docs/recipes/docker-mariadb-clean-arch/assets/CleanArchitecture.jpg new file mode 100644 index 00000000000..3cd44fb58d8 Binary files /dev/null and b/docs/recipes/docker-mariadb-clean-arch/assets/CleanArchitecture.jpg differ diff --git a/docs/recipes/docker-mariadb-clean-arch/assets/SystemArchitecture.png b/docs/recipes/docker-mariadb-clean-arch/assets/SystemArchitecture.png new file mode 100644 index 00000000000..76d163b4c10 Binary files /dev/null and b/docs/recipes/docker-mariadb-clean-arch/assets/SystemArchitecture.png differ diff --git a/docs/recipes/docker-nginx-loadbalancer/README.md b/docs/recipes/docker-nginx-loadbalancer/README.md new file mode 100644 index 00000000000..5a181e0f1a0 --- /dev/null +++ b/docs/recipes/docker-nginx-loadbalancer/README.md @@ -0,0 +1,34 @@ +# Docker+Nginx ๐Ÿš€ + + + + + Fiber + + + + +## Features + +- **Docker and Nginx** : Deploy in docker using 5 replicas and load balancer with Nginx +- **Logger**: The application includes a request logger for monitoring HTTP requests. + +## Endpoints + +| Name | Rute | Parameters | State | Protected | Method | +|--------------|----------| ---------- | --------- | --------- |--------| +| Hello | /hello | No | Completed | No | GET | + +## Getting Started + +To get a local copy up and running, follow these steps: + +1. Clone the repository to your local machine. +2. Navigate to the project directory. +3. Build the Docker image with docker compose +4. Run the Docker compose composition + ```bash + docker compose up --build + ``` +5. Access the application at `http://localhost:8080/hello`. + diff --git a/docs/recipes/dummyjson/README.md b/docs/recipes/dummyjson/README.md new file mode 100644 index 00000000000..7011e9c2162 --- /dev/null +++ b/docs/recipes/dummyjson/README.md @@ -0,0 +1,20 @@ +## Simple Fiber Proxy Server + +This is a basic Go application using the Fiber framework to create a web server. The server listens on port 3000 and has a single route (`GET /`) that fetches data from an external URL (`https://dummyjson.com/products/1`) and forwards it to the client. + +### How to Run + +1. Clone the repository. +2. Navigate to the project directory. +3. Run `go run main.go`. +4. Visit `http://localhost:3000/` in a web browser or use a tool like `curl` to test it. + +### What It Does + +- Fetches data from an external service, in this case `DummyJson.com` +- Forwards the fetched data or an error message to the client. + +### Error Handling + +- Returns a 500 Internal Server Error if any issue occurs during the fetch. +- Returns the same status code as the external service if it's not a 200 OK. \ No newline at end of file diff --git a/docs/recipes/ent-mysql/README.md b/docs/recipes/ent-mysql/README.md new file mode 100644 index 00000000000..706d1a03afb --- /dev/null +++ b/docs/recipes/ent-mysql/README.md @@ -0,0 +1,33 @@ +### Example ent ORM for fiber with MySQL + +A sample program how to connect ent ORM + +### How to start (If no ent dir) +Execute command first +```bash +go run -mod=mod entgo.io/ent/cmd/ent new Book +``` +go to `./ent/schema/book.go` and add fields(you want) to Book Schema +```go +// Fields of the Book. +func (Book) Fields() []ent.Field { + return []ent.Field{ + field.String("title").NotEmpty(), + field.String("author").NotEmpty(), + } +} +``` +Execute command +```bash +go generate ./ent +``` + +#### Endpoints + +| Method | URL | Description | +|--------|-------------|-----------------| +| GET | /book | All Books Info | +| GET | /book:id | One Book Info | +| POST | /create | One Book Add | +| PUT | /update/:id | One Book Update | +| DELETE | /delete/:id | One Book Delete | diff --git a/docs/recipes/entgo-sveltekit/README.md b/docs/recipes/entgo-sveltekit/README.md new file mode 100644 index 00000000000..109b354d35c --- /dev/null +++ b/docs/recipes/entgo-sveltekit/README.md @@ -0,0 +1,74 @@ +# Todo Application +![image](https://github.com/ugurkorkmaz/gofiber-recipes/assets/40540244/08c6ee52-724a-4cf4-8352-9cf6f5b007ef) + +This Todo application is a full-stack project built using Sveltekit, Tailwind CSS, Fiber, Entgo, and SQLite. It showcases the construction of a monolithic architecture for a full-stack application. + +## Run the Project + +To run the project, follow these steps: + +1. Execute the following command to run all the necessary commands for building and running the application: + +```bash +go run ./bin all +``` +2. Once the build process is complete, you can start the application by running: +```bash +./app +``` + + +## Available Commands +The following commands are available to manage the project: + + +| Command | Description | +| --- | --- | +| `go-run` | Run the Golang project. | +| `go-build` | Build the Golang project. | +| `go-test` | Run tests for the Golang project. | +| `svelte-run` | Run the SvelteKit project. | +| `svelte-build` | Build the SvelteKit project. | +| `generate-ent` | Generate entity files. | +| `all` | Run all commands (`generate-ent`, `svelte-build`, `go-test`, `go-build`). | + +## Usage + +To use this application, run the following command: + +```bash +go run ./bin +``` + + +API Routes +---------- + +The Go Fiber application provides the following API routes: + +| Method | Endpoint | Handler Function | Description | +| --- | --- | --- | --- | +| GET | /api/v1/todo/list | todoHandler.GetAllTodos | Get a list of all todos | +| GET | /api/v1/todo/get/:id | todoHandler.GetTodoByID | Get a specific todo by its ID | +| POST | /api/v1/todo/create | todoHandler.CreateTodo | Create a new todo | +| PUT | /api/v1/todo/update/:id | todoHandler.UpdateTodoByID | Update an existing todo by its ID | +| DELETE | /api/v1/todo/delete/:id | todoHandler.DeleteTodoByID | Delete a todo by its ID | + +Go Dependencies +--------------- + +- **Go Modules:** Go's built-in package manager used to manage dependencies for Go projects. +- **Entgo:** A Golang Object Relational Mapping (ORM) tool used to define and generate database schemas. +- **Fiber:** A fast and minimalist web framework for Golang. +- **Sqlite:** A small, lightweight, embedded SQL database engine. + +Npm Dependencies +---------------- + +- **SvelteKit:** A JavaScript framework used to build modern web applications. +- **Tailwind CSS:** A fast and customizable CSS styling library. Can be used in SvelteKit projects. + +---------------- + +Author: [@ugurkorkmaz](https://github.com/ugurkorkmaz) + diff --git a/docs/recipes/entgo-sveltekit/template/README.md b/docs/recipes/entgo-sveltekit/template/README.md new file mode 100644 index 00000000000..401c8ce1257 --- /dev/null +++ b/docs/recipes/entgo-sveltekit/template/README.md @@ -0,0 +1,40 @@ +# SvelteKit and Tailwind CSS Project + +This is a SvelteKit project that utilizes Tailwind CSS for styling. SvelteKit is a framework for building modern web applications, and Tailwind CSS is a utility-first CSS framework. Together, they provide a powerful combination for creating responsive and visually appealing web interfaces. + +## Available Scripts + +The following scripts are available in the project's `package.json` file: + +| Script | Description | +| ------------- | ---------------------------------------------------------------------------------------- | +| `dev` | Starts the development server and hot-reloads the application for a seamless development experience. | +| `build` | Builds the project for production, generating optimized and minified files. | +| `preview` | Starts a server to preview the production-ready build locally before deployment. | +| `check` | Runs the Svelte compiler and type-checker to validate the project's TypeScript configuration. | +| `check:watch` | Similar to `check`, but watches for changes and performs continuous type-checking. | + +## Usage + +To use the available scripts, you need to have Node.js and Npm (or Pnpm) installed on your system. Follow these steps: + +1. Install the project dependencies by running the following command in the project's root directory: + ```bash + npm install + ``` + or + ```bash + pnpm install + ``` +2. Once the installation is complete, you can run the desired script using the following command: + ```bash + npm run (code) + ``` + or + ```bash + pnpm run (code) + ``` + Replace `(code)` with one of the available scripts mentioned in the table above. + +3. The corresponding action will be executed, and you can see the output in the terminal. + Please note that specific configurations and additional steps might be required depending on your project setup or requirements. Refer to the project documentation for more information. \ No newline at end of file diff --git a/docs/recipes/entgo-sveltekit/template/static/favicon.png b/docs/recipes/entgo-sveltekit/template/static/favicon.png new file mode 100644 index 00000000000..825b9e65af7 Binary files /dev/null and b/docs/recipes/entgo-sveltekit/template/static/favicon.png differ diff --git a/docs/recipes/fiber-bootstrap/README.md b/docs/recipes/fiber-bootstrap/README.md new file mode 100644 index 00000000000..096ca120057 --- /dev/null +++ b/docs/recipes/fiber-bootstrap/README.md @@ -0,0 +1,31 @@ +# Fiber Bootstrap +Fiber bootstrap for rapid development using Go-Fiber / Gorm / Validator. + +# Components +* Fiber + * Html Engine Template + * Logger + * Monitoring +* Gorm + * PGSQL Driver +* Validator +* Env File + +# Router +API Router `/api` with rate limiter middleware +Http Router `/` with CORS and CSRF middleware + +# Setup + +1. Copy the example env file over: + ``` + cp .env.example .env + ``` + +2. Modify the env file you just copied `.env` with the correct credentials for your database. Make sure the database you entered in `DB_NAME` has been created. + +3. Run the API: + ``` + go run main.go + ``` +Your api should be running at `http://localhost:4000/` if the port is in use you may modify it in the `.env` you just created. \ No newline at end of file diff --git a/docs/recipes/fiber-colly-gorm/README.md b/docs/recipes/fiber-colly-gorm/README.md new file mode 100644 index 00000000000..ff69eee2fb6 --- /dev/null +++ b/docs/recipes/fiber-colly-gorm/README.md @@ -0,0 +1,16 @@ +## Simple Web Scraping Colly App with Fiber + +This is a basic Go application using the Fiber framework to create scraping tasks in colly. + +### How to Run + +1. Clone the repository. +2. Navigate to the project directory. +3. Run `docker compose up --build`. +4. Visit `http://127.0.0.1:3000/api/healthchecker` in a web browser or use a tool like `curl` to test it. +5. Send `GET` request to `http://127.0.0.1:3000/scrape/coursera` to start scraping Coursera courses. And `http://127.0.0.1:3000/scrape/quotes` to scrape `quotes.toscrape.com`. + + +### What It Does + +- Scrapes data from websites and stores in PostgreSQL database. diff --git a/docs/recipes/fiber-envoy-extauthz/README.md b/docs/recipes/fiber-envoy-extauthz/README.md new file mode 100644 index 00000000000..d3a72ada15e --- /dev/null +++ b/docs/recipes/fiber-envoy-extauthz/README.md @@ -0,0 +1,33 @@ +## Fiber as an Envoy External Authorization HTTP Service + +One way of extending the popular [Envoy](https://www.envoyproxy.io) proxy is by developing an +[external authorization service](https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto). + +This example illustrates using `fiber` and the `keyauth` middleware as an authorization service for a front +proxy (the configuration could also be used for an L2 / Sidecar proxy). See `authz`. + +It also uses `fiber` as a sample upstream service, with the following endpoints. See `app`. + +### Endpoints + +| Name | Rute | Protected | Method | +| --------- | ------------- | --------- | ------ | +| Health | /health | No | GET | +| Resource | /api/resource | Yes | GET | + +### Run + +`docker-compose up --build -d` + +### Test + +| Name | Command | Status | +| --------------- | ----------------------------------------------------------------- | ------ | +| Not protected | `curl localhost:8000/health -i` | 200 | +| Missing API key | `curl localhost:8000/api/resource -i` | 403 | +| Invalid API key | `curl localhost:8000/api/resource -i -H "x-api-key: invalid-key"` | 403 | +| Valid API key | `curl localhost:8000/api/resource -i -H "x-api-key: valid-key"` | 200 | + +### Stop + +`docker-compose down` diff --git a/docs/recipes/fiber-grpc/README.md b/docs/recipes/fiber-grpc/README.md new file mode 100644 index 00000000000..4c2dd05bc42 --- /dev/null +++ b/docs/recipes/fiber-grpc/README.md @@ -0,0 +1,19 @@ +### Example for fiber as a client to gRPC server. + +A sample program to showcase fiber as a client to a gRPC server. + +#### Endpoints + +| Method | URL | Return value | +| ------ | ------------- | ------------ | +| GET | "/add/:a/:b" | a + b | +| GET | "/mult/:a/:b" | a \* b | + +#### Output + +```bash +-> curl http://localhost:3000/add/33445/443234 +{"result":"476679"} +-> curl http://localhost:3000/mult/33445/443234 +{"result":"14823961130"} +``` diff --git a/docs/recipes/fiber-svelte-netlify/README.md b/docs/recipes/fiber-svelte-netlify/README.md new file mode 100644 index 00000000000..79fe60b777d --- /dev/null +++ b/docs/recipes/fiber-svelte-netlify/README.md @@ -0,0 +1,40 @@ +# Deploying fiber on Netlify + +[![Netlify Status](https://api.netlify.com/api/v1/badges/143c3c42-60f7-427a-b3fd-8ca3947a2d40/deploy-status)](https://app.netlify.com/sites/gofiber-svelte/deploys) + +### Demo @ https://gofiber-svelte.netlify.app/ + +#### Based on the fiber-lambda API written by Fenny. Since the code hasn't been merged yet, I borrowed it into `adapter/adapter.go` + +The app uses static pages under `public` directory. These are compiled using sveltejs and the complete template can be found [here](https://github.com/amalshaji/gofiber-sveltejs-netlify). + + +```toml +# netlify.toml + +[build] + command = "./build.sh" + functions = "functions" + publish = "public" + +[build.environment] + GO_IMPORT_PATH = "github.com/amalshaji/fiber-netlify" + GO111MODULE = "on" + +[[redirects]] + from = "/api/*" + to = "/.netlify/functions/gateway/:splat" + status = 200 +``` + +Deploying `net/http to Netlify` explains what these functions are doing. You can read it [here](https://blog.carlmjohnson.net/post/2020/how-to-host-golang-on-netlify-for-free/). + +#### TL;DR +- build command builds the whole code to binary `cmd/gateway/gateway` +- we're building something called [netlify functions](https://functions.netlify.com/) (Please read) +- everything under public folder will be published(entrypoint: `index.html`) +- Netlify maps endpoints to `/.netlify/functions/gateway`, which is weird when you do requests, so we redirect it to `/api/*` +- status = 200 for server side redirects + +#### Important +Netlify functions allows you to have up to 125,000 requests a month. This means you can have 2.89 requests per minute. Make sure you use `Cache` in you request handlers. \ No newline at end of file diff --git a/docs/recipes/file-server/files/gopher.gif b/docs/recipes/file-server/files/gopher.gif new file mode 100644 index 00000000000..dec69d38efa Binary files /dev/null and b/docs/recipes/file-server/files/gopher.gif differ diff --git a/docs/recipes/firebase-auth/README.MD b/docs/recipes/firebase-auth/README.MD new file mode 100644 index 00000000000..d46de01b4eb --- /dev/null +++ b/docs/recipes/firebase-auth/README.MD @@ -0,0 +1,18 @@ +# Go FIber Firebase Authentication Example + +This example use [gofiber-firebaseauth middleware ](https://github.com/sacsand/gofiber-firebaseauth) to authenticate the endpoints. Find the documentation for middlewae here for more confgurtion oprions [docs ](https://github.com/sacsand/gofiber-firebaseauth) + +### Setting Up + +* Clone the repo and set your firebase credentials in your .env file + Need Configured Firebase Authentication App and Google Service Account Credential (JSON file contain credential). You can get all these config from Firebase Console. + +``` +SERVICE_ACCOUNT_JSON = "path to service account credential json" +``` + +### Start +``` +go build +go run main +``` \ No newline at end of file diff --git a/docs/recipes/firebase-functions/README.md b/docs/recipes/firebase-functions/README.md new file mode 100644 index 00000000000..05a0674b81b --- /dev/null +++ b/docs/recipes/firebase-functions/README.md @@ -0,0 +1,415 @@ + +# Deploying GoFiber Application to Firebase Functions + +Welcome to this step-by-step guide on deploying a GoFiber application to Firebase Functions. If youโ€™re looking to leverage the power of GoFiber, a fast and lightweight web framework for Go, and host your application on Firebase, youโ€™re in the right place. In this tutorial, weโ€™ll walk through the process of setting up your GoFiber app to run seamlessly on Firebase Functions. + +## Prerequisites + +1. Go installed on your machine. +2. Firebase CLI installed. +3. A Firebase project created. +4. Firestore and Cloud Functions enabled. + +## Create a GoFiber App + +Start by initializing your GoFiber application. Use the following commands in your terminal: + +```bash +go mod init example.com/GofiberFirebaseBoilerplate +``` + +## Server Configuration + +Create a server file `(src/server.go)` with a `CreateServer` function that sets up your GoFiber server. + +```go +package src + +import ( + "example.com/GofiberFirebaseBoilerplate/src/routes" + + "github.com/gofiber/fiber/v2" +) + +func CreateServer() *fiber.App { + version := "v1.0.0" + + app := fiber.New(fiber.Config{ + ServerHeader: "Gofiber Firebase Boilerplate", + AppName: "Gofiber Firebase Boilerplate " + version, + }) + + app.Get("/", func(c *fiber.Ctx) error { + return c.SendString("Gofiber Firebase Boilerplate " + version) + }) + + routes.New().Setup(app) + + return app +} +``` + +## Routes Configuration + +Now that your GoFiber application is initialized, letโ€™s delve into setting up and configuring routes. This section is crucial for defining how your application handles incoming requests. Open the `src/routes/routes.go` file to manage your routes. + +```go +package routes + +import ( + "example.com/GofiberFirebaseBoilerplate/src/database" + "example.com/GofiberFirebaseBoilerplate/src/repositories" + + "github.com/gofiber/fiber/v2" +) + +type Routes struct { + mainRepository *repositories.MainRepository +} + +func New() *Routes { + db := database.NewConnection() + return &Routes{mainRepository: &repositories.MainRepository{DB: db}} +} + +func (r *Routes) Setup(app *fiber.App) { + app.Post("message", r.insertMessage) +} + +func (r *Routes) insertMessage(c *fiber.Ctx) error { + return c.SendString("ok") +} +``` + +## Database Configuration + +Configure your Firestore database connection in the `src/database/database.go` file. Make sure to replace the placeholder credentials with your Firebase project's actual credentials. + +```go +package database + +import ( + "context" + "encoding/json" + "log" + + "cloud.google.com/go/firestore" + firebase "firebase.google.com/go" + + "google.golang.org/api/option" +) + +type Config struct { + Host string + Port string + Password string + User string + DBName string + SSLMode string +} + +func NewConnection() *firestore.Client { + + ctx := context.Background() + + sa := option.WithCredentialsJSON(credentials()) + app, err := firebase.NewApp(ctx, nil, sa) + if err != nil { + log.Fatalf("functions.init: NewApp %v\n", err) + } + + db, err := app.Firestore(ctx) + if err != nil { + log.Fatalf("functions.init: Database init : %v\n", err) + } + + return db +} + +func credentials() []byte { + // TODO: Replace with your Credentials + data := map[string]interface{}{ + "type": "", + "project_id": "", + "private_key_id": "", + "private_key": "", + "client_email": "", + "client_id": "", + "auth_uri": "", + "token_uri": "", + "auth_provider_x509_cert_url": "", + "client_x509_cert_url": "", + "universe_domain": "", + } + + bytes, err := json.Marshal(data) + if err != nil { + panic(err) + } + + return bytes +} +``` + +## Repository Pattern + +Implement the repository pattern in the `src/repositories/main.repository.go` file to interact with Firestore. This file includes an example of inserting a message into the database. + +```go +package repositories + +import ( + "context" + + "cloud.google.com/go/firestore" + "example.com/GofiberFirebaseBoilerplate/src/models" + "github.com/google/uuid" +) + +type MainRepository struct { + DB *firestore.Client +} + +func (r *MainRepository) InsertMessage(body *models.MessageInputBody) error { + id := uuid.New().String() + _, err := r.DB.Collection("messages").Doc(id).Set(context.Background(), body) + return err +} +``` + +## Model Definition + +Define a message input model in src/models/message_input_body.go to structure the data you'll be working with. + +```go +package models + +type MessageInputBody struct { + From string `json:"from"` + To string `json:"to"` + Message string `json:"message"` +} +``` + +## Functions for Cloud Integration + +In `functions.go`, convert Google Cloud Function requests to Fiber and route them to your application. This file includes functions to facilitate the integration of Google Cloud Functions and GoFiber. + +```go +package app + +import ( + "bytes" + "context" + "fmt" + "io" + "log" + "net" + "net/http" + "strings" + + "github.com/gofiber/fiber/v2" + "github.com/valyala/fasthttp/fasthttputil" +) + +// CloudFunctionRouteToFiber route cloud function http.Handler to *fiber.App +// Internally, google calls the function with the /execute base URL +func CloudFunctionRouteToFiber(fiberApp *fiber.App, w http.ResponseWriter, r *http.Request) error { + return RouteToFiber(fiberApp, w, r, "/execute") +} + +// RouteToFiber route http.Handler to *fiber.App +func RouteToFiber(fiberApp *fiber.App, w http.ResponseWriter, r *http.Request, rootURL ...string) error { + ln := fasthttputil.NewInmemoryListener() + defer ln.Close() + + // Copy request + body, err := io.ReadAll(r.Body) + if err != nil { + return err + } + + url := fmt.Sprintf("%s://%s%s", "http", "0.0.0.0", r.RequestURI) + if len(rootURL) > 0 { + url = strings.Replace(url, rootURL[0], "", -1) + } + + proxyReq, err := http.NewRequest(r.Method, url, bytes.NewReader(body)) + + if err != nil { + return err + } + + proxyReq.Header = r.Header + + // Create http client + client := http.Client{ + Transport: &http.Transport{ + DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + return ln.Dial() + }, + }, + } + + // Serve request to internal HTTP client + go func() { + log.Fatal(fiberApp.Listener(ln)) + }() + + // Call internal Fiber API + response, err := client.Do(proxyReq) + if err != nil { + return err + } + + // Copy response and headers + for k, values := range response.Header { + for _, v := range values { + w.Header().Set(k, v) + } + } + w.WriteHeader(response.StatusCode) + + io.Copy(w, response.Body) + response.Body.Close() + + return nil +} +``` + +## Main Application Entry + +In `main.go`, initialize your GoFiber app and start the server. This file also includes an exported Cloud Function handler for deployment. + +```go +package app + +import ( + "fmt" + "net/http" + "strings" + + "example.com/GofiberFirebaseBoilerplate/src" + "github.com/gofiber/fiber/v2" +) + +var app *fiber.App + +func init() { + app = src.CreateServer() +} + +// Start start Fiber app with normal interface +func Start(addr string) error { + if -1 == strings.IndexByte(addr, ':') { + addr = ":" + addr + } + + return app.Listen(addr) +} + +// MyCloudFunction Exported http.HandlerFunc to be deployed to as a Cloud Function +func MyCloudFunction(w http.ResponseWriter, r *http.Request) { + err := CloudFunctionRouteToFiber(app, w, r) + if err != nil { + fmt.Fprintf(w, "err : %v", err) + return + } +} +``` + +## Development + +For local development, utilize the `cmd/main.go` file. If you prefer hot reloading, the `.air.toml` configuration file is included for use Air. + +## cmd/main.go + +```go +package main + +import ( + "log" + "os" + + app "example.com/GofiberFirebaseBoilerplate" +) + +func main() { + + port := "3001" + if envPort := os.Getenv("PORT"); envPort != "" { + port = envPort + } + + if err := app.Start(port); err != nil { + log.Fatalf("app.Start: %v\n", err) + } +} +``` + +## .air.toml + +```go +root = "." +testdata_dir = "testdata" +tmp_dir = "tmp" + +[build] + args_bin = [] + bin = "./tmp/main" + cmd = "go build -o ./tmp/main ./cmd" + delay = 1000 + exclude_dir = ["assets", "tmp", "vendor", "testdata"] + exclude_file = [] + exclude_regex = ["_test.go"] + exclude_unchanged = false + follow_symlink = false + full_bin = "" + include_dir = [] + include_ext = ["go", "tpl", "tmpl", "html"] + include_file = [] + kill_delay = "0s" + log = "build-errors.log" + poll = false + poll_interval = 0 + post_cmd = [] + pre_cmd = [] + rerun = false + rerun_delay = 500 + send_interrupt = false + stop_on_error = false + +[color] + app = "" + build = "yellow" + main = "magenta" + runner = "green" + watcher = "cyan" + +[log] + main_only = false + time = false + +[misc] + clean_on_exit = false + +[screen] + clear_on_rebuild = false + keep_scroll = true +``` + +## Deployment + +Deploy your Cloud Function using the following commands, replacing `` with your Firebase project ID: + +```bash +gcloud config set project +gcloud functions deploy MyCloudFunction --runtime go120 --trigger-http +``` + +## Conclusion + +Congratulations! Youโ€™ve successfully configured and deployed a GoFiber application on Firebase Functions. This powerful combination allows you to build fast and efficient serverless applications. Experiment further with GoFiber features and Firebase integrations to unlock the full potential of your serverless architecture. Happy coding! + +## Medium Post +https://medium.com/@kmltrk07/how-to-deploy-gofiber-app-to-firebase-functions-8d4d537a4464 \ No newline at end of file diff --git a/docs/recipes/gcloud-firebase/README.md b/docs/recipes/gcloud-firebase/README.md new file mode 100644 index 00000000000..9179f4e20f3 --- /dev/null +++ b/docs/recipes/gcloud-firebase/README.md @@ -0,0 +1,50 @@ +# Deploy Fiber to Google Cloud with Firebase + +Examples on how to run an application using Fiber on Google Cloud and connecting to Firebase Realtime Database. + +#### Running Locally + +* Run on the command line: +``` +go run cmd/main.go +``` + +#### Deploy using Google Cloud Run + +This step will build a Docker Image, publish to Google Cloud Registry and deploy on Cloud Run Managed enviroment. + +Just follow the steps and fill the `GCP_PROJECT` variable with your Google Cloud Platform project ID. That variable is needed to connect to Firebase. + +[![Run on Google Cloud](https://storage.googleapis.com/cloudrun/button.svg)](https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/gofiber/recipes&cloudshell_working_dir=gcloud-firebase) + +After deploying the server on Cloud Run, you can get it's url on GCP Console ([link](https://console.cloud.google.com/run)) and select the service `gcloud-fiber-firebase` that we just deployed. Then copy the URL. It will look like `https://{project-id}-{some-random-hash-string}.a.run.app`. + +Or you can do it manually with those steps: + +* Run on the command line: +``` +export GCLOUD_PROJECT=[YOUR_PROJECT_ID] +gcloud builds submit โ€” -tag gcr.io/$GCLOUD_PROJECT/gcloud-fiber-firebase . +gcloud beta run deploy --platform managed --image gcr.io/$GCLOUD_PROJECT/gcloud-fiber-firebase \ + --set-env-vars GCP_PROJECT=$GCLOUD_PROJECT +``` + +#### Deploy using Google App Engine + +This step will deploy the app to Google App Engine Standard Go enviroment. The app configuration and additional configurations can be tweaked on the `app.yaml` file. + +* Run on the command line: +``` +gcloud app deploy +``` + +#### Deploy using Google Cloud Function + +This step will deploy a HTTP Cloud Function using Go enviroment. You can use the `deploy.sh` script. Just edit your project id on it. + +For the Cloud Functions env, Google enforces us to deploy a function that is a `http.HandlerFunc`, so on the file `functions.go` there is a workaround to reroute the HTTP call to the Fiber app instance. + +* Run on the command line: +``` +gcloud functions deploy HeroesAPI --runtime go111 --trigger-http +``` diff --git a/docs/recipes/gcloud/README.md b/docs/recipes/gcloud/README.md new file mode 100644 index 00000000000..545826262bf --- /dev/null +++ b/docs/recipes/gcloud/README.md @@ -0,0 +1,47 @@ +# Deploy Fiber to Google Cloud with Firebase + +Examples on how to run an application using Fiber on Google Cloud. + +#### Running Locally + +* Run on the command line: +``` +go run cmd/main.go +``` + +#### Deploy using Google Cloud Run + +This step will build a Docker Image, publish to Google Cloud Registry and deploy on Cloud Run Managed enviroment. + +[![Run on Google Cloud](https://storage.googleapis.com/cloudrun/button.svg)](https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/gofiber/recipes&cloudshell_working_dir=gcloud) + +After deploying the server on Cloud Run, you can get it's url on GCP Console ([link](https://console.cloud.google.com/run)) and select the service `gcloud-fiber` that we just deployed. Them copy the URL will look like `https://{project-id}-{some-random-hash-string}.a.run.app`. + +Or you can do it manually with those steps: + +* Run on the command line: +``` +export GCLOUD_PROJECT=[YOUR_PROJECT_ID] +gcloud builds submit โ€” -tag gcr.io/$GCLOUD_PROJECT/gcloud-fiber . +gcloud beta run deploy --platform managed --image gcr.io/$GCLOUD_PROJECT/gcloud-fiber +``` + +#### Deploy using Google App Engine + +This step will deploy the app to Google App Engine Standard Go enviroment. The app configuration and additional configurations can be tweaked on the `app.yaml` file. + +* Run on the command line: +``` +gcloud app deploy +``` + +#### Deploy using Google Cloud Function + +This step will deploy a HTTP Cloud Function using Go enviroment. You can use the `deploy.sh` script. Just edit your project id on it. + +For the Cloud Functions env, Google enforces us to deploy a function that is a `http.HandlerFunc`, so on the file `functions.go` there is a workaround to reroute the HTTP call to the Fiber app instance. + +* Run on the command line: +``` +gcloud functions deploy MyCloudFunction --runtime go111 --trigger-http +``` \ No newline at end of file diff --git a/docs/recipes/geoip-maxmind/README.md b/docs/recipes/geoip-maxmind/README.md new file mode 100644 index 00000000000..957a6cb0004 --- /dev/null +++ b/docs/recipes/geoip-maxmind/README.md @@ -0,0 +1,43 @@ +# GeoIP (with MaxMind databases) + +This is an alternative method to resolve IP addresses to real-world location data using MaxMind GeoLite2 City databases. + +### Prerequisites +Before you run this, you must first download a database from the MaxMind website - https://dev.maxmind.com/geoip/geoip2/geolite2/. To do this, you may need to register for a free account. + +The database you need to download is the one with the edition ID `GeoLite2-City`. Place it in this folder and run + +``` +go run geoip-maxmind +``` + +### Usage +Make a request to `http://127.0.0.1:3000/geo/178.62.56.160`, for example. You can omit an IP address to use your current IP address, or replace to use another. If the IP address is invalid, a HTTP 400 is returned. + +The response fields can be modified from the `ipLookup` struct, found in the `handlers/handlers.go` file. + +### Example response + +```json +{ + "City": { + "GeoNameID": 2643743, + "Names": { + "de": "London", + "en": "London", + "es": "Londres", + "fr": "Londres", + "ja": "ใƒญใƒณใƒ‰ใƒณ", + "pt-BR": "Londres", + "ru": "ะ›ะพะฝะดะพะฝ", + "zh-CN": "ไผฆๆ•ฆ" + } + }, + "Country": { + "IsoCode": "GB" + }, + "Location": { + "AccuracyRadius": 50 + } +} +``` \ No newline at end of file diff --git a/docs/recipes/geoip/README.md b/docs/recipes/geoip/README.md new file mode 100644 index 00000000000..2db46a21e98 --- /dev/null +++ b/docs/recipes/geoip/README.md @@ -0,0 +1 @@ +![](https://i.imgur.com/yifgkJ5.png) \ No newline at end of file diff --git a/docs/recipes/gorm-mysql/README.md b/docs/recipes/gorm-mysql/README.md new file mode 100644 index 00000000000..5303c74bccf --- /dev/null +++ b/docs/recipes/gorm-mysql/README.md @@ -0,0 +1,14 @@ +### Example for fiber as a orm to MySQL + +A sample program to orm mysql connect + +#### Endpoints + +| Method | URL | +| ------ | --------- | +| GET | /hello | +| GET | /allbooks | +| GET | /book/:id | +| POST | /book | +| PUT | /book | +| DELETE | /book | diff --git a/docs/recipes/graceful-shutdown/README.md b/docs/recipes/graceful-shutdown/README.md new file mode 100644 index 00000000000..f714c8d58a5 --- /dev/null +++ b/docs/recipes/graceful-shutdown/README.md @@ -0,0 +1,25 @@ +# Graceful shutdown in Fiber + +``` +fiberRecipes/graceful-shutdown on graceful-shutdown (f0834df) [?] via ๐Ÿน v1.15.2 took 4s +โฏ go run graceful-shutdown + + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ Fiber v2.1.0 โ”‚ + โ”‚ http://127.0.0.1:3000 โ”‚ + โ”‚ โ”‚ + โ”‚ Handlers ............. 2 Threads ............. 8 โ”‚ + โ”‚ Prefork ....... Disabled PID .............. 2540 โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + +^CGracefully shutting down... +Running cleanup tasks... +``` + +This shows how to implement a graceful shutdown with Fiber and the `os/signal` package. + +### Explanation + +This example relies on the use of channels, a data type in Go that allows you to send and receive data to/from specific places in an application (read more about them [here](https://tour.golang.org/concurrency/2)). + +A channel is created, and registered with `signal.Notify` so that when the program receives an interrupt (for example, when `CTRL+C` is pressed), a notification is sent to the channel. Once this is received, `app.Shutdown` is called to close all active connections and return from `app.Listen`. After this point, cleanup functions can be run and the program eventually quits. diff --git a/docs/recipes/hexagonal/Hexagonal-Arch.png b/docs/recipes/hexagonal/Hexagonal-Arch.png new file mode 100644 index 00000000000..7b354c61b9d Binary files /dev/null and b/docs/recipes/hexagonal/Hexagonal-Arch.png differ diff --git a/docs/recipes/hexagonal/README.md b/docs/recipes/hexagonal/README.md new file mode 100644 index 00000000000..68165e18071 --- /dev/null +++ b/docs/recipes/hexagonal/README.md @@ -0,0 +1,4 @@ +# A Hexagonal Software Architecture in Golang and MongoDB +This presents a simple product catalogue microservice to demonstrate the principles of a hexagonal software architecture. The microservice exposes a RESTful API that allows consuming applications to perform CRUD operations on a product catalogue. The microservice is developed in Golang, and the product catalogue data is persisted in a MongoDB repository. + +![](Hexagonal-Arch.png) diff --git a/docs/recipes/i18n/README.md b/docs/recipes/i18n/README.md new file mode 100644 index 00000000000..ac301b2422b --- /dev/null +++ b/docs/recipes/i18n/README.md @@ -0,0 +1,38 @@ +# Fiber with i18n + +This is a quick example of how to use [nicksnyder/go-i18n](https://github.com/nicksnyder/go-i18n) package to translate your Fiber application into multiple languages. + +## Demo + +- Run Fiber application; +- Open `http://127.0.0.1:3000/?unread=1` and see: + +```bash +Hello Bob + + I have 1 unread email. + Bob has 1 unread email. +``` + +- Next, go to `http://127.0.0.1:3000/?unread=4` and see pluralization of your message: + +```bash +Hello Bob + + I have 4 unread emails. + Bob has 4 unread emails. +``` + +- OK. Try translation of other languages, just add `&lang=es` (or `&lang=ru`) query to the URL: + +```bash +Hola Bob + + Tengo 4 correos electrรณnicos no leรญdos + Bob tiene 4 correos electrรณnicos no leรญdos +``` + +## go-i18n docs + +- [Translating a new language](https://github.com/nicksnyder/go-i18n#translating-a-new-language); +- [Translating a new messages (updating)](https://github.com/nicksnyder/go-i18n#translating-new-messages); diff --git a/docs/recipes/jwt/README.md b/docs/recipes/jwt/README.md new file mode 100644 index 00000000000..76f7fd578a2 --- /dev/null +++ b/docs/recipes/jwt/README.md @@ -0,0 +1,3 @@ +# Fiber with JWT + +Postman examples [here](https://www.getpostman.com/collections/0e83876e0f2a0c8ecd70). \ No newline at end of file diff --git a/docs/recipes/memgraph/README.md b/docs/recipes/memgraph/README.md new file mode 100644 index 00000000000..033769be36e --- /dev/null +++ b/docs/recipes/memgraph/README.md @@ -0,0 +1,53 @@ +# Fiber and Memgraph + +This is a cookbook recipe for setting up Fiber backend and Memgraph database. ๐Ÿš€ + +## Prerequisites + +Go is an obvious prerequisite. Make sure it is installed and configured properly. + +After that you need two Go packages: Fiber and Neo4j driver for Go. You can install them with the following commands: + +``` +go get -u github.com/gofiber/fiber/v2 +go get github.com/neo4j/neo4j-go-driver/v5 +``` + +## Run Memgraph + +The easiest way to run Memgraph is to use Docker. +Once docker is installed on your machine, you can run Memgraph with the following command: + +``` +docker run โ€“name memgraph -it -p 7687:7687 -p 7444:7444 -p 3000:3000 -v mg_lib:/var/lib/memgraph memgraph/memgraph-platform +``` + +## Run the recipe + +After you have installed all the prerequisites, you can run the recipe with the following command: + +``` +cd memgraph +go run ./main.go +``` + +This will do the following: + +1. Connect Fiber backend to Memgraph database +2. Generate mock data to populate the database +3. Define two request handlers: one for getting the graph and one for getting developer nodes + +## Test the recipe + +Once Fiber app is running, you can test the recipe by sending a GET request to the following endpoints: + +``` +http://localhost:3000/graph +http://localhost:3000/developer/Andy +``` + +## Additional resources + +For extra information use the documentation on the following links: +- Fiber: https://docs.gofiber.io/ +- Memgraph: https://memgraph.com/docs \ No newline at end of file diff --git a/docs/recipes/minio/README.md b/docs/recipes/minio/README.md new file mode 100644 index 00000000000..385ba7317dd --- /dev/null +++ b/docs/recipes/minio/README.md @@ -0,0 +1,114 @@ +# MinIO File Upload & Download Example + +This example demonstrates a simple Go Fiber application that includes modules for uploading both single and multiple files, as well as downloading files from MinIO. Each module provides REST API endpoints for file upload and retrieval, serving as a foundation for applications requiring file storage and access. + +## Prerequisites + +Ensure you have the following installed: + +- [Go](https://golang.org/dl/): (version 1.22 or higher) installed +- [minio](https://min.io/download): MinIO running on your local machine or a remote server +- [Git](https://git-scm.com/downloads) + +## Project Structure + +- `single/main.go`: Example for uploading and downloading a single file to/from MinIO. + +- `multiple/main.go`: Example for uploading multiple files to MinIO and downloading files from MinIO. + +- `go.mod`: Go module file managing project dependencies. + +## Getting Started + +### 1. Clone the Repository + +Clone the repository and navigate to the example directory: + +```bash +git clone https://github.com/gofiber/recipes.git +cd recipes/minio +``` + +### 2. Install Dependencies + +Use Goโ€™s module system to install dependencies: + +```bash +go mod download +``` + +## Running the Examples + +### Uploading and Downloading a Single File + +1. Go to the `single` directory: + + ```bash + cd single + ``` + +2. Start the application: + + ```bash + go run main.go + ``` + +3. Upload a file using `curl` or `Postman`: + ```bash + curl -F "document=@/path/to/your/file" http://localhost:3000/upload + ``` +4. Download the file by specifying its name in the request: + + ```bash + curl -O http://localhost:3000/file/ + ``` + +### Uploading Multiple Files and Downloading Files + +1. Go to the `multiple` directory: + + ```bash + cd multiple + ``` + +2. Start the application: + + ```bash + go run main.go + ``` + +3. Upload multiple files using `curl` or `Postman`: + + ```bash + curl -F "documents=@/path/to/your/file1" -F "documents=@/path/to/your/file2" http://localhost:3000/upload + ``` + +4. Download a file by specifying its name in the request. + + ```bash + curl -O http://localhost:3000/file/ + ``` + +## Code Overview + +### `single/main.go` + +- Defines routes to handle a single file upload and download. + +- Includes error handling for file validation, MinIO connection, and bucket management. + +### `multiple/main.go` + +- Handles uploading multiple files in a single request and allows for file downloads. + +- Validates each file and provides detailed responses for both successful and failed uploads. + +## Conclusion + +This example offers a approach for managing file uploads and downloads with Go Fiber and MinIO. It can be expanded to support additional features, such as adding metadata, handling large files, or restricting access to files. + +## References + +- [Fiber Documentation](https://docs.gofiber.io) +- [Fiber storage](https://github.com/gofiber/storage) +- [MinIO Documentation](https://min.io/docs/) diff --git a/docs/recipes/oauth2-google/README.md b/docs/recipes/oauth2-google/README.md new file mode 100644 index 00000000000..bb04c28a9d4 --- /dev/null +++ b/docs/recipes/oauth2-google/README.md @@ -0,0 +1,14 @@ +# Fiber with Google OAuth2 + +### Implementation of Google OAuth2 with fiber, some packages used are mentioned below +Obtain OAuth credentials from https://console.developers.google.com/ + +## Endpoints +- /api/ - redirects to login url + +- /api/auth/google/callback - gives a callback to google and on success return's user's email + +## Packages Used +- [Godotenv](https://github.com/joho/godotenv) +- [Fiber](https://github.com/gofiber/fiber) +- [OAuth2](https://github.com/golang/oauth2) \ No newline at end of file diff --git a/docs/recipes/parsley/README.md b/docs/recipes/parsley/README.md new file mode 100644 index 00000000000..e28e258b054 --- /dev/null +++ b/docs/recipes/parsley/README.md @@ -0,0 +1,32 @@ +# Fiber with Dependency Injection (via Parsley) + +This example demonstrates integrating the [Parsley dependency injection framework](https://github.com/matzefriedrich/parsley) into a GoFiber web application. The goal is to showcase how dependency injection can create a clean, maintainable, and modular structure in your GoFiber projects. + +## Overview + +In this example, we use Parsley to: + +* **Bootstrap the Application:** Set up and configure the Fiber app using Parsleyโ€™s DI container. +* **Register Dependencies:** Define and register services and route handlers with the DI container. +* **Resolve Dependencies:** Automatically resolve and inject them where needed. + +## Key Features + +* **Modular Configuration:** Services are registered in modules, allowing for a clean separation of concerns. +* **Automatic Dependency Injection:** Constructor-based dependency injection wire services together. +* **Simplified Route Management:** Route handlers are registered and managed via the DI container, making it easy to extend and maintain. + +## How It Works + +* The `main` function bootstraps the application using Parsleyโ€™s `RunParsleyApplication` function. +* Modules define how services (such as the Fiber app and route handlers) are registered and configured. +* Route handlers are implemented as services that receive their dependencies (like the `Greeter` service) via constructor injection. +The `Greeter` service is a simple example of how services can be injected and used within route handlers to handle HTTP requests. + +## Running the Example + +To run this example: + +* Clone the repository and navigate to the example directory. +* Run `go run main.go` to start the application. +* Access the application by navigating to `http://localhost:5502/say-hello?name=YourName`. This will return a greeting message, demonstrating the integration of Parsley with GoFiber. \ No newline at end of file diff --git a/docs/recipes/rabbitmq/README.md b/docs/recipes/rabbitmq/README.md new file mode 100644 index 00000000000..229e17d742e --- /dev/null +++ b/docs/recipes/rabbitmq/README.md @@ -0,0 +1,43 @@ +# Fiber and RabbitMQ example + +1. Create Docker network: + +```bash +make docker.network +``` + +2. Run Docker container with RabbitMQ: + +```bash +make docker.rabbitmq +``` + +3. Wait 2-3 minutes for the RabbitMQ container to be ready to use. +4. Run Docker container with worker: + +```bash +make docker.worker +``` + +5. Start Fiber API server (_on another console_): + +```bash +make run +``` + +6. Go to [127.0.0.1:3000/send?msg=Hello!](http://127.0.0.1:3000/send?msg=Hello!) and see received message on worker's console, like this: + +```console +2021/03/27 16:32:35 Successfully connected to RabbitMQ instance +2021/03/27 16:32:35 [*] - Waiting for messages +2021/03/27 16:32:35 [*] - Run Fiber API server and go to http://127.0.0.1:3000/send?msg= +2021/03/27 16:33:24 Received message: Hello! +``` + +7. Also, you can see useful RabbitMQ dashboard at [localhost:15672](http://localhost:15672): + +![Screenshot](https://user-images.githubusercontent.com/11155743/112728092-8fe3a980-8f36-11eb-9d79-be8eab26358b.png) + +## How it works? + +![Screenshot](https://user-images.githubusercontent.com/11155743/112727736-f8ca2200-8f34-11eb-8d40-12d9f381bd05.png) diff --git a/docs/recipes/react-router/README.md b/docs/recipes/react-router/README.md new file mode 100644 index 00000000000..2e39c5f20bf --- /dev/null +++ b/docs/recipes/react-router/README.md @@ -0,0 +1,35 @@ +# React Fiber + +A sample application to showcase serving React (with Router) with an almost bare Fiber. Hopefully, this application can be of use (as a reference or others) for those who wants to serve their client-side SPA with Fiber. + +## Technologies + +- Go with Fiber +- React with TypeScript and React Router +- Docker + +## Application + +- This application has three routes: `/`, `/react`, and a catch-all, 404 route. `/` will show the Fiber logo, `/react` will show the React logo, and the 404 route will show both logos. +- As this application serves the frontend while backed by a server, the client-side routing will work well and will not cause any issue (unlike if you are running without a file server). You can type the URL route manually in the browser and it will still work and will render the accurate page, so no worries. +- This is a simplified form of Create React App with TypeScript. With that being said, that's why there is no `manifest.json`, `logo512.png`, and other extra things like that. +- I restructured the project structure to be a bit more modular by categorizing files to `assets`, `components`, and `styles`. I also made it so all of the CSS is loaded in `index.tsx` for easier seeing. +- I also moved several dependencies to their appropriate places, such as `@types` and `test` in development dependencies instead of dependencies. + +## Installation + +It is recommended that you use Docker to instantly run this application. After running the Docker application, please open `localhost:8080` in your browser. Make sure you are in the `react-router` folder before running these commands. + +```bash +docker build . -t react-router:latest +docker run -d -p 8080:8080 react-router:latest +``` + +If you prefer doing things manually, then the installation steps are as follows: + +- Clone the repository by using `git clone git@github.com:gofiber/recipes.git`. +- Switch to the application by using `cd recipes/react-router`. +- Install npm dependencies by using `cd web && yarn install`. +- Build frontend by using `yarn build`. +- Run the Fiber application by using `go run cmd/react-router/main.go`. Don't forget to return to the main repository by using `cd ..` (assuming you are in `web` folder). +- Open `localhost:8080` in your browser. diff --git a/docs/recipes/react-router/web/public/logo192.png b/docs/recipes/react-router/web/public/logo192.png new file mode 100644 index 00000000000..fc44b0a3796 Binary files /dev/null and b/docs/recipes/react-router/web/public/logo192.png differ diff --git a/docs/recipes/react-router/web/src/assets/fiber-logo.svg b/docs/recipes/react-router/web/src/assets/fiber-logo.svg new file mode 100644 index 00000000000..f52e60df8d8 --- /dev/null +++ b/docs/recipes/react-router/web/src/assets/fiber-logo.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + diff --git a/docs/recipes/react-router/web/src/assets/react-logo.svg b/docs/recipes/react-router/web/src/assets/react-logo.svg new file mode 100644 index 00000000000..9dfc1c058ce --- /dev/null +++ b/docs/recipes/react-router/web/src/assets/react-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/recipes/sessions-sqlite3/README.md b/docs/recipes/sessions-sqlite3/README.md new file mode 100644 index 00000000000..f3db7fc474a --- /dev/null +++ b/docs/recipes/sessions-sqlite3/README.md @@ -0,0 +1,9 @@ +# Sessions - SQLite3 + +A real-world example of how to use Fiber sessions with Storage package.\ +Run localhost:3000 from multiple browsers to see active sessions for different users. + +## Explanation + +This example uses SQLite3 Storage package to persist users sessions.\ +Storage package can create sessions table for you at init time but for the purpose of this example I created it manually expanding its structure with an "u" column to better query all user-related sessions. \ No newline at end of file diff --git a/docs/recipes/socketio/README.md b/docs/recipes/socketio/README.md new file mode 100644 index 00000000000..21fbaf320c0 --- /dev/null +++ b/docs/recipes/socketio/README.md @@ -0,0 +1,20 @@ +### Disclaimer: +__This an example of a basic chat, connecting multiple sockets.__ + +## Websocket Chat Example +With this example, you can create a simple chatroom using Websockets. This example supports multiple users and allows them to send messages to each other. + +### Connect to the websocket +``` +ws://localhost:3000/ws/ +``` +### Message object example + +``` +{ +"from": "", +"to": "", +"data": "hello" +} +``` + diff --git a/docs/recipes/sqlboiler/README.md b/docs/recipes/sqlboiler/README.md new file mode 100644 index 00000000000..d216a02177b --- /dev/null +++ b/docs/recipes/sqlboiler/README.md @@ -0,0 +1,103 @@ +# Fiber with sqlboiler + +> #### ๐ŸŽฏ [Fiber](https://github.com/gofiber/fiber) + [Sqlboiler](https://github.com/volatiletech/sqlboiler) Example + +## ๐Ÿ‘€ Usage +#### 1. Run Postgres +```bash +$ docker compose build +``` +```bash +$ docker compose up +``` +#### 2. Wait 1-2 minutes +```console +[+] Running 2/0 + โœ” Network sqlboiler_default Created 0.0s + โœ” Container postgres Created 0.0s +Attaching to postgres +postgres | +postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization +postgres | +postgres | 2023-09-22 01:09:46.453 UTC [1] LOG: starting PostgreSQL 16.0 (Debian 16.0-1.pgdg120+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit +postgres | 2023-09-22 01:09:46.453 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 +postgres | 2023-09-22 01:09:46.453 UTC [1] LOG: listening on IPv6 address "::", port 5432 +postgres | 2023-09-22 01:09:46.454 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" +postgres | 2023-09-22 01:09:46.461 UTC [30] LOG: database system was shut down at 2023-09-22 01:09:44 UTC +postgres | 2023-09-22 01:09:46.468 UTC [1] LOG: database system is ready to accept connections +``` +#### 3. You have to migrate the database. +> ###### ๐ŸŽฏ It is a "database-first" ORM as opposed to "code-first" (like gorm/gorp). That means you must first create your database schema. +> ###### ๐ŸŽฏ I used [golang-migrate](https://github.com/golang-migrate/migrate) to proceed with the migrate. +###### 1. Make Migration files +```bash +$ migrate create -ext sql -dir ./migrations -seq create_initial_table +``` +```console +sqlboiler/migrations/000001_create_initial_table.up.sql +sqlboiler/migrations/000001_create_initial_table.up.sql +``` +###### 2. Migrate +```bash +$ migrate -path migrations -database "postgresql://user:password@localhost:5432/fiber_demo?sslmode=disable" -verbose up +``` +```console +2023/09/22 20:00:00 Start buffering 1/u create_initial_table +2023/09/22 20:00:00 Read and execute 1/u create_initial_table +2023/09/22 20:00:00 Finished 1/u create_initial_table (read 24.693541ms, ran 68.30925ms) +2023/09/22 20:00:00 Finished after 100.661625ms +2023/09/22 20:00:00 Closing source and database +``` +###### 3. Rollback Migrate +```bash +$ migrate -path migrations -database "postgresql://user:password@localhost:5432/fiber_demo?sslmode=disable" -verbose down +``` +```console +2023/09/22 20:00:00 Are you sure you want to apply all down migrations? [y/N] +y +2023/09/22 20:00:00 Applying all down migrations +2023/09/22 20:00:00 Start buffering 1/d create_initial_table +2023/09/22 20:00:00 Read and execute 1/d create_initial_table +2023/09/22 20:00:00 Finished 1/d create_initial_table (read 39.681125ms, ran 66.220125ms) +2023/09/22 20:00:00 Finished after 1.83152475s +``` +#### 4. Use sqlboiler +###### 1. Install +```bash +# Go 1.16 and above: +$ go install github.com/volatiletech/sqlboiler/v4@latest +$ go install github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-psql@latest +``` +###### 2. Create a configuration file +> ###### ๐ŸŽฏ The configuration file should be named sqlboiler.toml +###### Example +```toml +output = "models" +wipe = true +no-tests = true +add-enum-types = true + +[psql] + dbname = "fiber_demo" + host = "localhost" + port = 5432 + user = "user" + pass = "password" + schema = "schema" + blacklist = ["migrations", "other"] +``` +###### 3. Create models +> ###### ๐ŸŽฏ After creating a configuration file that points at the database we want to generate models for, we can invoke the sqlboiler command line utility. +```bash +$ sqlboiler psql +``` +```text +models/ +โ”œโ”€โ”€ author.go +โ”œโ”€โ”€ boil_queries.go +โ”œโ”€โ”€ boil_table_names.go +โ”œโ”€โ”€ boil_types.go +โ”œโ”€โ”€ boil_view_names.go +โ”œโ”€โ”€ post.go +โ”œโ”€โ”€ schema_migrations.go +``` diff --git a/docs/recipes/sqlc/README.md b/docs/recipes/sqlc/README.md new file mode 100644 index 00000000000..efc24c8c1a3 --- /dev/null +++ b/docs/recipes/sqlc/README.md @@ -0,0 +1,135 @@ +# Fiber with sqlc + +> #### ๐ŸŽฏ [fiber](https://github.com/gofiber/fiber) + [sqlc](https://github.com/sqlc-dev/sqlc) Example + +## ๐Ÿ‘€ Usage +#### 1. Run Postgres +```bash +$ docker compose build +``` +```bash +$ docker compose up +``` +#### 2. Wait 1-2 minutes +```console +[+] Running 2/0 + โœ” Network sqlc_default Created 0.1s + โœ” Container postgres Created 0.0s +Attaching to postgres +postgres | +postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization +postgres | +postgres | +postgres | 2023-09-28 09:17:50.737 UTC [1] LOG: starting PostgreSQL 16.0 (Debian 16.0-1.pgdg120+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit +postgres | 2023-09-28 09:17:50.737 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 +postgres | 2023-09-28 09:17:50.737 UTC [1] LOG: listening on IPv6 address "::", port 5432 +postgres | 2023-09-28 09:17:50.740 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" +postgres | 2023-09-28 09:17:50.751 UTC [30] LOG: database system was shut down at 2023-09-28 08:50:35 UTC +postgres | 2023-09-28 09:17:50.770 UTC [1] LOG: database system is ready to accept connections +``` +#### 3. You have to migrate the database. +> ##### ๐ŸŽฏ It is a "database-first" ORM as opposed to "code-first" (like gorm/gorp). That means you must first create your database schema. +> ##### ๐ŸŽฏ I used [golang-migrate](https://github.com/golang-migrate/migrate) to proceed with the migrate. +###### 1. Make Migration files +```bash +$ migrate create -ext sql -dir ./database/migrations -seq create_initial_table +``` +```console +sqlc/database/migrations/000001_create_initial_table.up.sql +sqlc/database/migrations/000001_create_initial_table.up.sql +``` +###### 2. Migrate +```bash +$ migrate -path database/migrations -database "postgresql://user:password@localhost:5432/fiber_demo?sslmode=disable" -verbose up +``` +```console +2023/09/28 20:00:00 Start buffering 1/u create_initial_table +2023/09/28 20:00:00 Read and execute 1/u create_initial_table +2023/09/28 20:00:00 Finished 1/u create_initial_table (read 24.693541ms, ran 68.30925ms) +2023/09/28 20:00:00 Finished after 100.661625ms +2023/09/28 20:00:00 Closing source and database +``` +###### 3. Rollback Migrate +```bash +$ migrate -path database/migrations -database "postgresql://user:password@localhost:5432/fiber_demo?sslmode=disable" -verbose down +``` +```console +2023/09/28 20:00:00 Are you sure you want to apply all down migrations? [y/N] +y +2023/09/28 20:00:00 Applying all down migrations +2023/09/28 20:00:00 Start buffering 1/d create_initial_table +2023/09/28 20:00:00 Read and execute 1/d create_initial_table +2023/09/28 20:00:00 Finished 1/d create_initial_table (read 39.681125ms, ran 66.220125ms) +2023/09/28 20:00:00 Finished after 1.83152475s +``` +#### 4. Use sqlc +###### 1. Install +```bash +# Go 1.17 and above: +$ go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest + +# Go 1.16 and below: +go get github.com/sqlc-dev/sqlc/cmd/sqlc +``` +###### 2. Create a configuration file +###### Example +###### sqlc.yaml +```yaml +version: "2" +sql: + - engine: "postgresql" + queries: "database/query" + schema: "database/migrations" + gen: + go: + package: "sqlc" + out: "database/sqlc" +``` +###### author.sql +```sql +-- name: GetAuthors :many +SELECT * FROM author; + +-- name: GetAuthor :one +SELECT * FROM author WHERE id = $1; + +-- name: NewAuthor :one +INSERT INTO author (email, name) VALUES ($1, $2) RETURNING *; + +-- name: UpdateAuthor :one +UPDATE author SET email = $1, name = $2 WHERE id = $3 RETURNING *; + +-- name: DeleteAuthor :exec +DELETE FROM author WHERE id = $1; +``` +###### post.sql +```sql +-- name: GetPosts :many +SELECT * FROM post; + +-- name: GetPost :one +SELECT * FROM post WHERE id = $1; + +-- name: NewPost :one +INSERT INTO post (title, content, author) VALUES ($1, $2, $3) RETURNING *; + +-- name: UpdatePost :one +UPDATE post SET title = $1, content = $2, author = $3 WHERE id = $4 RETURNING *; + +-- name: DeletePost :exec +DELETE FROM post WHERE id = $1; + +``` +###### 3. Generate +```bash +$ sqlc generate +``` +```text +sqlc/ +โ”œโ”€โ”€ author.sql.go +โ”œโ”€โ”€ db.go +โ”œโ”€โ”€ models.go +โ”œโ”€โ”€ post.sql.go +``` +#### 5. Reference +[sqlc document](https://docs.sqlc.dev/en/stable/) \ No newline at end of file diff --git a/docs/recipes/sse/README.md b/docs/recipes/sse/README.md new file mode 100644 index 00000000000..1f332d5aa65 --- /dev/null +++ b/docs/recipes/sse/README.md @@ -0,0 +1,8 @@ +# Server-Sent Events with Fiber + +[More info](https://en.wikipedia.org/wiki/Server-sent_events) about SSE. + +## Endpoints + +- GET / - _Index_ +- GET /sse - _SSE Route_ diff --git a/docs/recipes/sveltekit-embed/README.md b/docs/recipes/sveltekit-embed/README.md new file mode 100644 index 00000000000..e8590efdb5e --- /dev/null +++ b/docs/recipes/sveltekit-embed/README.md @@ -0,0 +1,66 @@ +# Fiber Sveltekit Embed App +![image](https://github.com/gofiber/recipes/assets/40540244/2aa084b8-9bbc-46f3-9759-930857429f05) + +This application is a full-stack project built using Sveltekit, Tailwind CSS, Fiber. It showcases the construction of a monolithic architecture for a full-stack application. + +## Run the Project + +To run the project, follow these steps: + +1. Execute the following command to run all the necessary commands for building and running the application: + +```bash +make all +``` +2. Once the build process is complete, you can start the application by running: +```bash +./app +``` + + +## Available Commands +The following commands are available to manage the project: + + +| Command | Description | +| --- | --- | +| `info` | Info command. Displays the available commands and the purpose of the application. | +| `go-build` | Builds the Golang project and creates an `app` file. | +| `svelte-build` | Builds the SvelteKit project. It first installs the dependencies and then performs the project build. | +| `all` | Runs both `svelte-build` and `go-build` commands sequentially. | + +## Usage + +To use this application, run the following command: + +```bash +make +``` + + +API Routes +---------- + +The Go Fiber application provides the following API routes: + +| Route | Description | +| --- | --- | +| `/*` | Serves static files from the specified directory (`template.Dist()`). If a file is not found, it serves `index.html`. | + +Go Dependencies +--------------- + +- **Go Modules:** Go's built-in package manager used to manage dependencies for Go projects. +- **Fiber:** A fast and minimalist web framework for Golang. + +Npm Dependencies +---------------- + +- **SvelteKit:** A JavaScript framework used to build modern web applications. +- **Tailwind CSS:** A fast and customizable CSS styling library. Can be used in SvelteKit projects. +- **Skeleton UI:** This is a fully featured UI Toolkit for building reactive interfaces quickly using Svelte and Tailwind. + +---------------- + +Author: [@ugurkorkmaz](https://github.com/ugurkorkmaz) + diff --git a/docs/recipes/sveltekit-embed/template/README.md b/docs/recipes/sveltekit-embed/template/README.md new file mode 100644 index 00000000000..5c91169b0ca --- /dev/null +++ b/docs/recipes/sveltekit-embed/template/README.md @@ -0,0 +1,38 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm create svelte@latest + +# create a new project in my-app +npm create svelte@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/docs/recipes/sveltekit-embed/template/static/favicon.png b/docs/recipes/sveltekit-embed/template/static/favicon.png new file mode 100644 index 00000000000..20422759555 Binary files /dev/null and b/docs/recipes/sveltekit-embed/template/static/favicon.png differ diff --git a/docs/recipes/sveltekit-embed/template/static/fiber-logo.svg b/docs/recipes/sveltekit-embed/template/static/fiber-logo.svg new file mode 100644 index 00000000000..7cc7b6022ea --- /dev/null +++ b/docs/recipes/sveltekit-embed/template/static/fiber-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/recipes/sveltekit-embed/template/static/logo.svg b/docs/recipes/sveltekit-embed/template/static/logo.svg new file mode 100644 index 00000000000..c481c811d56 --- /dev/null +++ b/docs/recipes/sveltekit-embed/template/static/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/recipes/swagger/README.md b/docs/recipes/swagger/README.md new file mode 100644 index 00000000000..26045aff5c3 --- /dev/null +++ b/docs/recipes/swagger/README.md @@ -0,0 +1,53 @@ +# Simple Swagger Implementation for [Fiber](https://github.com/gofiber/fiber) + +This example use [fiber-swagger](https://github.com/arsmn/fiber-swagger) and [swaggo](https://github.com/swaggo/swag) (Go converter to Swagger Documentation 2.0) + +## Usage + +1. Download [swaggo](https://github.com/swaggo/swag) by using: + + ```bash + $ go get -u github.com/swaggo/swag/cmd/swag + + # 1.16 or newer + $ go install github.com/swaggo/swag/cmd/swag@latest + ``` + +2. Add comments to your API source code (example: `handlers/book.go`) or more details: [swaggo documentation](https://swaggo.github.io/swaggo.io/declarative_comments_format/). + +3. Download [fiber-swagger](https://github.com/arsmn/fiber-swagger) by using: + + ```bash + $ go get -u github.com/arsmn/fiber-swagger/v2 + ``` + +4. Import to your routes file (example: `routes/routes.go`): + + ```go + import swagger "github.com/arsmn/fiber-swagger/v2" + ``` + +5. Add swagger handler to routes as a middleware (example: `routes/routes.go`): + + ```go + app.Get("/docs/*", swagger.Handler) // default + + app.Get("/docs/*", swagger.New(swagger.Config{ // custom + URL: "http://example.com/doc.json", + DeepLinking: false, + })) + ``` + +6. Run the [swaggo](https://github.com/swaggo/swag) command in your Go project root directory which contain `main.go` file. This command will generate required files (`docs` and `docs/doc.go`) + + ```bash + $ swag init + ``` + +7. Import docs directory that generated by Swag CLI to your `main.go` file: + + ```go + import _ "swagger/docs" + ``` + +8. Horray! You're ready to Go ๐Ÿš€ \ No newline at end of file diff --git a/docs/recipes/tableflip/README.md b/docs/recipes/tableflip/README.md new file mode 100644 index 00000000000..c0454838cd7 --- /dev/null +++ b/docs/recipes/tableflip/README.md @@ -0,0 +1,34 @@ +## tableflip example +### What is [tableflip](https://github.com/cloudflare/tableflip) +> It is sometimes useful to update the running code and / or configuration of a network service, without disrupting existing connections. Usually, this is achieved by starting a new process, somehow transferring clients to it and then exiting the old process. + +> There are many ways to implement graceful upgrades. They vary wildly in the trade-offs they make, and how much control they afford the user. This library has the following goals: +> - No old code keeps running after a successful upgrade +> - The new process has a grace period for performing initialisation +> - Crashing during initialisation is OK +> - Only a single upgrade is ever run in parallel +> - tableflip works on Linux and macOS. + +### Steps +1. Build v0.0.1 demo. + ```bash + go build -o demo main.go + ``` +2. Run the demo and create a get request to `127.0.0.1:8080/version`, here is the output: + ```bash + [PID: 123] v0.0.1 + ``` +3. Prepare a new version. change the main.go, let the version be "v0.0.2" and rebuild it. + ```bash + go build -o demo main.go + ``` +4. Now, kill the old one ! + ```bash + kill -s HUP 123 + ``` +5. Create the request to version api again, but output is changed: + ```bash + [PID: 123] v0.0.2 + ``` + +The client is completely immune to server upgrades and reboots, and our application updates gracefully! diff --git a/docs/recipes/template-asset-bundling/README.md b/docs/recipes/template-asset-bundling/README.md new file mode 100644 index 00000000000..dabf5eaa09f --- /dev/null +++ b/docs/recipes/template-asset-bundling/README.md @@ -0,0 +1,27 @@ +# template-asset-bundling + +This is a quick example of how to do asset bundling. +It's using [gofiber/template](https://github.com/gofiber/template), [Tailwind CSS](https://tailwindcss.com) and [Parcel](https://parceljs.org). + +## Additional requirements +- node.js +- npm + +## Usage + +First build the assets +```bash +# Install dependencies +npm install + +# Build assets +npm run build + +# Watch assets for changes +npm run dev +``` + +Then run the fiber app +```bash +go run main.go +``` diff --git a/docs/recipes/template-asset-bundling/public/icon.png b/docs/recipes/template-asset-bundling/public/icon.png new file mode 100644 index 00000000000..20422759555 Binary files /dev/null and b/docs/recipes/template-asset-bundling/public/icon.png differ diff --git a/docs/recipes/todo-app-with-auth-gorm/README.md b/docs/recipes/todo-app-with-auth-gorm/README.md new file mode 100644 index 00000000000..81c05fad21b --- /dev/null +++ b/docs/recipes/todo-app-with-auth-gorm/README.md @@ -0,0 +1,35 @@ +# Prerequisite + +1. Make sure you have the following installed outside the current project directory and available in your `GOPATH` + - golang + - [air](https://github.com/air-verse/air) for hot reloading + - [godotenv](https://github.com/joho/godotenv) for loading `.env` file + +# Installation + +1. Clone this repo +2. Run `go get` + +# Running + +1. Type `air` in the command line + +# Environment Variables + +```shell +# PORT returns the server listening port +# default: 5000 +PORT= + +# DB returns the name of the sqlite database +# default: gotodo.db +DB= + +# TOKENKEY returns the jwt token secret +TOKENKEY= + +# TOKENEXP returns the jwt token expiration duration. +# Should be time.ParseDuration string. Source: https://golang.org/pkg/time/#ParseDuration +# default: 10h +TOKENEXP= +``` diff --git a/docs/recipes/unit-test/README.md b/docs/recipes/unit-test/README.md new file mode 100644 index 00000000000..4c256acf7fa --- /dev/null +++ b/docs/recipes/unit-test/README.md @@ -0,0 +1,187 @@ +# Unit Testing Example + +This example demonstrates how to write unit tests for a Go Fiber application using the `stretchr/testify` package. + +## Description + +This project provides a basic setup for unit testing in a Go Fiber application. It includes examples of how to structure tests, write test cases, and use the `stretchr/testify` package for assertions. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [Git](https://git-scm.com/downloads) + +## Project Structure + +- `main.go`: The main application entry point. +- `main_test.go`: The test file containing unit tests. +- `go.mod`: The Go module file. + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/unit-test + ``` + +2. Install the dependencies: + ```bash + go mod download + ``` + +## Running the Tests + +To run the tests, use the following command: +```bash +go test ./... +``` + +## Example Usage + +The `main.go` file sets up a simple Fiber application with a single route. The `main_test.go` file contains unit tests for this application. + +### `main.go` + +This file sets up a basic Fiber application with a single route that returns "OK". + +### `main_test.go` + +This file contains unit tests for the Fiber application. It uses the `stretchr/testify` package for assertions. + +```go +package main + +import ( + "io" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIndexRoute(t *testing.T) { + tests := []struct { + description string + route string + expectedError bool + expectedCode int + expectedBody string + }{ + { + description: "index route", + route: "/", + expectedError: false, + expectedCode: 200, + expectedBody: "OK", + }, + { + description: "non existing route", + route: "/i-dont-exist", + expectedError: false, + expectedCode: 404, + expectedBody: "Cannot GET /i-dont-exist", + }, + } + + app := Setup() + + for _, test := range tests { + req, _ := http.NewRequest("GET", test.route, nil) + res, err := app.Test(req, -1) + assert.Equalf(t, test.expectedError, err != nil, test.description) + if test.expectedError { + continue + } + assert.Equalf(t, test.expectedCode, res.StatusCode, test.description) + body, err := io.ReadAll(res.Body) + assert.Nilf(t, err, test.description) + assert.Equalf(t, test.expectedBody, string(body), test.description) + } +} +``` + +## Unit Testing in General + +Unit testing is a software testing method where individual units or components of a software are tested in isolation from the rest of the application. The purpose of unit testing is to validate that each unit of the software performs as expected. Unit tests are typically automated and written by developers as part of the development process. + +### Benefits of Unit Testing + +- **Early Bug Detection**: Unit tests help in identifying bugs early in the development cycle. +- **Documentation**: Unit tests can serve as documentation for the code. +- **Refactoring Support**: Unit tests provide a safety net when refactoring code. +- **Design**: Writing unit tests can lead to better software design. + +## Unit Testing in Fiber + +Fiber is an Express-inspired web framework written in Go. Unit testing in Fiber involves testing the individual routes and handlers to ensure they behave as expected. The `stretchr/testify` package is commonly used for writing assertions in Go tests. + +### Writing Unit Tests in Fiber + +1. **Setup the Application**: Create a function to setup the Fiber application. This function can be reused in the tests. +2. **Define Test Cases**: Create a structure to define the input and expected output for each test case. +3. **Perform Requests**: Use the `app.Test` method to perform HTTP requests and capture the response. +4. **Assertions**: Use the `stretchr/testify` package to write assertions and verify the response. + +### The `app.Test` Method + +The `app.Test` method in Fiber is used to simulate HTTP requests to the Fiber application and test the responses. This is particularly useful for unit tests as it allows testing the routes and handlers of the application without starting a real server. + +#### Usage of the `app.Test` Method + +The `app.Test` method takes two parameters: +1. **req**: An `*http.Request` object representing the HTTP request to be tested. +2. **timeout**: An `int` value specifying the maximum time in milliseconds that the request can take. A value of `-1` disables the timeout. + +The method returns an `*http.Response` and an `error`. The `*http.Response` contains the application's response to the simulated request, and the `error` indicates if any error occurred during the request processing. + +#### Example + +Here is an example of how the `app.Test` method is used in a unit test: + +```go +package main + +import ( + "io" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIndexRoute(t *testing.T) { + // Setup the app as it is done in the main function + app := Setup() + + // Create a new HTTP request + req, _ := http.NewRequest("GET", "/", nil) + + // Perform the request using app.Test + res, err := app.Test(req, -1) + + // Verify that no error occurred + assert.Nil(t, err) + + // Verify the status code + assert.Equal(t, 200, res.StatusCode) + + // Read the response body + body, _ := io.ReadAll(res.Body) + + // Verify the response body + assert.Equal(t, "OK", string(body)) +} +``` + +In this example, a GET request is sent to the root route (`"/"`) of the application. The response is verified to ensure that the status code is `200` and the response text is `"OK"`. + +## Conclusion + +This example provides a basic setup for unit testing in a Go Fiber application. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Fiber Documentation](https://docs.gofiber.io) +- [Testify Documentation](https://github.com/stretchr/testify) +- [Go Testing](https://golang.org/pkg/testing/) diff --git a/docs/recipes/upload-file/README.md b/docs/recipes/upload-file/README.md new file mode 100644 index 00000000000..99e7d51e209 --- /dev/null +++ b/docs/recipes/upload-file/README.md @@ -0,0 +1,107 @@ +# File Upload Example + +This example demonstrates how to handle file uploads using Go Fiber. + +## Description + +This project provides a basic setup for handling file uploads in a Go Fiber application. It includes examples for uploading single and multiple files, as well as saving files to different directories. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [Git](https://git-scm.com/downloads) + +## Project Structure + +- `single/main.go`: Example for uploading a single file to the root directory. +- `single_relative_path/main.go`: Example for uploading a single file to a relative path. +- `multiple/main.go`: Example for uploading multiple files. +- `go.mod`: The Go module file. + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/upload-file + ``` + +2. Install the dependencies: + ```bash + go mod download + ``` + +## Running the Examples + +### Single File Upload + +1. Navigate to the `single` directory: + ```bash + cd single + ``` + +2. Run the application: + ```bash + go run main.go + ``` + +3. Use a tool like `curl` or Postman to upload a file: + ```bash + curl -F "document=@/path/to/your/file" http://localhost:3000/ + ``` + +### Single File Upload with Relative Path + +1. Navigate to the `single_relative_path` directory: + ```bash + cd single_relative_path + ``` + +2. Run the application: + ```bash + go run main.go + ``` + +3. Use a tool like `curl` or Postman to upload a file: + ```bash + curl -F "document=@/path/to/your/file" http://localhost:3000/ + ``` + +### Multiple File Upload + +1. Navigate to the `multiple` directory: + ```bash + cd multiple + ``` + +2. Run the application: + ```bash + go run main.go + ``` + +3. Use a tool like `curl` or Postman to upload multiple files: + ```bash + curl -F "documents=@/path/to/your/file1" -F "documents=@/path/to/your/file2" http://localhost:3000/ + ``` + +## Code Overview + +### `single/main.go` + +Handles uploading a single file to the root directory. + +### `single_relative_path/main.go` + +Handles uploading a single file to a relative path. + +### `multiple/main.go` + +Handles uploading multiple files. + +## Conclusion + +This example provides a basic setup for handling file uploads in a Go Fiber application. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Fiber Documentation](https://docs.gofiber.io) diff --git a/docs/recipes/url-shortener-api/README.md b/docs/recipes/url-shortener-api/README.md new file mode 100644 index 00000000000..b003be083a8 --- /dev/null +++ b/docs/recipes/url-shortener-api/README.md @@ -0,0 +1,34 @@ +#### Tech Stack + +- Golang +- Redis + +### API Documentation + +> API endpoint: http://localhost:3000/api/v1/ + +#### API Payload + +- "url" - Original URL +- "short" - Custom short URL(Optional) +- "expiry" - Time to expire: int(hours) + +#### API Response + +- "url" - Original URL +- "short" - Custom short URL +- "expiry" - Time to expire: int(hours) +- "rate_limit" - # of API calls remaining: int +- "rate_limit_reset" - Time to rate limit reset: int(minutes) + +> API is rate limited to 10 calls every 30mins. +> These values can be changed in the .env file. Have fun. + +#### Demo + +1. Start the containers +``` +docker-compose up -d +``` +2. Test the API +![test.gif](test.gif) diff --git a/docs/recipes/url-shortener-api/test.gif b/docs/recipes/url-shortener-api/test.gif new file mode 100644 index 00000000000..45c09d5e9dd Binary files /dev/null and b/docs/recipes/url-shortener-api/test.gif differ diff --git a/docs/recipes/validation/README.md b/docs/recipes/validation/README.md new file mode 100644 index 00000000000..4e59021d3d8 --- /dev/null +++ b/docs/recipes/validation/README.md @@ -0,0 +1,87 @@ +# Validation with [Fiber](https://gofiber.io) + +This example demonstrates how to use [go-playground/validator](https://github.com/go-playground/validator) for input validation in a Go Fiber application. + +## Description + +This project provides a basic setup for validating request data in a Go Fiber application using the `go-playground/validator` package. It includes the necessary configuration and code to perform validation on incoming requests. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [Git](https://git-scm.com/downloads) + +## Project Structure + +- `main.go`: The main application entry point. +- `config/env.go`: Configuration file for environment variables. +- `go.mod`: The Go module file. +- `.env`: Environment variables file. + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/validation + ``` + +2. Install the dependencies: + ```bash + go mod download + ``` + +3. Create a `.env` file in the root directory with the following content: + ```dotenv + PORT=":8080" + ``` + +4. Run the application: + ```bash + go run main.go + ``` + +The application should now be running on `http://localhost:8080`. + +## Example Usage + +1. Send a POST request to `http://localhost:8080/validate` with a JSON payload: + ```json + { + "name": "John Doe", + "email": "john.doe@example.com", + "age": 30 + } + ``` + +2. The server will validate the request data and respond with a success message if the data is valid, or an error message if the data is invalid. + +## Code Overview + +### `main.go` + +The main Go file sets up the Fiber application, handles HTTP requests, and performs validation using the `go-playground/validator` package. + +### `config/env.go` + +The configuration file for loading environment variables. + +```go +package config + +import "os" + +// Config func to get env value +func Config(key string) string { + return os.Getenv(key) +} +``` + +## Conclusion + +This example provides a basic setup for validating request data in a Go Fiber application using the `go-playground/validator` package. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Fiber Documentation](https://docs.gofiber.io) +- [Validator Documentation](https://github.com/go-playground/validator) diff --git a/docs/recipes/vercel/README.md b/docs/recipes/vercel/README.md new file mode 100644 index 00000000000..f37f23f515b --- /dev/null +++ b/docs/recipes/vercel/README.md @@ -0,0 +1,127 @@ +# Vercel Example + +This example demonstrates how to deploy a Go Fiber application to Vercel. + +## Description + +This project provides a starting point for deploying a Go Fiber application to Vercel. It includes the necessary configuration files and code to run a serverless application on Vercel. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [Git](https://git-scm.com/downloads) +- [Vercel CLI](https://vercel.com/download) + +## Project Structure + +- `api/index.go`: The main entry point for the serverless function. +- `vercel.json`: Configuration file for Vercel. +- `go.mod`: The Go module file. + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/vercel + ``` + +2. Install the dependencies: + ```bash + go mod download + ``` + +## Configuration + +Ensure the `vercel.json` file is present in the root directory to handle routing properly. This file rewrites all requests to the `api/index.go` handler. + +```json +{ + "rewrites": [ + { "source": "(.*)", "destination": "api/index.go" } + ] +} +``` + +## Deploy + +1. Install the Vercel CLI: + ```bash + npm install -g vercel + ``` + +2. Log in to Vercel: + ```bash + vercel login + ``` + +3. Deploy the application: + ```bash + vercel + ``` + +Follow the prompts to complete the deployment. Your application will be deployed to Vercel and a URL will be provided. + +## Example Usage + +1. Open your browser and navigate to the provided Vercel URL. +2. You should see the JSON response with the URI and path. + +## Code Overview + +### `api/index.go` + +The main Go file sets up the Fiber application, handles HTTP requests, and manages the routing. + +```go +package handler + +import ( + "github.com/gofiber/fiber/v2/middleware/adaptor" + "github.com/gofiber/fiber/v2" + "net/http" +) + +// Handler is the main entry point of the application. Think of it like the main() method +func Handler(w http.ResponseWriter, r *http.Request) { + // This is needed to set the proper request path in `*fiber.Ctx` + r.RequestURI = r.URL.String() + + handler().ServeHTTP(w, r) +} + +// building the fiber application +func handler() http.HandlerFunc { + app := fiber.New() + + app.Get("/v1", func(ctx *fiber.Ctx) error { + return ctx.JSON(fiber.Map{ + "version": "v1", + }) + }) + + app.Get("/v2", func(ctx *fiber.Ctx) error { + return ctx.JSON(fiber.Map{ + "version": "v2", + }) + }) + + app.Get("/", func(ctx *fiber.Ctx) error { + return ctx.JSON(fiber.Map{ + "uri": ctx.Request().URI().String(), + "path": ctx.Path(), + }) + }) + + return adaptor.FiberApp(app) +} +``` + +## Conclusion + +This example provides a basic setup for deploying a Go Fiber application to Vercel. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Vercel Documentation](https://vercel.com/docs) +- [Fiber Documentation](https://docs.gofiber.io) diff --git a/docs/recipes/websocket-chat/README.md b/docs/recipes/websocket-chat/README.md new file mode 100644 index 00000000000..7a463a4d53d --- /dev/null +++ b/docs/recipes/websocket-chat/README.md @@ -0,0 +1,67 @@ +# WebSocket Chat Example + +This example demonstrates a simple chat application using Go Fiber and WebSockets. + +## Description + +This project provides a basic setup for a WebSocket-based chat application using Go Fiber. It includes the necessary configuration and code to run a real-time chat server. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [Git](https://git-scm.com/downloads) + +## Project Structure + +- `main.go`: The main application entry point. +- `home.html`: The HTML file for the chat client. +- `go.mod`: The Go module file. + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/websocket-chat + ``` + +2. Install the dependencies: + ```bash + go mod download + ``` + +3. Run the application: + ```bash + go run main.go + ``` + +The application should now be running on `http://localhost:8080`. + +## WebSocket Endpoints + +- **GET /ws**: WebSocket endpoint for the chat application. + +## Example Usage + +1. Open your browser and navigate to `http://localhost:8080`. +2. Enter a message in the input field and click "Send". +3. The message should appear in the chat log. + +## Code Overview + +### `main.go` + +The main Go file sets up the Fiber application, handles WebSocket connections, and manages the chat hub. + +### `home.html` + +The HTML file provides a simple user interface for the chat application, including a message log and input field. + +## Conclusion + +This example provides a basic setup for a WebSocket-based chat application using Go Fiber. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Fiber Documentation](https://docs.gofiber.io) +- [WebSocket Documentation](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) diff --git a/docs/recipes/websocket/README.md b/docs/recipes/websocket/README.md new file mode 100644 index 00000000000..b78e8d7a029 --- /dev/null +++ b/docs/recipes/websocket/README.md @@ -0,0 +1,108 @@ +# WebSocket Example + +This example demonstrates a simple WebSocket application using Go Fiber. + +## Description + +This project provides a basic setup for a WebSocket server using Go Fiber. It includes the necessary configuration and code to run a real-time WebSocket server. + +## Requirements + +- [Go](https://golang.org/dl/) 1.18 or higher +- [Git](https://git-scm.com/downloads) + +## Project Structure + +- `main.go`: The main application entry point. +- `go.mod`: The Go module file. + +## Setup + +1. Clone the repository: + ```bash + git clone https://github.com/gofiber/recipes.git + cd recipes/websocket + ``` + +2. Install the dependencies: + ```bash + go mod download + ``` + +3. Run the application: + ```bash + go run main.go + ``` + +The application should now be running on `http://localhost:3000`. + +## WebSocket Endpoint + +- **GET /ws**: WebSocket endpoint for the application. + +## Example Usage + +1. Connect to the WebSocket server at `ws://localhost:3000/ws`. +2. Send a message to the server. +3. The server will echo the message back to the client. + +## Code Overview + +### `main.go` + +The main Go file sets up the Fiber application, handles WebSocket connections, and manages the WebSocket communication. + +```go +package main + +import ( + "fmt" + "log" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/contrib/websocket" +) + +func main() { + app := fiber.New() + + // Optional middleware + app.Use("/ws", func(c *fiber.Ctx) error { + if c.Get("host") == "localhost:3000" { + c.Locals("Host", "Localhost:3000") + return c.Next() + } + return c.Status(403).SendString("Request origin not allowed") + }) + + // Upgraded websocket request + app.Get("/ws", websocket.New(func(c *websocket.Conn) { + fmt.Println(c.Locals("Host")) // "Localhost:3000" + 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 + } + } + })) + + // ws://localhost:3000/ws + log.Fatal(app.Listen(":3000")) +} +``` + +## Conclusion + +This example provides a basic setup for a WebSocket server using Go Fiber. It can be extended and customized further to fit the needs of more complex applications. + +## References + +- [Fiber Documentation](https://docs.gofiber.io) +- [WebSocket Documentation](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) diff --git a/docusaurus.config.js b/docusaurus.config.js index 446c76b94f5..bff88f9354e 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -94,7 +94,7 @@ const config = { return 'https://github.com/gofiber/contrib/edit/main/' + params.docPath; }, editCurrentVersion: true, - sidebarPath: require.resolve('./sidebarsContrib.js'), + sidebarPath: require.resolve('./default_sidebars.js'), showLastUpdateAuthor: false, showLastUpdateTime: true, }), @@ -109,7 +109,7 @@ const config = { return 'https://github.com/gofiber/storage/edit/main/' + params.docPath; }, editCurrentVersion: true, - sidebarPath: require.resolve('./sidebarsStorage.js'), + sidebarPath: require.resolve('./default_sidebars.js'), showLastUpdateAuthor: false, showLastUpdateTime: true, }), @@ -124,7 +124,22 @@ const config = { return 'https://github.com/gofiber/template/edit/master/' + params.docPath; }, editCurrentVersion: true, - sidebarPath: require.resolve('./sidebarsTemplate.js'), + sidebarPath: require.resolve('./default_sidebars.js'), + showLastUpdateAuthor: false, + showLastUpdateTime: true, + }), + ], + [ + '@docusaurus/plugin-content-docs', + ({ + id: 'recipes', + path: 'docs/recipes', + routeBasePath: 'recipes', + editUrl: (params) => { + return 'https://github.com/gofiber/recipes/edit/master/' + params.docPath; + }, + editCurrentVersion: true, + sidebarPath: require.resolve('./default_sidebars.js'), showLastUpdateAuthor: false, showLastUpdateTime: true, }), @@ -140,7 +155,7 @@ const config = { path: 'docs/core', routeBasePath: '/', sidebarCollapsed: false, - sidebarPath: require.resolve('./sidebars.js'), + sidebarPath: require.resolve('./default_sidebars.js'), // disabled until we make a redirect to the respective source repository // editUrl: 'https://github.com/gofiber/fiber/edit/master/', editUrl: (params) => { @@ -210,7 +225,8 @@ const config = { position: 'left', }, { - to: 'https://github.com/gofiber/recipes', + type: 'docsVersion', + docsPluginId: 'recipes', label: '๐Ÿณ Examples', position: 'left', }, @@ -276,6 +292,10 @@ const config = { label: '๐Ÿ“„๏ธ Template', href: 'https://github.com/gofiber/template', }, + { + label: '๐Ÿณ๏ธ Recipes', + href: 'https://github.com/gofiber/recipes', + }, ], }, ], diff --git a/sidebarsContrib.js b/sidebarsContrib.js deleted file mode 100644 index 5d6a1510fa2..00000000000 --- a/sidebarsContrib.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ - -// @ts-check - -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const sidebars = { - tutorialSidebar: [{ - type: 'autogenerated', - dirName: '.' - }], -}; - -module.exports = sidebars; diff --git a/sidebarsStorage.js b/sidebarsStorage.js deleted file mode 100644 index 5d6a1510fa2..00000000000 --- a/sidebarsStorage.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ - -// @ts-check - -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const sidebars = { - tutorialSidebar: [{ - type: 'autogenerated', - dirName: '.' - }], -}; - -module.exports = sidebars; diff --git a/sidebarsTemplate.js b/sidebarsTemplate.js deleted file mode 100644 index 5d6a1510fa2..00000000000 --- a/sidebarsTemplate.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ - -// @ts-check - -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const sidebars = { - tutorialSidebar: [{ - type: 'autogenerated', - dirName: '.' - }], -}; - -module.exports = sidebars;