I'm using Go to implement an API endpoint that should return data that looks like this:
{
"object1s": [
{
"object2": {
"key1": {
"key3": 1,
"key4": 2,
"key5": 3
},
"key2": {
"key3": 4,
"key4": 5,
"key5": 6
}
}
},
{
"object2": {
"key1": {
"key3": 7,
"key4": 8,
"key5": 9
},
"key2": {
"key3": 10,
"key4": 11,
"key5": 12
}
}
}
]
}
How can I model this with proto3?
I have this:
message SubObject {
map<string, map<string, int32>> object2 = 1;
}
message ResponseMessage {
repeated SubObject object1s = 1;
}
But I believe the syntax map<string, map<string, int>> is invalid.
So what is the correct way to describe SubObject?
Your desired way isn't supported yet.
Right now, only way to do this, is to create a message type to hold the inner map field.
message InnerObject {
map<string, int32> object3 = 1;
}
message SubObject {
map<string, InnerObject> object2 = 1;
}
message ResponseMessage {
repeated SubObject object1s = 1;
}
So, you have to modify your return data as follows,
{
"object1s": [
{
"object2": {
"key1": {
"object3": {
"key3": 1,
"key4": 2
}
}
}
}
]
}
Reference : Issue#4596
Related
I cannot mutate a list of objects completely, because only the last element of the array will be mutated.
What already works perfectly is, if I put each element ({play_positions_id: ...}) in the array manually like here:
mutation CreateProfile {
__typename
create_profiles_item(data: {status: "draft", play_positions: [{play_positions_id: {id: "1"}}, {play_positions_id: {id: "2"}}]}) {
id
status
play_positions {
play_positions_id {
abbreviation
name
}
}
}
}
Output:
{
"data": {
"__typename": "Mutation",
"create_profiles_item": {
"id": "1337",
"status": "draft",
"play_positions": [
{
"play_positions_id": {
"id": "1",
"abbreviation": "RWB",
"name": "Right Wingback"
}
},
{
"play_positions_id": {
"id": "2",
"abbreviation": "CAM",
"name": "Central Attacking Midfielder"
}
}
],
}
}
}
Since you can add many of those elements, I defined a variable/argument like here
mutation CreateProfile2($cpppi: [create_profiles_play_positions_input]) {
__typename
create_profiles_item(data: {status: "draft", play_positions: $cpppi}) {
id
status
play_positions {
play_positions_id {
id
abbreviation
name
}
}
}
}
Variable object for above:
"cpppi": {
"play_positions_id": {
"id": "1"
},
"play_positions_id": {
"id": "2
}
}
Output:
{
"data": {
"__typename": "Mutation",
"create_profiles_item": {
"id": "1338",
"play_positions": [
{
"play_positions_id": {
"id": "2",
"abbreviation": "CAM",
"name": "Central Attacking Midfielder"
}
}
],
}
}
}
Schema:
input create_profiles_input {
id: ID
status: String!
play_positions: [create_profiles_play_positions_input]
}
input create_profiles_play_positions_input {
id: ID
play_positions_id: create_play_positions_input
}
input create_play_positions_input {
id: ID
abbreviation: String
name: String
}
At the last both snippets, only the last object with the id "2" will be mutated. I need these to use the defined input type from my backend.
I figured it out. I got it wrong with the brackets in the variable. Here the solution:
"cpppi": [
{
"play_positions_id": {
"id": "1"
}
},
{
"play_positions_id": {
"id": "2"
}
}
]
I have the following query that can be run against the github graphql API
query userRepositories($cursor: String, $q: String!, $githubId: String!) {
search(query: $q, type: REPOSITORY, first: 100, after: $cursor) {
repositoryCount
pageInfo {
endCursor
startCursor
}
nodes {
... on Repository {
id
name
description
isArchived
isPrivate
nameWithOwner
url
defaultBranchRef {
target {
... on Commit {
history(first: 10, author: {id: $githubId}) {
totalCount
}
}
}
}
}
}
}
}
It returns results like this:
{
"data": {
"search": {
"repositoryCount": 103,
"pageInfo": {
"endCursor": "Y3Vyc29yOjEwMA==",
"startCursor": "Y3Vyc29yOjE="
},
"nodes": [
{
"id": "MDEwOlJlcG9zaXRvcnk2MTg1OTczOA==",
"name": "microstates",
"nameWithOwner": "thefrontside/microstates",
"url": "https://github.com/thefrontside/microstates",
"defaultBranchRef": {
"target": {
"history": {
"totalCount": 0
}
}
},
{
"id": "MDEwOlJlcG9zaXRvcnkxNTU5MTUyODc=",
"name": "effection",
"nameWithOwner": "thefrontside/effection",
"url": "https://github.com/thefrontside/effection",
"defaultBranchRef": {
"target": {
"history": {
"totalCount": 16
}
}
}
},
I am only interested in the nodes array that has a defaultBranchRef.target.history.totalCount that is greater than 0.
So I am not interested in element 0 of the nodes array but I am of element 1.
Can I filter this in graphql or do I have to do that in code outside of the query?
GraphQL can't filter an array so if the API support filter base on totalCount you can pass this filter otherwise you have to filter in your code. In JS it's very easy:
const filtered = {
...data,
search: {
...data.search,
nodes: data.search.nodes.filter(node => node.defaultBranchRef.target.history.totalCount > 0),
}
};
Now I am testing the Shopify graphql for get customer by email.
But Shopify Customer query does not work correctly. query is following.
{
customers(first: 10, query:"email:'test#gmail.com'") {
edges {
node {
id
lastName
verifiedEmail
firstName
lastName
email
phone
tags
}
}
}
}
but the result is following.
{
"data": {
"customers": {
"edges": []
}
},
"extensions": {
"cost": {
"requestedQueryCost": 252,
"actualQueryCost": 2,
"throttleStatus": {
"maximumAvailable": 1000,
"currentlyAvailable": 998,
"restoreRate": 50
}
}
}
}
Shopify Store have that customer. But the query didn't find customer.
I am sure we can solve this problem.
If you have experience one, please help me.
Thanks.
Not sure if you still need an answer. The string after query: needs to be just the email. see here:
query GetThat {
customers(first: 10, query: "mikeyboy#aol.com"){
edges{
node {
firstName
lastName
defaultAddress {
id
address1
}
}
}
}
}
Results:
{
"data": {
"customers": {
"edges": [
{
"node": {
"firstName": "MikeyBoy",
"lastName": "ohohoh",
"defaultAddress": {
"id": "gid://shopify/MailingAddress/7969224163540?model_name=CustomerAddress",
"address1": "123 sesame st"
}
}
}
]
}
},
"extensions": {
"cost": {
"requestedQueryCost": 22,
"actualQueryCost": 4,
"throttleStatus": {
"maximumAvailable": 1000,
"currentlyAvailable": 996,
"restoreRate": 50
}
}
}
}
I am trying to filter an original map by comparing with a condition map which has only the key sets with id. Based on the condition map, I want to filter from the original map.
The original map which I have is,
Map<Integer, AppFeatureDTO> appFeatureMap = new TreeMap<>();
which will result like,
{
"101": {
"id": 101,
"subFeature": {
"1": {
"id": 1,
"title": "Title Value",
"desc": "Description Value"
}
}
},
"102": {
"id": 102,
"subFeature": {
"1": {
"id": 1,
"title": "Title Value",
"desc": "Description Value"
}
}
},
"103": {
"id": 103,
"subFeature": {
"1": {
"id": 1,
"title": "Title Value",
"desc": "Description Value"
},
"2": {
"id": 2,
"title": "Title Value",
"desc": "Description Value"
},
"3": {
"id": 3,
"title": "Title Value",
"desc": "Description Value"
},
"4": {
"id": 4,
"title": "Title Value",
"desc": "Description Value"
}
}
}
}
and the corresponding classes are:
class AppFeatureDTO {
private int id;
private Map<Integer, AppSubFeatureDTO> subFeature;
}
class AppSubFeatureDTO{
private int id;
private String title;
private String description;
}
then I have a filter map,
Map<Integer, FeatureDTO> conditionFilterMap = new TreeMap<>();
which is resulting like,
{
"101": {
"id": 101,
"subFeature": {
"1": {
"id": 1,
}
}
},
"103": {
"id": 103,
"subFeature": {
"2": {
"id": 2
},
"4": {
"id": 4
}
}
}
}
the corresponding classes for the filter map are,
class FeatureDTO {
private int id;
private Map<Integer, SubFeatureDTO> subFeature;
}
class SubFeatureDTO{
private int id;
}
I want to filter the result map using conditionFilterMap like,
{
"101": {
"id": 101,
"subFeature": {
"1": {
"id": 1,
"title": "Title Value",
"desc": "Description Value"
}
}
},
"103": {
"id": 103,
"subFeature": {
"2": {
"id": 2,
"title": "Title Value",
"desc": "Description Value"
},
"4": {
"id": 4,
"title": "Title Value",
"desc": "Description Value"
}
}
}
}
I'm using spring modelMapper to copy AppFeatureDTO to FeatureDTO. But, filtering the map, I didn't get clue.
Could you please suggest how to get the resultMap using Java 8?
Even I couldn't imagine a simple solution using Java 7 or 6 also.
Assuming that the map key is the same as the id field:
Map<Integer, AppFeatureDTO> resultMap = conditionFilterMap.values().stream()
.map(FeatureDTO::getId)
.map(appFeatureMap::get)
.collect(Collectors.toMap(AppFeatureDTO::getId, a -> new AppFeatureDTO(a.getId(),
conditionFilterMap.get(a.getId()).getSubFeature().values().stream()
.map(SubFeatureDTO::getId)
.map(a.getSubFeature()::get)
.collect(Collectors.toMap(AppSubFeatureDTO::getId, x -> x)))));
If you need TreeMap, add the arguments (a, b) -> a, TreeMap::new to the Collectors.toMap calls.
The non-stream version doesn't really look any worse:
Map<Integer, AppFeatureDTO> resultMap = new TreeMap<>();
for (FeatureDTO f : conditionFilterMap.values()) {
AppFeatureDTO a = appFeatureMap.get(f.getId());
Map<Integer, AppSubFeatureDTO> resultSub = new TreeMap<>();
for (SubFeatureDTO s : f.getSubFeature().values()) {
resultSub.put(s.getId(), a.getSubFeature().get(s.getId()));
}
resultMap.put(a.getId(), new AppFeatureDTO(a.getId(), resultSub));
}
I need to filter my data.but i don't know how to use Linq.
The ClassRoom Model
public class ClassRoom
{
public int RoomID { get; set; }
public string Name { get; set; }
public List<Student> Students { get; set; }
}
The Student Model
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
public int StyleId {get;set;}
}
Example JSON DATA
var json=
[
{
"RoomID": 1,
"Name": "A Class",
"Students": [{
"StudentId": 1,
"Name":"Charlie",
"StyleId":"1"
},
{
"StudentId": 2,
"Name":"Tom",
"StyleId":"2"
}
]
},
{
"RoomID": 2,
"Name": "B Class",
"Students": [{
"StudentId": 3,
"Name":"ALLEN",
"StyleId":"2"
},
{
"StudentId": 4,
"Name":"Jeremy",
"StyleId":"2"
},
{
"StudentId": 5,
"Name":"Curry",
"StyleId":"3"
}
]
}
]
If i want get StyleID equals "2", and below is expected a answer.
var json =
[
{
"RoomID": 1,
"Name": "A Class",
"Students": [
{
"StudentId": 2,
"Name":"Tom",
"StyleId":"2"
}
]
},
{
"RoomID": 2,
"Name": "B Class",
"Students": [{
"StudentId": 3,
"Name":"ALLEN",
"StyleId":"2"
},
{
"StudentId": 4,
"Name":"Jeremy",
"StyleId":"2"
}
]
}
]
Here is how i filer, but not correct. how can i get expected data?
json.Select( v => v.Students.where( i => i.StyleId == "2") )
thanks.
Try linq query as below.
var result = json.Where(v => v.Students.Any(y => y.StyleId == "2"))
.Select(v => new ClassRoom() {
RoomID = v.RoomID,
Name = v.Name,
Students = v.Students.Where(y => y.StyleId == "2")
});