encode creates a JSON encoded GraphQL response.
(encInp encodeInput)
| 78 | |
| 79 | // encode creates a JSON encoded GraphQL response. |
| 80 | func (genc *graphQLEncoder) encode(encInp encodeInput) bool { |
| 81 | child := genc.children(encInp.fj) |
| 82 | // This is a scalar value for DQL. |
| 83 | if child == nil { |
| 84 | val, err := genc.getScalarVal(encInp.fj) |
| 85 | if err != nil { |
| 86 | genc.errs = append(genc.errs, encInp.parentField.GqlErrorf(encInp.parentPath, |
| 87 | "%s", err.Error())) |
| 88 | // return false so that the caller can appropriately handle null writing. |
| 89 | return false |
| 90 | } |
| 91 | if val == nil { |
| 92 | // val being nil here can only be the case for a top-level query and not for a nested |
| 93 | // field. val being nil indicates that the top-level query has no value to resolve |
| 94 | // to, and we need to write null/[]/raise an error depending on the return type of the |
| 95 | // query. Now, for queries which return a list (whether nullable or not), [] would |
| 96 | // anyways be written by the parent encode() call. If we return false from here, |
| 97 | // then too the parent encode() call will write [], but then we won't be able to |
| 98 | // distinguish between whether the first item of the list was null or the whole query |
| 99 | // had no results. |
| 100 | // So, for lists lets return true. |
| 101 | // We will return false for single valued cases so that the caller can correctly write |
| 102 | // null or raise an error. |
| 103 | // Note that we don't need to add any errors to the errs here. |
| 104 | return encInp.parentField.Type().ListType() != nil |
| 105 | } |
| 106 | |
| 107 | // here we have a valid value, lets write it to buffer appropriately. |
| 108 | if encInp.parentField.Type().IsGeo() { |
| 109 | var geoVal map[string]interface{} |
| 110 | x.Check(json.Unmarshal(val, &geoVal)) // this unmarshal can't error |
| 111 | if err := completeGeoObject(encInp.parentPath, encInp.parentField, geoVal, |
| 112 | genc.buf); err != nil { |
| 113 | genc.errs = append(genc.errs, err) |
| 114 | return false |
| 115 | } |
| 116 | } else { |
| 117 | // we got a GraphQL scalar |
| 118 | // check coercion rules to see if it matches the GraphQL spec requirements. |
| 119 | if cantCoerceScalar(val, encInp.parentField) { |
| 120 | genc.errs = append(genc.errs, encInp.parentField.GqlErrorf(encInp.parentPath, |
| 121 | "Error coercing value '%s' for field '%s' to type %s.", |
| 122 | string(val), encInp.parentField.Name(), encInp.parentField.Type().Name())) |
| 123 | // if it can't be coerced, return false so that the caller can appropriately |
| 124 | // handle null writing |
| 125 | return false |
| 126 | } |
| 127 | x.Check2(genc.buf.Write(val)) |
| 128 | } |
| 129 | // we have successfully written the value, lets return true to indicate that this |
| 130 | // call to encode() was successful. |
| 131 | return true |
| 132 | } |
| 133 | |
| 134 | // if we are here, ensure that GraphQL was expecting an object, otherwise return error. |
| 135 | if len(encInp.childSelSet) == 0 { |
| 136 | genc.errs = append(genc.errs, encInp.parentField.GqlErrorf(encInp.parentPath, |
| 137 | gqlSchema.ErrExpectedScalar)) |
nothing calls this directly
no test coverage detected