github.com/System-Glitch/goyave/v3@v3.6.1-0.20210226143142-ac2fe42ee80e/README.md (about) 1 <p align="center"> 2 <img src="resources/img/logo/goyave_text.png" alt="Goyave Logo" width="550"/> 3 </p> 4 5 <p align="center"> 6 <a href="https://github.com/System-Glitch/goyave/releases"><img src="https://img.shields.io/github/v/release/System-Glitch/goyave?include_prereleases" alt="Version"/></a> 7 <a href="https://github.com/System-Glitch/goyave/actions"><img src="https://github.com/System-Glitch/goyave/workflows/Test/badge.svg?branch=develop" alt="Build Status"/></a> 8 <a href="https://coveralls.io/github/System-Glitch/goyave?branch=master"><img src="https://coveralls.io/repos/github/System-Glitch/goyave/badge.svg" alt="Coverage Status"/></a> 9 <a href="https://goreportcard.com/report/github.com/System-Glitch/goyave"><img src="https://goreportcard.com/badge/github.com/System-Glitch/goyave" alt="Go Report"/></a> 10 11 </p> 12 13 <p align="center"> 14 <a href="https://github.com/System-Glitch/goyave/blob/master/LICENSE"><img src="https://img.shields.io/dub/l/vibe-d.svg" alt="License"/></a> 15 <a href="https://github.com/avelino/awesome-go"><img src="https://awesome.re/mentioned-badge.svg" alt="Awesome"/></a> 16 <a href="https://discord.gg/mfemDMc"><img src="https://img.shields.io/discord/744264895209537617?logo=discord" alt="Discord"/></a> 17 </p> 18 19 <h2 align="center">An Elegant Golang Web Framework</h2> 20 21 Goyave is a progressive and accessible web application framework focused on REST APIs, aimed at making backend development easy and enjoyable. It has a philosophy of cleanliness and conciseness to make programs more elegant, easier to maintain and more focused. Goyave is an **opinionated** framework, helping your applications keeping a uniform architecture and limit redundancy. With Goyave, expect a full package with minimum setup. 22 23 - **Clean Code**: Goyave has an expressive, elegant syntax, a robust structure and conventions. Minimalist calls and reduced redundancy are among the Goyave's core principles. 24 - **Fast Development**: Develop faster and concentrate on the business logic of your application thanks to the many helpers and built-in functions. 25 - **Powerful functionalities**: Goyave is accessible, yet powerful. The framework includes routing, request parsing, validation, localization, testing, authentication, and more! 26 - **Reliability**: Error reporting is made easy thanks to advanced error handling and panic recovery. The framework is deeply tested. 27 28 ## Table of contents 29 30 - [Learning Goyave](#learning-goyave) 31 - [Getting started](#getting-started) 32 - [Features tour](#features-tour) 33 - [Contributing](#contributing) 34 - [License](#license) 35 36 ## Learning Goyave 37 38 The Goyave framework has an extensive documentation covering in-depth subjects and teaching you how to run a project using Goyave from setup to deployment. 39 40 <a href="https://goyave.dev/guide/installation"><h3 align="center">Read the documentation</h3></a> 41 42 <a href="https://pkg.go.dev/github.com/System-Glitch/goyave/v3"><h3 align="center">pkg.go.dev</h3></a> 43 44 <a href="https://github.com/go-goyave/goyave-blog-example"><h3 align="center">Example project</h3></a> 45 46 ## Getting started 47 48 ### Requirements 49 50 - Go 1.13+ 51 - Go modules 52 53 ### Install using the template project 54 55 You can bootstrap your project using the [Goyave template project](https://github.com/System-Glitch/goyave-template). This project has a complete directory structure already set up for you. 56 57 #### Linux / MacOS 58 59 ``` 60 $ curl https://raw.githubusercontent.com/System-Glitch/goyave/master/install.sh | bash -s github.com/username/projectname 61 ``` 62 63 #### Windows (Powershell) 64 65 ``` 66 > & ([scriptblock]::Create((curl "https://raw.githubusercontent.com/System-Glitch/goyave/master/install.ps1").Content)) -moduleName github.com/username/projectname 67 ``` 68 69 --- 70 71 Run `go run .` in your project's directory to start the server, then try to request the `hello` route. 72 ``` 73 $ curl http://localhost:8080/hello 74 Hi! 75 ``` 76 77 There is also an `echo` route, with basic validation of the request body. 78 ``` 79 $ curl -H "Content-Type: application/json" -X POST -d '{"text":"abc 123"}' http://localhost:8080/echo 80 abc 123 81 ``` 82 83 ## Features tour 84 85 This section's goal is to give a **brief** look at the main features of the framework. It doesn't describe everything the framework has to offer, so don't consider this documentation. If you want a complete reference and documentation, head to [pkg.go.dev](https://pkg.go.dev/github.com/System-Glitch/goyave/v3) and the [official documentation](https://goyave.dev/guide/). 86 87 - [Hello world from scratch](#hello-world-from-scratch) 88 - [Configuration](#configuration) 89 - [Routing](#routing) 90 - [Controller](#controller) 91 - [Middleware](#middleware) 92 - [Validation](#validation) 93 - [Database](#database) 94 - [Localization](#localization) 95 - [Testing](#testing) 96 - [Status handlers](#status-handlers) 97 - [CORS](#cors) 98 - [Authentication](#authentication) 99 - [Rate limiting](#rate-limiting) 100 101 ### Hello world from scratch 102 103 The example below shows a basic `Hello world` application using Goyave. 104 105 ``` go 106 import "github.com/System-Glitch/goyave/v3" 107 108 func registerRoutes(router *goyave.Router) { 109 router.Get("/hello", func(response *goyave.Response, request *goyave.Request) { 110 response.String(http.StatusOK, "Hello world!") 111 }) 112 } 113 114 func main() { 115 if err := goyave.Start(registerRoutes); err != nil { 116 os.Exit(err.(*goyave.Error).ExitCode) 117 } 118 } 119 ``` 120 121 ### Configuration 122 123 To configure your application, use the `config.json` file at your project's root. If you are using the template project, copy `config.example.json` to `config.json`. The following code is an example of configuration for a local development environment: 124 125 ```json 126 { 127 "app": { 128 "name": "goyave_template", 129 "environment": "localhost", 130 "debug": true, 131 "defaultLanguage": "en-US" 132 }, 133 "server": { 134 "host": "127.0.0.1", 135 "maintenance": false, 136 "protocol": "http", 137 "domain": "", 138 "port": 8080, 139 "httpsPort": 8081, 140 "timeout": 10, 141 "maxUploadSize": 10 142 }, 143 "database": { 144 "connection": "mysql", 145 "host": "127.0.0.1", 146 "port": 3306, 147 "name": "goyave", 148 "username": "root", 149 "password": "root", 150 "options": "charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", 151 "maxOpenConnections": 20, 152 "maxIdleConnections": 20, 153 "maxLifetime": 300, 154 "autoMigrate": false 155 } 156 } 157 ``` 158 159 If this config file misses some config entries, the default values will be used. 160 161 All entries are **validated**. That means that the application will not start if you provided an invalid value in your config (for example if the specified port is not a number). That also means that a goroutine trying to change a config entry with the incorrect type will panic. 162 Entries can be registered with a default value, their type and authorized values from any package. 163 164 **Getting a value:** 165 ```go 166 config.GetString("app.name") // "goyave" 167 config.GetBool("app.debug") // true 168 config.GetInt("server.port") // 80 169 config.Has("app.name") // true 170 ``` 171 172 **Setting a value:** 173 ```go 174 config.Set("app.name", "my awesome app") 175 ``` 176 177 **Using environment variables:** 178 ```json 179 { 180 "database": { 181 "host": "${DB_HOST}" 182 } 183 } 184 ``` 185 186 **Learn more about configuration in the [documentation](https://goyave.dev/guide/configuration.html).** 187 188 ### Routing 189 190 Routing is an essential part of any Goyave application. Routes definition is the action of associating a URI, sometimes having parameters, with a handler which will process the request and respond to it. Separating and naming routes clearly is important to make your API or website clear and expressive. 191 192 Routes are defined in **routes registrer functions**. The main route registrer is passed to `goyave.Start()` and is executed automatically with a newly created root-level **router**. 193 194 ``` go 195 func Register(router *goyave.Router) { 196 // Register your routes here 197 198 // With closure, not recommended 199 router.Get("/hello", func(response *goyave.Response, r *goyave.Request) { 200 response.String(http.StatusOK, "Hi!") 201 }) 202 203 router.Get("/hello", myHandlerFunction) 204 router.Post("/user", user.Register).Validate(user.RegisterRequest) 205 router.Route("PUT|PATCH", "/user", user.Update).Validate(user.UpdateRequest) 206 router.Route("POST", "/product", product.Store).Validate(product.StoreRequest).Middleware(middleware.Trim) 207 } 208 ``` 209 210 URIs can have parameters, defined using the format `{name}` or `{name:pattern}`. If a regular expression pattern is not defined, the matched variable will be anything until the next slash. 211 212 **Example:** 213 ``` go 214 router.Get("/product/{key}", product.Show) 215 router.Get("/product/{id:[0-9]+}", product.ShowById) 216 router.Get("/category/{category}/{id:[0-9]+}", category.Show) 217 ``` 218 219 Route parameters can be retrieved as a `map[string]string` in handlers using the request's `Params` attribute. 220 ``` go 221 func myHandlerFunction(response *goyave.Response, request *goyave.Request) { 222 category := request.Params["category"] 223 id, _ := strconv.Atoi(request.Params["id"]) 224 //... 225 } 226 ``` 227 228 **Learn more about routing in the [documentation](https://goyave.dev/guide/basics/routing.html).** 229 230 ### Controller 231 232 Controllers are files containing a collection of Handlers related to a specific feature. Each feature should have its own package. For example, if you have a controller handling user registration, user profiles, etc, you should create a `http/controller/user` package. Creating a package for each feature has the advantage of cleaning up route definitions a lot and helps keeping a clean structure for your project. 233 234 A `Handler` is a `func(*goyave.Response, *goyave.Request)`. The first parameter lets you write a response, and the second contains all the information extracted from the raw incoming request. 235 236 Handlers receive a `goyave.Response` and a `goyave.Request` as parameters. 237 `goyave.Request` can give you a lot of information about the incoming request, such as its headers, cookies, or body. Learn more [here](https://goyave.dev/guide/basics/requests.html). 238 `goyave.Response` implements `http.ResponseWriter` and is used to write a response. If you didn't write anything before the request lifecycle ends, `204 No Content` is automatically written. Learn everything about reponses [here](https://goyave.dev/guide/basics/responses.html). 239 240 Let's take a very simple CRUD as an example for a controller definition: 241 **http/controller/product/product.go**: 242 ``` go 243 func Index(response *goyave.Response, request *goyave.Request) { 244 products := []model.Product{} 245 result := database.Conn().Find(&products) 246 if response.HandleDatabaseError(result) { 247 response.JSON(http.StatusOK, products) 248 } 249 } 250 251 func Show(response *goyave.Response, request *goyave.Request) { 252 product := model.Product{} 253 result := database.Conn().First(&product, request.Params["id"]) 254 if response.HandleDatabaseError(result) { 255 response.JSON(http.StatusOK, product) 256 } 257 } 258 259 func Store(response *goyave.Response, request *goyave.Request) { 260 product := model.Product{ 261 Name: request.String("name"), 262 Price: request.Numeric("price"), 263 } 264 if err := database.Conn().Create(&product).Error; err != nil { 265 response.Error(err) 266 } else { 267 response.JSON(http.StatusCreated, map[string]uint{"id": product.ID}) 268 } 269 } 270 271 func Update(response *goyave.Response, request *goyave.Request) { 272 product := model.Product{} 273 db := database.Conn() 274 result := db.Select("id").First(&product, request.Params["id"]) 275 if response.HandleDatabaseError(result) { 276 if err := db.Model(&product).Update("name", request.String("name")).Error; err != nil { 277 response.Error(err) 278 } 279 } 280 } 281 282 func Destroy(response *goyave.Response, request *goyave.Request) { 283 product := model.Product{} 284 db := database.Conn() 285 result := db.Select("id").First(&product, request.Params["id"]) 286 if response.HandleDatabaseError(result) { 287 if err := db.Delete(&product).Error; err != nil { 288 response.Error(err) 289 } 290 } 291 } 292 ``` 293 294 **Learn more about controllers in the [documentation](https://goyave.dev/guide/basics/controllers.html).** 295 296 ### Middleware 297 298 Middleware are handlers executed before the controller handler. They are a convenient way to filter, intercept or alter HTTP requests entering your application. For example, middleware can be used to authenticate users. If the user is not authenticated, a message is sent to the user even before the controller handler is reached. However, if the user is authenticated, the middleware will pass to the next handler. Middleware can also be used to sanitize user inputs, by trimming strings for example, to log all requests into a log file, to automatically add headers to all your responses, etc. 299 300 ``` go 301 func MyCustomMiddleware(next goyave.Handler) goyave.Handler { 302 return func(response *goyave.Response, request *goyave.Request) { 303 // Do something 304 next(response, request) // Pass to the next handler 305 } 306 } 307 ``` 308 309 To assign a middleware to a router, use the `router.Middleware()` function. Many middleware can be assigned at once. The assignment order is important as middleware will be **executed in order**. 310 311 ``` go 312 router.Middleware(middleware.MyCustomMiddleware) 313 ``` 314 315 **Learn more about middleware in the [documentation](https://goyave.dev/guide/basics/middleware.html).** 316 317 318 ### Validation 319 320 Goyave provides a powerful, yet easy way to validate all incoming data, no matter its type or its format, thanks to a large number of validation rules. 321 322 Incoming requests are validated using **rules set**, which associate rules with each expected field in the request. 323 324 Validation rules can **alter the raw data**. That means that when you validate a field to be number, if the validation passes, you are ensured that the data you'll be using in your controller handler is a `float64`. Or if you're validating an IP, you get a `net.IP` object. 325 326 Validation is automatic. You just have to define a rules set and assign it to a route. When the validation doesn't pass, the request is stopped and the validation errors messages are sent as a response. 327 328 Rule sets are defined in the same package as the controller, typically in a separate file named `request.go`. Rule sets are named after the name of the controller handler they will be used with, and end with `Request`. For example, a rule set for the `Store` handler will be named `StoreRequest`. If a rule set can be used for multiple handlers, consider using a name suited for all of them. The rules for a store operation are often the same for update operations, so instead of duplicating the set, create one unique set called `UpsertRequest`. 329 330 **Example:** (`http/controller/product/request.go`) 331 ``` go 332 var ( 333 StoreRequest validation.RuleSet = validation.RuleSet{ 334 "name": {"required", "string", "between:3,50"}, 335 "price": {"required", "numeric", "min:0.01"}, 336 "image": {"nullable", "file", "image", "max:2048", "count:1"}, 337 } 338 339 // ... 340 ) 341 ``` 342 343 Once your rules sets are defined, you need to assign them to your routes using the `Validate()` method. 344 345 ``` go 346 router.Post("/product", product.Store).Validate(product.StoreRequest) 347 ``` 348 349 350 **Learn more about validation in the [documentation](https://goyave.dev/guide/basics/validation.html).** 351 352 ### Database 353 354 Most web applications use a database. In this section, we are going to see how Goyave applications can query a database, using the awesome [Gorm ORM](https://gorm.io/). 355 356 Database connections are managed by the framework and are long-lived. When the server shuts down, the database connections are closed automatically. So you don't have to worry about creating, closing or refreshing database connections in your application. 357 358 Very few code is required to get started with databases. There are some [configuration](https://goyave.dev/guide/configuration.html#configuration-reference) options that you need to change though: 359 360 - `database.connection` 361 - `database.host` 362 - `database.port` 363 - `database.name` 364 - `database.username` 365 - `database.password` 366 - `database.options` 367 - `database.maxOpenConnection` 368 - `database.maxIdleConnection` 369 - `database.maxLifetime` 370 371 ``` go 372 user := model.User{} 373 db := database.Conn() 374 db.First(&user) 375 376 fmt.Println(user) 377 ``` 378 379 Models are usually just normal Golang structs, basic Go types, or pointers of them. `sql.Scanner` and `driver.Valuer` interfaces are also supported. 380 381 ```go 382 func init() { 383 database.RegisterModel(&User{}) 384 } 385 386 type User struct { 387 gorm.Model 388 Name string 389 Age sql.NullInt64 390 Birthday *time.Time 391 Email string `gorm:"type:varchar(100);uniqueIndex"` 392 Role string `gorm:"size:255"` // set field size to 255 393 MemberNumber *string `gorm:"unique;not null"` // set member number to unique and not null 394 Num int `gorm:"autoIncrement"` // set num to auto incrementable 395 Address string `gorm:"index:addr"` // create index with name `addr` for address 396 IgnoreMe int `gorm:"-"` // ignore this field 397 } 398 ``` 399 400 **Learn more about using databases in the [documentation](https://goyave.dev/guide/basics/database.html).** 401 402 ### Localization 403 404 The Goyave framework provides a convenient way to support multiple languages within your application. Out of the box, Goyave only provides the `en-US` language. 405 406 Language files are stored in the `resources/lang` directory. 407 408 ``` 409 . 410 └── resources 411 └── lang 412 └── en-US (language name) 413 ├── fields.json (optional) 414 ├── locale.json (optional) 415 └── rules.json (optional) 416 ``` 417 418 The `fields.json` file contains the field names translations and their rule-specific messages. Translating field names helps making more expressive messages instead of showing the technical field name to the user. Rule-specific messages let you override a validation rule message for a specific field. 419 420 **Example:** 421 ``` json 422 { 423 "email": { 424 "name": "email address", 425 "rules": { 426 "required": "You must provide an :field." 427 } 428 } 429 } 430 ``` 431 432 The `locale.json` file contains all language lines that are not related to validation. This is the place where you should write the language lines for your user interface or for the messages returned by your controllers. 433 434 **Example:** 435 ``` json 436 { 437 "product.created": "The product have been created with success.", 438 "product.deleted": "The product have been deleted with success." 439 } 440 ``` 441 442 The `rules.json` file contains the validation rules messages. These messages can have **[placeholders](https://goyave.dev/guide/basics/validation.html#placeholders)**, which will be automatically replaced by the validator with dynamic values. If you write custom validation rules, their messages shall be written in this file. 443 444 **Example:** 445 446 ``` json 447 { 448 "integer": "The :field must be an integer.", 449 "starts_with": "The :field must start with one of the following values: :values.", 450 "same": "The :field and the :other must match." 451 } 452 ``` 453 454 When an incoming request enters your application, the core language middleware checks if the `Accept-Language` header is set, and set the `goyave.Request`'s `Lang` attribute accordingly. Localization is handled automatically by the validator. 455 456 ``` go 457 func ControllerHandler(response *goyave.Response, request *goyave.Request) { 458 response.String(http.StatusOK, lang.Get(request.Lang, "my-custom-message")) 459 } 460 ``` 461 462 **Learn more about localization in the [documentation](https://goyave.dev/guide/advanced/localization.html).** 463 464 ### Testing 465 466 Goyave provides an API to ease the unit and functional testing of your application. This API is an extension of [testify](https://github.com/stretchr/testify). `goyave.TestSuite` inherits from testify's `suite.Suite`, and sets up the environment for you. That means: 467 468 - `GOYAVE_ENV` environment variable is set to `test` and restored to its original value when the suite is done. 469 - All tests are run using your project's root as working directory. This directory is determined by the presence of a `go.mod` file. 470 - Config and language files are loaded before the tests start. As the environment is set to `test`, you **need** a `config.test.json` in the root directory of your project. 471 472 This setup is done by the function `goyave.RunTest`, so you shouldn't run your test suites using testify's `suite.Run()` function. 473 474 The following example is a **functional** test and would be located in the `test` package. 475 476 ``` go 477 import ( 478 "github.com/username/projectname/http/route" 479 "github.com/System-Glitch/goyave/v3" 480 ) 481 482 type CustomTestSuite struct { 483 goyave.TestSuite 484 } 485 486 func (suite *CustomTestSuite) TestHello() { 487 suite.RunServer(route.Register, func() { 488 resp, err := suite.Get("/hello", nil) 489 suite.Nil(err) 490 suite.NotNil(resp) 491 if resp != nil { 492 defer resp.Body.Close() 493 suite.Equal(200, resp.StatusCode) 494 suite.Equal("Hi!", string(suite.GetBody(resp))) 495 } 496 }) 497 } 498 499 func TestCustomSuite(t *testing.T) { 500 goyave.RunTest(t, new(CustomTestSuite)) 501 } 502 ``` 503 504 When writing functional tests, you can retrieve the response body easily using `suite.GetBody(response)`. 505 506 ``` go 507 resp, err := suite.Get("/get", nil) 508 suite.Nil(err) 509 if err == nil { 510 defer resp.Body.Close() 511 suite.Equal("response content", string(suite.GetBody(resp))) 512 } 513 ``` 514 515 **URL-encoded requests:** 516 517 ``` go 518 headers := map[string]string{"Content-Type": "application/x-www-form-urlencoded; param=value"} 519 resp, err := suite.Post("/product", headers, strings.NewReader("field=value")) 520 suite.Nil(err) 521 if err == nil { 522 defer resp.Body.Close() 523 suite.Equal("response content", string(suite.GetBody(resp))) 524 } 525 ``` 526 527 **JSON requests:** 528 529 ``` go 530 headers := map[string]string{"Content-Type": "application/json"} 531 body, _ := json.Marshal(map[string]interface{}{"name": "Pizza", "price": 12.5}) 532 resp, err := suite.Post("/product", headers, bytes.NewReader(body)) 533 suite.Nil(err) 534 if err == nil { 535 defer resp.Body.Close() 536 suite.Equal("response content", string(suite.GetBody(resp))) 537 } 538 ``` 539 540 **Testing JSON response:** 541 542 ``` go 543 suite.RunServer(route.Register, func() { 544 resp, err := suite.Get("/product", nil) 545 suite.Nil(err) 546 if err == nil { 547 defer resp.Body.Close() 548 json := map[string]interface{}{} 549 err := suite.GetJSONBody(resp, &json) 550 suite.Nil(err) 551 if err == nil { // You should always check parsing error before continuing. 552 suite.Equal("value", json["field"]) 553 suite.Equal(float64(42), json["number"]) 554 } 555 } 556 }) 557 ``` 558 559 The testing API has many more features such as record generators, factories, database helpers, a middleware tester, support for multipart and file uploads... 560 561 **Learn more about testing in the [documentation](https://goyave.dev/guide/advanced/testing.html).** 562 563 ### Status handlers 564 565 Status handlers are regular handlers executed during the finalization step of the request's lifecycle if the response body is empty but a status code has been set. Status handler are mainly used to implement a custom behavior for user or server errors (400 and 500 status codes). 566 567 The following file `http/controller/status/status.go` is an example of custom 404 error handling: 568 ``` go 569 package status 570 571 import "github.com/System-Glitch/goyave/v3" 572 573 func NotFound(response *goyave.Response, request *goyave.Request) { 574 if err := response.RenderHTML(response.GetStatus(), "errors/404.html", nil); err != nil { 575 response.Error(err) 576 } 577 } 578 ``` 579 580 Status handlers are registered in the **router**. 581 582 ``` go 583 // Use "status.NotFound" for empty responses having status 404 or 405. 584 router.StatusHandler(status.NotFound, 404) 585 ``` 586 587 **Learn more about status handlers in the [documentation](https://goyave.dev/guide/advanced/status-handlers.html).** 588 589 590 ### CORS 591 592 Goyave provides a built-in CORS module. CORS options are set on **routers**. If the passed options are not `nil`, the CORS core middleware is automatically added. 593 594 ``` go 595 router.CORS(cors.Default()) 596 ``` 597 598 CORS options should be defined **before middleware and route definition**. All of this router's sub-routers **inherit** CORS options by default. If you want to remove the options from a sub-router, or use different ones, simply create another `cors.Options` object and assign it. 599 600 `cors.Default()` can be used as a starting point for custom configuration. 601 602 ``` go 603 options := cors.Default() 604 options.AllowedOrigins = []string{"https://google.com", "https://images.google.com"} 605 router.CORS(options) 606 ``` 607 608 **Learn more about CORS in the [documentation](https://goyave.dev/guide/advanced/cors.html).** 609 610 ### Authentication 611 612 Goyave provides a convenient and expandable way of handling authentication in your application. Authentication can be enabled when registering your routes: 613 614 ``` go 615 import "github.com/System-Glitch/goyave/v3/auth" 616 617 //... 618 619 authenticator := auth.Middleware(&model.User{}, &auth.BasicAuthenticator{}) 620 router.Middleware(authenticator) 621 ``` 622 623 Authentication is handled by a simple middleware calling an **Authenticator**. This middleware also needs a model, which will be used to fetch user information on a successful login. 624 625 Authenticators use their model's struct fields tags to know which field to use for username and password. To make your model compatible with authentication, you must add the `auth:"username"` and `auth:"password"` tags: 626 627 ``` go 628 type User struct { 629 gorm.Model 630 Email string `gorm:"type:char(100);uniqueIndex" auth:"username"` 631 Name string `gorm:"type:char(100)"` 632 Password string `gorm:"type:char(60)" auth:"password"` 633 } 634 ``` 635 636 When a user is successfully authenticated on a protected route, its information is available in the controller handler, through the request `User` field. 637 638 ``` go 639 func Hello(response *goyave.Response, request *goyave.Request) { 640 user := request.User.(*model.User) 641 response.String(http.StatusOK, "Hello " + user.Name) 642 } 643 ``` 644 645 **Learn more about authentication in the [documentation](https://goyave.dev/guide/advanced/authentication.html).** 646 647 ### Rate limiting 648 649 Rate limiting is a crucial part of public API development. If you want to protect your data from being crawled, protect yourself from DDOS attacks, or provide different tiers of access to your API, you can do it using Goyave's built-in rate limiting middleware. 650 651 This middleware uses either a client's IP or an authenticated client's ID (or any other way of identifying a client you may need) and maps a quota, a quota duration and a request count to it. If a client exceeds the request quota in the given quota duration, this middleware will block and return `HTTP 429 Too Many Requests`. 652 653 The middleware will always add the following headers to the response: 654 - `RateLimit-Limit`: containing the requests quota in the time window 655 - `RateLimit-Remaining`: containing the remaining requests quota in the current window 656 - `RateLimit-Reset`: containing the time remaining in the current window, specified in seconds 657 658 ```go 659 import "github.com/System-Glitch/goyave/v3/middleware/ratelimiter" 660 661 ratelimiterMiddleware := ratelimiter.New(func(request *goyave.Request) ratelimiter.Config { 662 return ratelimiter.Config { 663 RequestQuota: 100, 664 QuotaDuration: time.Minute, 665 // 100 requests per minute allowed 666 // Client IP will be used as identifier 667 } 668 }) 669 670 router.Middleware(ratelimiterMiddleware) 671 ``` 672 673 **Learn more about rate limiting in the [documentation](https://goyave.dev/guide/advanced/rate-limiting.html).** 674 675 ## Contributing 676 677 Thank you for considering contributing to the Goyave framework! You can find the contribution guide in the [documentation](https://goyave.dev/guide/contribution-guide.html). 678 679 I have many ideas for the future of Goyave. I would be infinitely grateful to whoever want to support me and let me continue working on Goyave and making it better and better. 680 681 You can support me on Github Sponsor or Patreon. 682 683 <a href="https://github.com/sponsors/System-Glitch">❤ Sponsor me!</a> 684 685 <a href="https://www.patreon.com/bePatron?u=25997573"> 686 <img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160"> 687 </a> 688 689 I'm very grateful to my patrons and donators: 690 691 - Ben Hyrman 692 - Massimiliano Bertinetti 693 694 ### Contributors 695 696 A big "Thank you" to the Goyave contributors: 697 698 - [Kuinox](https://github.com/Kuinox) (Powershell install script) 699 - [Alexandre GV.](https://github.com/alexandregv) (Install script MacOS compatibility) 700 - [jRimbault](https://github.com/jRimbault) (CI and code analysis) 701 - [Guillermo Galvan](https://github.com/gmgalvan) (Request extra data) 702 - [Albert Shirima](https://github.com/agbaraka) (Rate limiting) 703 704 ## License 705 706 The Goyave framework is MIT Licensed. Copyright © 2019 Jérémy LAMBERT (SystemGlitch)