github.com/goplus/yap@v0.8.1/doc/manual.md (about)

     1  yap - Yet Another Go/Go+ HTTP Web Framework
     2  ======
     3  
     4  This repo contains three [Go+ classfiles](https://github.com/goplus/gop/blob/main/doc/classfile.md): `yap` (a HTTP Web Framework), `yaptest` (a HTTP Test Framework) and `ydb` (a Go+ Database Framework).
     5  
     6  The classfile `yap` has the file suffix `.yap`. The classfile `yaptest` has the file suffix `_ytest.gox`. And the classfile `ydb` has the file suffix `_ydb.gox`.
     7  
     8  Before using `yap`, `yaptest` or `ydb`, you need to add `github.com/goplus/yap` to `go.mod`:
     9  
    10  ```sh
    11  gop get github.com/goplus/yap@latest
    12  ```
    13  
    14  
    15  ### Router and Parameters
    16  
    17  demo in Go ([hello.go](../demo/hello/hello.go)):
    18  
    19  ```go
    20  import "github.com/goplus/yap"
    21  
    22  func main() {
    23  	y := yap.New()
    24  	y.GET("/", func(ctx *yap.Context) {
    25  		ctx.TEXT(200, "text/html", `<html><body>Hello, YAP!</body></html>`)
    26  	})
    27  	y.GET("/p/:id", func(ctx *yap.Context) {
    28  		ctx.JSON(200, yap.H{
    29  			"id": ctx.Param("id"),
    30  		})
    31  	})
    32  	y.Run("localhost:8080")
    33  }
    34  ```
    35  
    36  demo in Go+ classfile v1 ([main.yap](../demo/classfile_hello/main.yap)):
    37  
    38  ```go
    39  get "/", ctx => {
    40  	ctx.html `<html><body>Hello, YAP!</body></html>`
    41  }
    42  get "/p/:id", ctx => {
    43  	ctx.json {
    44  		"id": ctx.param("id"),
    45  	}
    46  }
    47  
    48  run "localhost:8080"
    49  ```
    50  
    51  demo in Go+ classfile v2 ([get.yap](../demo/classfile2_hello/get.yap), [get_p_#id.yap](../demo/classfile2_hello/get_p_%23id.yap)):
    52  
    53  * [get.yap](../demo/classfile2_hello/get.yap):
    54  
    55  ```go
    56  html `<html><body>Hello, YAP!</body></html>`
    57  ```
    58  
    59  * [get_p_#id.yap](../demo/classfile2_hello/get_p_%23id.yap):
    60  
    61  ```coffee
    62  json {
    63  	"id": ${id},
    64  }
    65  ```
    66  
    67  ### Static files
    68  
    69  Static files server demo in Go:
    70  
    71  ```go
    72  y := yap.New(os.DirFS("."))
    73  
    74  y.Static("/foo", y.FS("public"))
    75  y.Static("/") // means: y.Static("/", y.FS("static"))
    76  
    77  y.Run(":8080")
    78  ```
    79  
    80  Static files server demo in Go+ classfile ([main.yap](../demo/classfile2_static/main.yap)):
    81  
    82  ```go
    83  static "/foo", FS("public")
    84  static "/"
    85  
    86  run ":8080"
    87  ```
    88  
    89  Static files server also can use a `http.FileSystem` instead of `fs.FS` object (See [yapserve](https://github.com/xushiwei/yapserve) for details):
    90  
    91  ```go
    92  import "github.com/qiniu/x/http/fs"
    93  
    94  static "/", fs.http("https://goplus.org"), false // false means not allow to redirect
    95  run ":8080"
    96  ```
    97  
    98  
    99  ### YAP Template
   100  
   101  demo in Go ([blog.go](../demo/blog/blog.go), [article_yap.html](../demo/blog/yap/article_yap.html)):
   102  
   103  ```go
   104  import (
   105  	"os"
   106  
   107  	"github.com/goplus/yap"
   108  )
   109  
   110  y := yap.New(os.DirFS("."))
   111  
   112  y.GET("/p/:id", func(ctx *yap.Context) {
   113  	ctx.YAP(200, "article", yap.H{
   114  		"id": ctx.Param("id"),
   115  	})
   116  })
   117  
   118  y.Run(":8888")
   119  ```
   120  
   121  demo in Go+ classfile v1 ([main.yap](../demo/classfile_blog/blog_yap.gox), [article_yap.html](../demo/classfile_blog/yap/article_yap.html)):
   122  
   123  ```go
   124  get "/p/:id", ctx => {
   125  	ctx.yap "article", {
   126  		"id": ctx.param("id"),
   127  	}
   128  }
   129  
   130  run ":8888"
   131  ```
   132  
   133  demo in Go+ classfile v2 ([get_p_#id.yap](../demo/classfile2_blog/get_p_%23id.yap), [article_yap.html](../demo/classfile2_blog/yap/article_yap.html)):
   134  
   135  ```go
   136  yap "article", {
   137  	"id": ${id},
   138  }
   139  ```
   140  
   141  
   142  ### YAP Test Framework
   143  
   144  This classfile has the file suffix `_ytest.gox`.
   145  
   146  Suppose we have a web server ([foo/get_p_#id.yap](../ytest/demo/foo/get_p_%23id.yap)):
   147  
   148  ```go
   149  json {
   150  	"id": ${id},
   151  }
   152  ```
   153  
   154  Then we create a yaptest file ([foo/foo_ytest.gox](../ytest/demo/foo/foo_ytest.gox)):
   155  
   156  ```go
   157  mock "foo.com", new(AppV2)  // name of any YAP v2 web server is `AppV2`
   158  
   159  id := "123"
   160  get "http://foo.com/p/${id}"
   161  ret 200
   162  json {
   163  	"id": id,
   164  }
   165  ```
   166  
   167  The directive `mock` creates the web server by [mockhttp](https://pkg.go.dev/github.com/qiniu/x/mockhttp). Then we write test code directly.
   168  
   169  You can change the directive `mock` to `testServer` (see [foo/bar_ytest.gox](../ytest/demo/foo/bar_ytest.gox)), and keep everything else unchanged:
   170  
   171  ```go
   172  testServer "foo.com", new(AppV2)
   173  
   174  id := "123"
   175  get "http://foo.com/p/${id}"
   176  ret 200
   177  json {
   178  	"id": id,
   179  }
   180  ```
   181  
   182  The directive `testServer` creates the web server by [net/http/httptest](https://pkg.go.dev/net/http/httptest#NewServer) and obtained a random port as the service address. Then it calls the directive [host](https://pkg.go.dev/github.com/goplus/yap/ytest#App.Host) to map the random service address to `foo.com`. This makes all other code no need to changed.
   183  
   184  For more details, see [yaptest - Go+ HTTP Test Framework](../ytest).