Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Character escaping problem #873

Closed
bpandur opened this issue Apr 9, 2018 · 4 comments
Closed

Character escaping problem #873

bpandur opened this issue Apr 9, 2018 · 4 comments
Assignees

Comments

@bpandur
Copy link

bpandur commented Apr 9, 2018

Currently, we're trying to call a mutation which has a JSON parameter. We've already managed to send the request but the JSON parameter wasn't escaped correctly and our backend is not able to parse it correctly.

We intercepted the request with the OkHttpClient object:

Header:

Accept: application/json
CONTENT_TYPE: application/json
X-APOLLO-OPERATION-ID: 9b6bc35328395ce775411bd43e5b1862690ce03194bd42bd3a85d38e7fa32fbd
X-APOLLO-OPERATION-NAME: processStart
Content-Type: application/json; charset=utf-8
Content-Length: 244
Host: uniweb-api.dev.ferratum.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.8.1

Data:

{"query":"mutation processStart($jsonobject: JSON!) {  processStart(type: ONBOARDING_PROCESS, name: \"POC_MyAccountApplication\", parameters: $jsonobject)}","variables":{"jsonobject":"{\"entityUid\":\"CE-FBM_MB_TC\",\"channel\":\"SE_MB_MA\"}"}}

Is there any chance to replace the \" with "? Why is it escaped in this way?

Related code snippets:

ProcessStartMutation build = new ProcessStartMutation.Builder().jsonobject(new JSONObject("{\"entityUid\":\"CE-FBM_MB_TC\",\"channel\":\"SE_MB_MA\"}")).build();
ApolloCall<ProcessStartMutation.Data> entryDetailQuery = apolloClient.mutate(build);
    private static class JsonCustomTypeAdapter implements CustomTypeAdapter<JSONObject> {
        @Override
        public JSONObject decode(@Nonnull String value) {
            try {
                return new JSONObject(value);
            } catch (JSONException e) {
                return null;
            }
        }

        @Nonnull
        @Override
        public String encode(@Nonnull JSONObject value) {
            return value.toString();
        }
    }

Thanks in advance,
Balazs

@sav007
Copy link
Contributor

sav007 commented Apr 9, 2018

Are you referring to: {"jsonobject":"{\"entityUid\":\"CE-FBM_MB_TC\",\"channel\":\"SE_MB_MA\"}"}? If yes than re answer is that encode function returns return value.toString();

And what version of Apollo are you using?

Try to use the latest snapshot version, as it has support of Map serialization (sort of what you need if you replace JSONObject to Map).
https://github.com/apollographql/apollo-android/blob/master/apollo-runtime/src/main/java/com/apollographql/apollo/response/CustomTypeValue.java

@bpandur
Copy link
Author

bpandur commented Apr 10, 2018

Now I'm using the Snapshot version 0.4.5-SNAPSHOT, but the result is still the same:

"{\"channel\":\"SE_MB_MA\",\"entityUidd\":\"CE-FBM_MB_TC\"}"
Map<String, String> map = new HashMap<>();
map.put("entityUid", "CE-FBM_MB_TC");
map.put("channel", "SE_MB_MA");

ProcessStartMutation build = new ProcessStartMutation.Builder().jsonobject(map).build();

ApolloCall<ProcessStartMutation.Data> entryDetailQuery = apolloClient
                .mutate(build);
private static class JsonCustomTypeAdapter implements CustomTypeAdapter<Map<String, String>> {

        @SuppressWarnings("unchecked")
        @Override
        public Map<String, String> decode(@Nonnull CustomTypeValue value) {
            return (Map<String, String>) value.value;
        }

        @Nonnull
        @Override
        public CustomTypeValue encode(@Nonnull Map<String, String> value) {
            return CustomTypeValue.fromRawValue(value);
        }
    }

@sav007
Copy link
Contributor

sav007 commented Apr 13, 2018

Sorry, but why "{\"channel\":\"SE_MB_MA\",\"entityUidd\":\"CE-FBM_MB_TC\"}" is not represented as separate GraphQL type.

CustomTypeAdapter designed to serialize / deserialize primitive or scalar GraphQL types (like Date, Money etc.) but not objects. As a result even it can serialize Map, List but it will be serialize as String not as Json object.

If you need to serialize object then it must be represented as GraphQL Object type in the schema. Or your server should accept jsonobject as Json string and do parsing.

@alexisbmills
Copy link

The use case is the implementation of generic mutations where a parameter could contain various object structures. One solution is to provide a scalar JSON type.

An working example of the mutation request body, supported by the JavaScript Apollo Client , where the value of the parameters is passed a JavaScript object literal:
[ { "variables": { "name": "OneOfManySituations", "parameters": { "key": "A value", "anotherKey": "Another value" } }, "extensions": {}, "operationName": "processStart", "query": "mutation processStart($name: String!, $parameters: JSON!) {\n processUid: processStart(name: $name, parameters: $parameters)\n}\n" } ]

Can this be reproduced in this library?

A more type-centric solution is union types which is being discussed in an RFC.

@sav007 sav007 added the feature label Apr 23, 2018
@sav007 sav007 self-assigned this Apr 27, 2018
sav007 added a commit to sav007/apollo-android that referenced this issue Apr 27, 2018
Current implementation allows Map to be serialized as JSON string value, with this changes we introduce new CustomTypeValue type that will
allow Map to be serialized as regular JSON object.

Closes apollographql#873
sav007 added a commit to sav007/apollo-android that referenced this issue May 1, 2018
Current implementation allows Map to be serialized as JSON string value, with this changes we introduce new CustomTypeValue type that will
allow Map to be serialized as regular JSON object.

Closes apollographql#873
sav007 added a commit that referenced this issue May 1, 2018
Current implementation allows Map to be serialized as JSON string value, with this changes we introduce new CustomTypeValue type that will
allow Map to be serialized as regular JSON object.

Closes #873
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants