trpc.group/trpc-go/trpc-go@v1.0.3/internal/httprule/README.md (about)

     1  # About HttpRule
     2  
     3  To support RESTful API, the difficulty is how to map fields in Proto Message to HTTP request/response. This mapping does not exist natively.
     4  
     5  Therefore, we need to define a specification to specify the mapping details. This specification is called ***HttpRule***:
     6  
     7  Inside pb file, we use **trpc.api.http** option to specify HttpRule. During the mapping, the leaf fields in the message is handled by the following **three** scenarios:
     8  
     9  1. Field is referenced by url path in HttpRule: If url path in HttpRule uses one or more fields in rpc request message, these message will be passed through url path. But these fields must be native data types. Array type and message type are not supported.
    10  
    11  2. Field is referenced by the body of HttpRule: If the body of HttpRule specifies the mapped field, then these fields in rpc request message are passed through HTTP request body.
    12  
    13  3. Other fields: Other fields will be generated as URL request parameters automatically. If the field is repeatable, the same URL request parameter is permitted to query multiple times.
    14  
    15  **Other things to notice**:
    16  
    17  1. If "*" is used in HttpRule's body without specifying exact fields, then every request message field that has not been bind to URL path can be passed through the HTTP request body.
    18  
    19  2. If the body of HttpRule is empty, then every request message field that has not been bind to URL path will become URL request parameter automatically.
    20  
    21  ## About httprule package
    22  
    23  Apparently, the difficulty of HttpRule is the matching of URL path.
    24  
    25  First of all, the URL path of RESTful request should be unified into a template:
    26  
    27  ```Go
    28   Template = "/" Segments [ Verb ] ;
    29   Segments = Segment { "/" Segment } ;
    30   Segment  = "*" | "**" | LITERAL | Variable ;
    31   Variable = "{" FieldPath [ "=" Segments ] "}" ;
    32   FieldPath = IDENT { "." IDENT } ;
    33   Verb     = ":" LITERAL ;
    34  ```
    35  
    36  Every URL path in the HttpRule must follow this template.
    37  
    38  Package ```httprule``` provides ```Parse``` method to parse URL path in HttpRule into the type ```PathTemplate```.
    39  
    40  ```PathTemplate``` provides ```Match``` method to match the variable value from the authentic HTTP request URL path.
    41  
    42  ***Example 1:***
    43  
    44     If the HttpRule URL path specified in pb Option **trpc.api.http** is ```/foobar/{foo}/bar/{baz}```, where ```foo``` and ```baz``` are variables, then it is parsed into the template:
    45  
    46     ```Go
    47        tpl, _ := httprule.Parse("/foobar/{foo}/bar/{baz}")
    48     ```
    49  
    50     the template is used to match the URL path from an HTTP request:
    51  
    52     ```Go
    53        captured, _ := tpl.Match("/foobar/x/bar/y")
    54     ```
    55  
    56     captured is:
    57  
    58     ```Go
    59        reflect.DeepEqual(captured, map[string]string{"foo":"x", "baz":"y"})
    60     ```
    61  
    62  ***Example 2:***
    63  
    64     If the HttpRule URL path specified in pb Option **trpc.api.http** is ```/foobar/{foo=x/*}```, where ```foo``` is a variable, then it is parsed into the template:
    65  
    66     ```Go
    67        tpl, _ := httprule.Parse("/foobar/{foo=x/*}")
    68     ```
    69  
    70     the template is used to match the URL path from an HTTP request:
    71  
    72     ```Go
    73        captured, _ := tpl.Match("/foobar/x/y")
    74     ```
    75  
    76     captured is:
    77  
    78     ```Go
    79        reflect.DeepEqual(captured, map[string]string{"foo":"x/y"})
    80     ```