github.com/thetreep/go-swagger@v0.0.0-20240223100711-35af64f14f01/docs/use/server.md (about)

     1  # Use the generated server
     2  
     3  The generated server serves the API but the default implementation returns 501 Not implemented for everything. Let's
     4  look into using the generated code.
     5  
     6  Go swagger primarily deals with HTTP and originally only supports the stdlib `net/http` interface. A typical HTTP
     7  request expects a response.  This is reflected in go-swagger where a handler is typically defined as a function of
     8  input parameters to a responder.
     9  
    10  ```go
    11  type ListTravelsHandler interface {
    12  	Handle(ListTravelsParams) middleware.Responder
    13  }
    14  ```
    15  
    16  The signature of this handler is one of 2 possible variations. When a handler doesn't use authentication then a handler
    17  interface consists out of input parameters and a responder.
    18  
    19  ```go
    20  type AddOneAuthenticatedHandler interface {
    21  	Handle(AddOneParams, interface{}) middleware.Responder
    22  }
    23  ```
    24  
    25  When a handler does use authentication then the second argument to the handler function represents the security
    26  principal for your application. You can specify the type name for this principal at generation time by specifying the
    27  -P or --principal flag.
    28  
    29  ```
    30  swagger generate server -P models.User
    31  swagger generate client -P models.User
    32  ```
    33  
    34  The type name can be specified by package path.
    35  
    36  ```
    37  swagger generate server -P github.com/foobar/models.User
    38  ```
    39  
    40  See the full list of available options [for server](../generate/server.md) and [for client](../generate/client.md).
    41  
    42  When you would execute the generate step with that parameter for the security principal then the
    43  AddOneAuthenticatedHandler would look a bit like this:
    44  
    45  ```go
    46  type AddOneAuthenticatedHandler interface {
    47  	Handle(AddOneParams, *models.User) middleware.Responder
    48  }
    49  ```
    50  
    51  ## Implement handlers
    52  
    53  A handler is an interface/contract that defines a statically typed representation of the input and output parameters of
    54  an operation on your API.
    55  The tool generates handlers that are stubbed with a NotImplemented response when you first generate the server.
    56  
    57  ### The `not implemented` handler
    58  
    59  The not implemented handler is actually a not implemented responder, it returns a responder that will always respond
    60  with status code 501 and a message that lets people know it's not the fault of the client that things don't work.
    61  
    62  ```go
    63  middleware.NotImplemented("operation todos.AddOne has not yet been implemented")
    64  ```
    65  
    66  ### Your own code
    67  
    68  Each HTTP request expects a response of some sort, this response might have no data but it's a response none the less.
    69  
    70  Every incoming request is described as a bunch of input parameters which have been validated prior to calling the
    71  handler. So whenever your code is executed, the input parameters are guaranteed to be valid according to what the
    72  swagger specification prescribes.
    73  
    74  All the input parameters have been validated, and the request has been authenticated should it have triggered
    75  authentication.
    76  
    77  You probably want to return something a bit more useful to the users of your API than a not implemented response.
    78  
    79  A possible implementation of the `ListTravelsHandler` interface might look like this:
    80  
    81  ```go
    82  type PublicListTravelsOK struct {
    83    Body []models.Travel
    84  }
    85  func (m *PublicListTravelsOK) WriteResponse(rw http.ResponseWriter, producer httpkit.Producer){
    86    // generated code here
    87  }
    88  
    89  type PublicListTravelsError struct {
    90    Body models.Error
    91  }
    92  func (m *PublicListTravelsOK) WriteResponse(rw http.ResponseWriter, producer httpkit.Producer){
    93    // generated code here
    94  }
    95  
    96  type PublicListTravelsHandler struct {
    97    db interface {
    98      FetchTravels(*PublicListTravelsParams) ([]models.Travel, error)
    99    }
   100  }
   101  
   102  func (m *PublicListTravelsHandler) Handle(params ListTravelsParams) middleware.Responder {
   103    travels, err := m.db.FetchTravels(&params)
   104    if err != nil {
   105      return &PublicListTravelsError{Body: models.Error{Message: err.Error()}}
   106    }
   107    return &PublicListTravelsOK{Body: travels}
   108  }
   109  ```
   110  
   111  In the example above we have a handler implementation with a hypothetical database fetch interface. When the handle
   112  method is executed there are 2 possible responses for the provided parameters. There can either be an error in which
   113  case the PublicListTravelsError will be returned, otherwise the PublicListTravelsOK will be returned.
   114  
   115  The code generator has written the remaining code to render that response with the headers etc.
   116