Skip to content

Commit

Permalink
Adds Cookie and Header methods to context
Browse files Browse the repository at this point in the history
  • Loading branch information
EwenQuim committed Mar 20, 2024
1 parent 447efa1 commit ef7cea6
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 8 deletions.
25 changes: 25 additions & 0 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ type ctx[B any] interface {
// By default, [templateToExecute] is added to the list of templates to override.
Render(templateToExecute string, data any, templateGlobsToOverride ...string) (HTML, error)

Cookie(name string) (*http.Cookie, error) // Get request cookie
SetCookie(cookie http.Cookie) // Sets response cookie
Header(key string) string // Get request header
SetHeader(key, value string) // Sets response header

Context() context.Context

Request() *http.Request // Request returns the underlying http request.
Expand Down Expand Up @@ -162,6 +167,26 @@ func (c ContextNoBody) Context() context.Context {
return c.Req.Context()
}

// Get request header
func (c ContextNoBody) Header(key string) string {
return c.Request().Header.Get(key)
}

// Sets response header
func (c ContextNoBody) SetHeader(key, value string) {
c.Response().Header().Set(key, value)
}

// Get request cookie
func (c ContextNoBody) Cookie(name string) (*http.Cookie, error) {
return c.Request().Cookie(name)
}

// Sets response cookie
func (c ContextNoBody) SetCookie(cookie http.Cookie) {
http.SetCookie(c.Response(), &cookie)
}

// Render renders the given templates with the given data.
// It returns just an empty string, because the response is written directly to the http.ResponseWriter.
//
Expand Down
45 changes: 42 additions & 3 deletions documentation/docs/guides/controllers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import FlowChart from '@site/src/components/FlowChart';

Controllers are the main way to interact with the application. They are responsible for handling the requests and responses.



<FlowChart selected="Controller" />

## Controller types
Expand Down Expand Up @@ -48,7 +46,7 @@ type MyResponse struct {
Message string `json:"message"`
}

func MyController(ctx *fuego.ContextWithBody[MyInput]) (MyResponse, error) {
func MyController(c *fuego.ContextWithBody[MyInput]) (MyResponse, error) {
body, err := c.Body()
if err != nil {
return MyResponse{}, err
Expand All @@ -60,3 +58,44 @@ func MyController(ctx *fuego.ContextWithBody[MyInput]) (MyResponse, error) {
}
```

## Headers

You can always go further in the request and response by using the underlying net/http request and response, by using `c.Request` and `c.Response`.

### Get request header

```go
func MyController(c *fuego.ContextNoBody) (MyResponse, error) {
value := c.Header("X-My-Header")
return MyResponse{}, nil
}
```

### Set response header

```go
func MyController(c *fuego.ContextNoBody) (MyResponse, error) {
c.SetHeader("X-My-Header", "value")
return MyResponse{}, nil
}
```

## Cookies

### Get request cookie

```go
func MyController(c *fuego.ContextNoBody) (MyResponse, error) {
value := c.Cookie("my-cookie")
return MyResponse{}, nil
}
```

### Set response cookie

```go
func MyController(c *fuego.ContextNoBody) (MyResponse, error) {
c.SetCookie("my-cookie", "value")
return MyResponse{}, nil
}
```
21 changes: 17 additions & 4 deletions documentation/docs/guides/openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,10 @@ func main() {
s := fuego.NewServer(fuego.WithOpenAPIConfig(fuego.OpenAPIConfig{
DisableSwagger : false, // If true, the server will not serve the swagger ui nor the openapi json spec
DisableLocalSave : false, // If true, the server will not save the openapi json spec locally
SwaggerUrl : "/xxx", // URL to serve the swagger ui
JsonUrl : "/xxx/swagger.json", // URL to serve the openapi json spec
JsonFilePath : "./foo/bar.json", // Local path to save the openapi json spec
SwaggerUrl : "/swagger", // URL to serve the swagger ui
JsonUrl : "/swagger/openapi.json", // URL to serve the openapi json spec
JsonFilePath : "doc/openapi.json", // Local path to save the openapi json spec
UIHandler : DefaultOpenAPIHandler, // Custom UI handler
}))

fuego.Get(s, "/", func(c fuego.ContextNoBody) (string, error) {
Expand Down Expand Up @@ -114,6 +115,18 @@ func openApiHandler(specURL string) http.Handler {
httpSwagger.URL(specURL), // The url pointing to API definition
)
}

func main() {
s := fuego.NewServer(
fuego.WithOpenAPIConfig(fuego.OpenAPIConfig{
UIHandler: openApiHandler("/swagger.json"),
}),
)

fuego.Get(s, "/", helloWorld)

s.Run()
}
```

The default spec url reference Element Stoplight swagger ui.
Expand Down Expand Up @@ -157,4 +170,4 @@ func main() {

s.Run()
}
```
```
2 changes: 1 addition & 1 deletion middleware/cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type testStruct struct {

const waitTime = 10 * time.Millisecond

func baseController(ctx *fuego.ContextNoBody) (testStruct, error) {
func baseController(c *fuego.ContextNoBody) (testStruct, error) {
time.Sleep(waitTime)
return testStruct{Name: "test", Age: 10}, nil
}
Expand Down
42 changes: 42 additions & 0 deletions mux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fuego

import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
Expand Down Expand Up @@ -494,3 +495,44 @@ func TestGroup(t *testing.T) {
require.Equal(t, "/slash/", g.basePath)
})
}

func ExampleContextNoBody_SetCookie() {
s := NewServer()
Get(s, "/test", func(c *ContextNoBody) (string, error) {
c.SetCookie(http.Cookie{
Name: "name",
Value: "value",
})
return "test", nil
})

w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/test", nil)

s.Mux.ServeHTTP(w, r)

fmt.Println(w.Result().Cookies()[0].Name)
fmt.Println(w.Result().Cookies()[0].Value)

// Output:
// name
// value
}

func ExampleContextNoBody_SetHeader() {
s := NewServer()
Get(s, "/test", func(c *ContextNoBody) (string, error) {
c.SetHeader("X-Test", "test")
return "test", nil
})

w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/test", nil)

s.Mux.ServeHTTP(w, r)

fmt.Println(w.Header().Get("X-Test"))

// Output:
// test
}

0 comments on commit ef7cea6

Please sign in to comment.