When I execute a mutation created by useMutation with react-relay, and do not explicitly set optional variables, Relay sets those optional variables to null in the request.
My GraphQL server (Apollo) is able to distinguish between undefined and null values. I tested this by sending a GraphQL request from a HTTP client and omitting optional values.
I did search the docs, code and GitHub issues and neither did I find a way to adjust this behavior nor a reasoning why Relay does this.
The only thing I found is that in the official GraphQL specification omission and null are intermingled:
Mutations - Support being more specific about null and omission in input types
Questions:
What is Relay's reasoning behind setting missing optional variables to null? Is it because Relay adheres to the GraphQL spec accurately? If yes, does that mean that my Apollo GraphQL server is not properly adhering to the GraphQL spec?
Is there a way to omit optional variables instead of sending null with Relay?
Related
I need to have a "global argument" that can be specified (at most) once and applies to the entire request (having however many queries/mutations inside). If I were able to have the client specify it in query(arg: "value") {...} and/or mutation(arg: "value") {...} I would... but I understand this is reserved for "variables". I dislike other options I am aware of:
HTTP header - ties this to HTTP only, not in schema, not documented nicely.
POST /graphql
X-MyArg: some-value
...
{"query":"{someQuery{id name}}"}
HTTP (URL) query string parameter - ugh... I like the single common URL, also same problems as with (1)
POST /graphql?myArg=some-value
...
{"query":"{someQuery{id name}}"}
Introduce an intermediate wrapper field to expose this argument ... but this makes everything longer and I don't know of a way saying "this must be specified/requested at most once", while supporting multiple occurrences makes no sense for at least some of these (e.g. authentication / authorization / security related and others).
POST /graphql
...
{"query":"{wrapper(arg: \"some-value\"){someQuery{id name}}}"}
Cheat/hack and require an $arg variable (meant to be defined by the API client(s)) to be specified while somehow preventing the framework I am using from throwing up when that variable isn't actually referenced from anywhere inside.
POST /graphql
...
{"query":"query($arg:String){someQuery{id name}}","variables":{"arg":"some-value"}}
Can anyone help? Am I missing something or am I really forced to pick one of those poison pills?
I defined some custom scalars in my GraphQL schema. If I query for data the custom scalars can be available on various places. Is it possible to extract them from a GraphQL response in a generic way?
So I get the response and then I want to extract all values of a scalar I defined into an array. Based on the schema the information is available. Is the some JavaScript library, which can do that?
I use Apollo Server and JavaScript on the client.
Use local resolver - #client directive - it can read other fields/cache to /collect/convert/provide required data.
I have a question about the light-rest-4j URL validation, for example, if I have a POST request path /party, if I type the path as /party11, I will get error: No handler defined for path /party11, but if I put /party?qqqq, It will pass through, and system treat it as /party should we add validation for this? Our QA team creates this as a defect, in case user input it by mistake, they expect to have error message return.
The light-rest-4j framework validates the request/response based on the OpenAPI specification during the runtime; however, it only validates based on the spec — nothing more and nothing less. In most cases, the spec will define the type of headers, query parameters, path parameters, and cookies, as well as if they are required. We make sure these are validated as defined. For anything that is not defined in the spec, we are doing nothing. For example, an extra query parameter or an extra header in the request will be ignored as they are not defined in the spec. We cannot do any negative validation as we don't know if any client will add additional headers or query parameters for tracing, auditing, etc. A request that comes from one client might be different than another one comes from the same client through a gateway or proxy.
I have an app written with reason-react using apollo-client. I have defined some fragments on the frontend to basically reuse some field definitions. I'm setting up automated tests for a components that uses fragments, but I keep getting this warning saying I need to use the IntrospectionFragmentMatcher.
'You are using the simple (heuristic) fragment matcher, but your queries contain union or interface types. Apollo Client will not be able to accurately map fragments. To make this error go away, use the `IntrospectionFragmentMatcher` as described in the docs: https://www.apollographql.com/docs/react/advanced/fragments.html#fragment-matcher'
I've tried setting up the fragment matcher according to the docs. The codegen result returns no types:
{
"__schema": {
"types": []
}
}
When I queried my server and looked at the manual method recommended by apollo-client, I noticed it would also return no types.
Another strange thing is that when I don't use the fragment matcher, I get the mocked response back but I just get the warnings from apollo. If I do use it then the mocked response doesn't return correctly.
Why would I query the graphql api for fragments defined in my frontend code? Why would I only received these errors when running the tests & using mock data, but not when running my actual application?
As the error states, the default fragment matcher does not work on intersection or union types. You will need to use Apollo's IntrospectionFragmentMatcher. It works by asking the server (introspecting) for information about your schema types, and then providing that information for reference to the cache so that it can match the fields accurately. It's not querying the server for information about the fragments you are defining on the front end, it's asking for data about the GraphQL schema that must be defined on your back end so that it can properly relate the two. There is an example in the documentation, also more information here.
As for why your server is not returning any types, that is a separate issue that would require more info to debug. If you're using Apollo Server, doublecheck your schema to make sure all the necessary types are defined properly and that you are passing them into the server when it's initialized.
I'm building a microservice system with multiple disconnected components, and I'm currently trying to find out how to implement knowing which fields on an object should be updated based on the protobuf data provided.
The flow is this:
The client sends a JSON-request to an API.
The API translates the JSON-data into a protobuf struct, which is then sent along to the microservice responsible for handling it.
The microservice receives the data from the API and performs any action on it, in this case, I'm trying to change a single value in a MySQL table, such as a client's email address.
Now, the problem I have is that since protobuf (understandably) doesn't allow pointers, the protobuf object will contain zero-values for everything not provided. This means that if a customer wants to update their email address, I can't know if they also set IncludeInMailLists to false - or if it was simply not provided (having its zero-value) and shouldn't change.
The question is: how will I - from the protobuf object - know if a value is expressively set to 0, or just not provided?
My current solution is pretty much having a special UpdateCustomer-object which also has an array of Fields specifying which fields the microservice should care about, but it feels like bad solution.
Someone must have solved this better already. How should I implement it?
Protobufs field masks are one way.
https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.FieldMask
https://github.com/golang/protobuf/issues/225
But if you are using grpc then there's a (sort of) built in way.
Grpc wrappers
Since proto3 (protobufs v3) there's been no distinction between a primitive that is not set, and a primitive that's been set to the "zero value" (false, 0, "", etc).
Instead you can use objects or in protobufs language a "message", as objects can be nil / null. You've not mentioned what language you are working in but hopefully these examples make sense.
Given an RPC service such as:
import "google/protobuf/wrappers.proto";
service Users {
rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse)
}
message UpdateUserRequest {
int32 user_id = 1;
google.protobuf.StringValue email = 2;
}
message UpdateUserResponse {}
Note the import "google/protobuf/wrappers.proto"; is important.
It given you access to the google protobufs wrappers source code here. These are not objects that have methods that allow you to test for presence.
Grpc generated code in java gives you methods such as .hasEmail() which returns true if the value is present. The getter on an unset value will still return you the zero value. I think the golang version uses pointers that you can test for nil instead of an explicit hasX() method.
More info / discussion in this github issue