graphql-query.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. package v1
  11. import (
  12. "encoding/json"
  13. "net/http"
  14. "devt.de/krotik/common/stringutil"
  15. "devt.de/krotik/eliasdb/api"
  16. "devt.de/krotik/eliasdb/graphql"
  17. )
  18. /*
  19. EndpointGraphQLQuery is a query-only GraphQL endpoint URL (rooted). Handles
  20. everything under graphql-query/...
  21. */
  22. const EndpointGraphQLQuery = api.APIRoot + APIv1 + "/graphql-query/"
  23. /*
  24. GraphQLQueryEndpointInst creates a new endpoint handler.
  25. */
  26. func GraphQLQueryEndpointInst() api.RestEndpointHandler {
  27. return &graphQLQueryEndpoint{}
  28. }
  29. /*
  30. Handler object for GraphQL operations.
  31. */
  32. type graphQLQueryEndpoint struct {
  33. *api.DefaultEndpointHandler
  34. }
  35. /*
  36. HandleGET handles GraphQL queries.
  37. */
  38. func (e *graphQLQueryEndpoint) HandleGET(w http.ResponseWriter, r *http.Request, resources []string) {
  39. gqlquery := map[string]interface{}{
  40. "variables": nil,
  41. "operationName": nil,
  42. }
  43. partition := r.URL.Query().Get("partition")
  44. if partition == "" && len(resources) > 0 {
  45. partition = resources[0]
  46. }
  47. if partition == "" {
  48. http.Error(w, "Need a partition", http.StatusBadRequest)
  49. return
  50. }
  51. query := r.URL.Query().Get("query")
  52. if query == "" {
  53. http.Error(w, "Need a query parameter", http.StatusBadRequest)
  54. return
  55. }
  56. gqlquery["query"] = query
  57. if operationName := r.URL.Query().Get("operationName"); operationName != "" {
  58. gqlquery["operationName"] = operationName
  59. }
  60. if variables := r.URL.Query().Get("variables"); variables != "" {
  61. varData := make(map[string]interface{})
  62. if err := json.Unmarshal([]byte(variables), &varData); err != nil {
  63. http.Error(w, "Could not decode variables: "+err.Error(), http.StatusBadRequest)
  64. return
  65. }
  66. gqlquery["variables"] = varData
  67. }
  68. res, err := graphql.RunQuery(stringutil.CreateDisplayString(partition)+" query",
  69. partition, gqlquery, api.GM, nil, true)
  70. if err != nil {
  71. http.Error(w, err.Error(), http.StatusBadRequest)
  72. return
  73. }
  74. w.Header().Set("content-type", "application/json; charset=utf-8")
  75. json.NewEncoder(w).Encode(res)
  76. }
  77. /*
  78. SwaggerDefs is used to describe the endpoint in swagger.
  79. */
  80. func (e *graphQLQueryEndpoint) SwaggerDefs(s map[string]interface{}) {
  81. s["paths"].(map[string]interface{})["/v1/graphql-query/{partition}"] = map[string]interface{}{
  82. "get": map[string]interface{}{
  83. "summary": "GraphQL interface which only executes non-modifying queries.",
  84. "description": "The GraphQL interface can be used to query data.",
  85. "consumes": []string{
  86. "application/json",
  87. },
  88. "produces": []string{
  89. "text/plain",
  90. "application/json",
  91. },
  92. "parameters": []map[string]interface{}{
  93. {
  94. "name": "partition",
  95. "in": "path",
  96. "description": "Partition to query.",
  97. "required": true,
  98. "type": "string",
  99. },
  100. {
  101. "name": "operationName",
  102. "in": "query",
  103. "description": "GraphQL query operation name.",
  104. "required": false,
  105. "type": "string",
  106. },
  107. {
  108. "name": "query",
  109. "in": "query",
  110. "description": "GraphQL query.",
  111. "required": true,
  112. "type": "string",
  113. },
  114. {
  115. "name": "variables",
  116. "in": "query",
  117. "description": "GraphQL query variable values.",
  118. "required": false,
  119. "type": "string",
  120. },
  121. },
  122. "responses": map[string]interface{}{
  123. "200": map[string]interface{}{
  124. "description": "The operation was successful.",
  125. },
  126. "default": map[string]interface{}{
  127. "description": "Error response",
  128. "schema": map[string]interface{}{
  129. "$ref": "#/definitions/Error",
  130. },
  131. },
  132. },
  133. },
  134. }
  135. }