operation.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. // Copyright 2015 go-swagger maintainers
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package spec
  15. import (
  16. "encoding/json"
  17. "github.com/go-openapi/jsonpointer"
  18. "github.com/go-openapi/swag"
  19. )
  20. type OperationProps struct {
  21. Description string `json:"description,omitempty"`
  22. Consumes []string `json:"consumes,omitempty"`
  23. Produces []string `json:"produces,omitempty"`
  24. Schemes []string `json:"schemes,omitempty"` // the scheme, when present must be from [http, https, ws, wss]
  25. Tags []string `json:"tags,omitempty"`
  26. Summary string `json:"summary,omitempty"`
  27. ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"`
  28. ID string `json:"operationId,omitempty"`
  29. Deprecated bool `json:"deprecated,omitempty"`
  30. Security []map[string][]string `json:"security,omitempty"`
  31. Parameters []Parameter `json:"parameters,omitempty"`
  32. Responses *Responses `json:"responses,omitempty"`
  33. }
  34. // Operation describes a single API operation on a path.
  35. //
  36. // For more information: http://goo.gl/8us55a#operationObject
  37. type Operation struct {
  38. VendorExtensible
  39. OperationProps
  40. }
  41. // SuccessResponse gets a success response model
  42. func (o *Operation) SuccessResponse() (*Response, int, bool) {
  43. if o.Responses == nil {
  44. return nil, 0, false
  45. }
  46. for k, v := range o.Responses.StatusCodeResponses {
  47. if k/100 == 2 {
  48. return &v, k, true
  49. }
  50. }
  51. return o.Responses.Default, 0, false
  52. }
  53. // JSONLookup look up a value by the json property name
  54. func (o Operation) JSONLookup(token string) (interface{}, error) {
  55. if ex, ok := o.Extensions[token]; ok {
  56. return &ex, nil
  57. }
  58. r, _, err := jsonpointer.GetForToken(o.OperationProps, token)
  59. return r, err
  60. }
  61. // UnmarshalJSON hydrates this items instance with the data from JSON
  62. func (o *Operation) UnmarshalJSON(data []byte) error {
  63. if err := json.Unmarshal(data, &o.OperationProps); err != nil {
  64. return err
  65. }
  66. if err := json.Unmarshal(data, &o.VendorExtensible); err != nil {
  67. return err
  68. }
  69. return nil
  70. }
  71. // MarshalJSON converts this items object to JSON
  72. func (o Operation) MarshalJSON() ([]byte, error) {
  73. b1, err := json.Marshal(o.OperationProps)
  74. if err != nil {
  75. return nil, err
  76. }
  77. b2, err := json.Marshal(o.VendorExtensible)
  78. if err != nil {
  79. return nil, err
  80. }
  81. concated := swag.ConcatJSON(b1, b2)
  82. return concated, nil
  83. }
  84. // NewOperation creates a new operation instance.
  85. // It expects an ID as parameter but not passing an ID is also valid.
  86. func NewOperation(id string) *Operation {
  87. op := new(Operation)
  88. op.ID = id
  89. return op
  90. }
  91. // WithID sets the ID property on this operation, allows for chaining.
  92. func (o *Operation) WithID(id string) *Operation {
  93. o.ID = id
  94. return o
  95. }
  96. // WithDescription sets the description on this operation, allows for chaining
  97. func (o *Operation) WithDescription(description string) *Operation {
  98. o.Description = description
  99. return o
  100. }
  101. // WithSummary sets the summary on this operation, allows for chaining
  102. func (o *Operation) WithSummary(summary string) *Operation {
  103. o.Summary = summary
  104. return o
  105. }
  106. // WithExternalDocs sets/removes the external docs for/from this operation.
  107. // When you pass empty strings as params the external documents will be removed.
  108. // When you pass non-empty string as one value then those values will be used on the external docs object.
  109. // So when you pass a non-empty description, you should also pass the url and vice versa.
  110. func (o *Operation) WithExternalDocs(description, url string) *Operation {
  111. if description == "" && url == "" {
  112. o.ExternalDocs = nil
  113. return o
  114. }
  115. if o.ExternalDocs == nil {
  116. o.ExternalDocs = &ExternalDocumentation{}
  117. }
  118. o.ExternalDocs.Description = description
  119. o.ExternalDocs.URL = url
  120. return o
  121. }
  122. // Deprecate marks the operation as deprecated
  123. func (o *Operation) Deprecate() *Operation {
  124. o.Deprecated = true
  125. return o
  126. }
  127. // Undeprecate marks the operation as not deprected
  128. func (o *Operation) Undeprecate() *Operation {
  129. o.Deprecated = false
  130. return o
  131. }
  132. // WithConsumes adds media types for incoming body values
  133. func (o *Operation) WithConsumes(mediaTypes ...string) *Operation {
  134. o.Consumes = append(o.Consumes, mediaTypes...)
  135. return o
  136. }
  137. // WithProduces adds media types for outgoing body values
  138. func (o *Operation) WithProduces(mediaTypes ...string) *Operation {
  139. o.Produces = append(o.Produces, mediaTypes...)
  140. return o
  141. }
  142. // WithTags adds tags for this operation
  143. func (o *Operation) WithTags(tags ...string) *Operation {
  144. o.Tags = append(o.Tags, tags...)
  145. return o
  146. }
  147. // AddParam adds a parameter to this operation, when a parameter for that location
  148. // and with that name already exists it will be replaced
  149. func (o *Operation) AddParam(param *Parameter) *Operation {
  150. if param == nil {
  151. return o
  152. }
  153. for i, p := range o.Parameters {
  154. if p.Name == param.Name && p.In == param.In {
  155. params := append(o.Parameters[:i], *param)
  156. params = append(params, o.Parameters[i+1:]...)
  157. o.Parameters = params
  158. return o
  159. }
  160. }
  161. o.Parameters = append(o.Parameters, *param)
  162. return o
  163. }
  164. // RemoveParam removes a parameter from the operation
  165. func (o *Operation) RemoveParam(name, in string) *Operation {
  166. for i, p := range o.Parameters {
  167. if p.Name == name && p.In == name {
  168. o.Parameters = append(o.Parameters[:i], o.Parameters[i+1:]...)
  169. return o
  170. }
  171. }
  172. return o
  173. }
  174. // SecuredWith adds a security scope to this operation.
  175. func (o *Operation) SecuredWith(name string, scopes ...string) *Operation {
  176. o.Security = append(o.Security, map[string][]string{name: scopes})
  177. return o
  178. }
  179. // WithDefaultResponse adds a default response to the operation.
  180. // Passing a nil value will remove the response
  181. func (o *Operation) WithDefaultResponse(response *Response) *Operation {
  182. return o.RespondsWith(0, response)
  183. }
  184. // RespondsWith adds a status code response to the operation.
  185. // When the code is 0 the value of the response will be used as default response value.
  186. // When the value of the response is nil it will be removed from the operation
  187. func (o *Operation) RespondsWith(code int, response *Response) *Operation {
  188. if o.Responses == nil {
  189. o.Responses = new(Responses)
  190. }
  191. if code == 0 {
  192. o.Responses.Default = response
  193. return o
  194. }
  195. if response == nil {
  196. delete(o.Responses.StatusCodeResponses, code)
  197. return o
  198. }
  199. if o.Responses.StatusCodeResponses == nil {
  200. o.Responses.StatusCodeResponses = make(map[int]Response)
  201. }
  202. o.Responses.StatusCodeResponses[code] = *response
  203. return o
  204. }