Форум программистов, компьютерный форум, киберфорум
GraphQL
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
1 / 1 / 0
Регистрация: 11.01.2020
Сообщений: 15
1

Аргумент graphql запроса не преобразуетс­я в слайс структур

14.08.2022, 13:35. Показов 774. Ответов 4

Author24 — интернет-сервис помощи студентам
Добрый день.

для обработки запросов в формате graphql использую библиотеку github.com/graphql-go/graphql


Аргумент запроса filters , принимает объект. поэтому аргумент определен , как input

Все поля структур с большой буквы, т.е. экспортируемые.

Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
type Product struct {
    ProductId   int64   `json:"product_id"`
    Name        string  `json:"name"`
    CategoryId  int64   `json:"category_id"`
    BrandId     int64   `json:"brand_id"`
}
type Filter  struct {
    Id      int64   `json:"id"`
    Code    string  `json:"code"`
}
 
// products
var products = []Product{
    {
        ProductId:  18810,
        Name:       "Book",
        CategoryId: 19,
        BrandId:    39,
    },
}
Резолвер метод :

Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
                Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                    p_id, pOk := p.Args["product_id"].(int)
                    filters, filtersOk := p.Args["filters"].([]Filter)
 
                    fmt.Println("->filters: ", filters, "filtersOk: ", filtersOk)
 
                    fmt.Println("->print p.Args[filters]: ", p.Args["filters"])
                    
                    if pOk {
                        product_id := int64(p_id)
                        for _, product := range products {
                            if product.ProductId == product_id {
                                fmt.Println("->Name: ", product.Name, " queryType")
 
                                if len(filters) > 0 {
                                    for _, f := range filters {
                                        if (f.Code == "category" && product.CategoryId == f.Id) && (f.Code == "brand" && product.BrandId == f.Id) {
                                            return product, nil
                                        }
                                    }
                                }
 
 
                            }
                        }
                    }
                    return nil, nil
                },

Отправляю graphql запрос :

Код
http://localhost:8000/graphql?query={product(product_id:18810,filters:[{code:"category",id:19},{code:"brand",id:39}]){product_id,name}}
Ответ сервера:
Код
{"data":{"product":null}}
Хотя товар полностью соответствует данным переданным в фильтре.


Смотрю вывод в консоль , видно что аргумент filters не преобразовался в []Filter . хотя соответствует структуре golang

Код
->filters:  [] filtersOk:  false
->print p.Args[filters]:  [map[code:category id:19] map[code:brand id:39]]
->Name:  Book  queryType

Сокращенный вариант кода, который воспроизводит проблему:
https://play.golang.com/p/xrW__QRZ0k7
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.08.2022, 13:35
Ответы с готовыми решениями:

Отправка запроса GraphQL с использованием фреймворка Yew
Всем привет! У меня есть клиент на Yew и сервер с API GraphQL. Не нашел примеров, как...

Задание нескольких экземпляров структур как аргумент в методе
Есть метод образца Lista::Insert(Lista a, Lista b, Lista c), который по считыванию данных из...

Функция, возвращает квадрат аргумента, если аргумент число; хвост списка, если аргумент список; иначе сам аргумент
Помогите, пожалуйста, с заданием: Написать функцию, которая возвращает квадрат аргумента, если...

Работа с Graphql
Добрый день! Начал пробовать работать с graphql (сайт, который пытаюсь спарсить имеет такой тип...

graphql mutation
Можете помочь составить мутацию? type Mutation { createCustomMatch(input:...

4
294 / 255 / 76
Регистрация: 17.04.2022
Сообщений: 813
Записей в блоге: 8
14.08.2022, 16:37 2
Я не знаю что такое graphql, но мне кажется, что в тексте json-подобного запроса, отправляемого на сервер, запрос должен содержать валидный json. На знание истины не претендую, но что-то подсказывает, что имена ключей надо брать в кавычки итд
0
Модератор
5106 / 3334 / 535
Регистрация: 01.06.2013
Сообщений: 7,009
Записей в блоге: 9
14.08.2022, 16:53 3
Я тоже ничего не знаю, но
Go
1
if (f.Code == "category" && product.CategoryId == f.Id) && (f.Code == "brand" && product.BrandId == f.Id)
Как может f.Code быть одновременно равно и "category" и "brand".
Ну, вы поняли.
1
Эксперт функциональных языков программированияЭксперт Java
4544 / 2738 / 486
Регистрация: 28.04.2012
Сообщений: 8,648
14.08.2022, 20:17 4
Лучший ответ Сообщение было отмечено logthumb как решение

Решение

Цитата Сообщение от sqltd1 Посмотреть сообщение
Я не знаю что такое graphql, но мне кажется, что в тексте json-подобного запроса, отправляемого на сервер, запрос должен содержать валидный json.
Это не json, а graphql.

Добавлено через 12 минут
Цитата Сообщение от logthumb Посмотреть сообщение
видно что аргумент filters не преобразовался в []Filter . хотя соответствует структуре golang
Он и не должен преобразовываться. Откуда graphql должен узнать, что его нужно преобразовать и именно в []Filter?

Добавлено через 35 минут
logthumb, нужно самому руками разгребать Args и преобразовывать в нужную структуру. Во всяком случае, не припомню, чтобы эта библиотека умела сама как-то маппить запрос на Go'шные структуры.

Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
 
    "github.com/graphql-go/graphql"
)
 
type (
    Product struct {
        ProductId  int64  `json:"product_id"`
        Name       string `json:"name"`
        CategoryId int64  `json:"category_id"`
        BrandId    int64  `json:"brand_id"`
    }
 
    Filter struct {
        Id   int64
        Code string
    }
)
 
var products = []Product{
    {
        ProductId:  18810,
        Name:       "Book",
        CategoryId: 19,
        BrandId:    39,
    },
}
 
var productType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Product",
    Fields: graphql.Fields{
        "product_id": &graphql.Field{
            Type: graphql.Int,
        },
        "name": &graphql.Field{
            Type: graphql.String,
        },
    },
})
 
var filtersInputType = graphql.NewInputObject(graphql.InputObjectConfig{
    Name: "FiltersInput",
    Fields: graphql.InputObjectConfigFieldMap{
        "id": &graphql.InputObjectFieldConfig{
            Type: graphql.Int,
        },
        "code": &graphql.InputObjectFieldConfig{
            Type: graphql.String,
        },
    },
})
 
var queryType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Query",
    Fields: graphql.Fields{
        //http://localhost:8000/graphql?query={product(product_id:18810,filters:[{code:"category",id:19},{code:"brand",id:39}]){product_id,name}}
        "product": &graphql.Field{
            Type:        productType,
            Description: "Get product by product_id",
            Args: graphql.FieldConfigArgument{
                "product_id": &graphql.ArgumentConfig{
                    Type: graphql.Int,
                },
                "filters": &graphql.ArgumentConfig{
                    Type: graphql.NewList(filtersInputType),
                },
            },
            Resolve: func(p graphql.ResolveParams) (_ interface{}, err error) {
                var productId int64
                if productId, err = ProductId(p.Args); err != nil {
                    return nil, err
                }
 
                var filters []Filter
                if filters, err = Filters(p.Args); err != nil {
                    return nil, err
                }
 
                log.Println("-> productId:", productId, ", filters:", filters)
 
                for _, product := range products {
                    if product.ProductId != productId {
                        continue
                    }
 
                    if MatchFilters(&product, filters) {
                        return product, nil
                    }
                }
 
                return nil, nil
            },
        },
    },
})
 
func MatchFilters(p *Product, filters []Filter) bool {
    for _, f := range filters {
        if f.Code == "category" && p.CategoryId != f.Id {
            return false
        }
 
        if f.Code == "brand" && p.BrandId != f.Id {
            return false
        }
    }
 
    return true
}
 
func ProductId(args map[string]interface{}) (int64, error) {
    var pID, pOk = args["product_id"].(int)
    if !pOk {
        return 0, fmt.Errorf("product_id is not an int: %+v", args["product_id"])
    }
    return int64(pID), nil
}
 
func Filters(args map[string]interface{}) ([]Filter, error) {
    slice, ok := args["filters"].([]interface{})
    if !ok {
        return nil, fmt.Errorf("filters are not a slice: %+v", args["filters"])
    }
 
    var filters = make([]Filter, len(slice))
 
    for i, item := range slice {
        dict, ok := item.(map[string]interface{})
        if !ok {
            return nil, fmt.Errorf("filter is not a map: %+v", dict)
        }
 
        id, ok := dict["id"].(int)
        if !ok {
            return nil, fmt.Errorf("filter.id is not an int: %+v", dict["id"])
        }
 
        code, ok := dict["code"].(string)
        if !ok {
            return nil, fmt.Errorf("filter.code is not a string: %+v", dict["code"])
        }
 
        filters[i] = Filter{
            Id:   int64(id),
            Code: code,
        }
    }
 
    return filters, nil
}
 
var schema, _ = graphql.NewSchema(
    graphql.SchemaConfig{
        Query: queryType,
    },
)
 
func executeQuery(query string, schema graphql.Schema) *graphql.Result {
    result := graphql.Do(graphql.Params{
        Schema:        schema,
        RequestString: query,
    })
 
    return result
}
 
func Start() {
    http.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) {
        var requestData = r.URL.Query().Get("query")
 
        var result = executeQuery(requestData, schema)
 
        if err := json.NewEncoder(w).Encode(result); err != nil {
            log.Println(err)
        }
    })
 
    log.Println("Server is running on port 8000")
    log.Fatalln(http.ListenAndServe(":8000", nil))
}
1
1 / 1 / 0
Регистрация: 11.01.2020
Сообщений: 15
14.08.2022, 21:42  [ТС] 5
Curry , безусловно вы правы насчет условия.

я привел сокращенный вариант кода, чтобы не выкладывать портянку.

допустил логическую ошибку, которую вы верно подметили.

Но сути это не меняем , так как видно из вывода переменной filters, то в ней пустой слайс .

Код
->filters:  [] filtersOk:  false
Добавлено через 3 минуты
korvin_ , спасибо огромное за ответ.
Ваш ответ это единственный выход из ситуации!
0
14.08.2022, 21:42
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.08.2022, 21:42
Помогаю со студенческими работами здесь

MeteorJS и GraphQL
Привет, Хочу сказать что до недавнего времени MeteorJS и GraphQL являются какойто мутью в...

GraphQL: подскажите по теории
Сел изучать GraphQL. На хабре приводят пример запроса: query { stuff { eggs shirt...

GraphQL validation error
..... const app = Relay.createContainer(App, { fragments: { viewer: () => Relay.QL` ...

Работа с Graphql запросами
Добрый день! Нужно организовать парсинг сайта с помощью graphql (сайт, который пытаюсь спарсить...

Ввести аргумент x, если аргумент попадает в область допустимых значений, вычислить значение выражения
Ввести аргумент x с помощью клавиатуры и определить, попадает ли он в область допустимых значений....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Интеграция Arduino и ChatGPT: Практическое руководство
InfoMaster 16.01.2025
В современную эпоху технологических инноваций интеграция искусственного интеллекта с микроконтроллерами открывает принципиально новые возможности для создания умных устройств и автоматизированных. . .
Как создать робота, управляемого ChatGPT
InfoMaster 16.01.2025
Концепция проекта В современную эпоху искусственный интеллект и робототехника становятся все более доступными для энтузиастов и разработчиков. Создание роботизированной руки, управляемой ChatGPT,. . .
Как создать ChatGPT бота в Telegram на Python
InfoMaster 16.01.2025
В современном мире технологии искусственного интеллекта становятся все более доступными для разработчиков, открывая новые возможности для создания умных и интерактивных приложений. Одним из самых. . .
Машинное обучение с помощью Python
InfoMaster 16.01.2025
Машинное обучение стало неотъемлемой частью современных технологий, позволяя компьютерам учиться на основе данных и принимать решения без явного программирования. В сочетании с языком. . .
Использование связки C# и PHP в корпоративной разработке и микросервисной архитектуре
InfoMaster 16.01.2025
Введение в интеграцию C# и PHP В современной корпоративной разработке все чаще возникает потребность в создании гибких и масштабируемых решений, способных эффективно решать широкий спектр. . .
Как использовать Kerio дома для управления сетью и пользователями
InfoMaster 16.01.2025
Использование технологий для улучшения повседневной жизни стало неотъемлемой частью современного быта. Одной из таких технологий является Kerio — мощный инструмент для управления сетью и. . .
Есть ли будущее у DVD и Blu-ray?
InfoMaster 16.01.2025
В эпоху стремительного развития цифровых технологий и повсеместного распространения потоковых сервисов вопрос о будущем физических носителей информации становится все более актуальным. Особенно остро. . .
Как проводить научные вычисления на Python
InfoMaster 15.01.2025
Python стал одним из наиболее востребованных языков программирования в области научных вычислений благодаря своей простоте, гибкости и обширной экосистеме специализированных библиотек. Научные. . .
Создание игры типа Minecraft на PyGame/Python: пошаговое руководство
InfoMaster 15.01.2025
В данном руководстве мы рассмотрим процесс создания игры в стиле Minecraft с использованием библиотеки PyGame на языке программирования Python. Этот проект идеально подходит как для начинающих. . .
Как создать свою первую игру в стиле Doom на Unreal Engine
InfoMaster 15.01.2025
Разработка шутера от первого лица в стиле классического Doom представляет собой увлекательное путешествие в мир игрового программирования, где сочетаются творческий подход и технические навыки. . . .
Параллельное программировани­е: основные технологии и принципы
InfoMaster 15.01.2025
Введение в параллельное программирование Параллельное программирование представляет собой фундаментальный подход к разработке программного обеспечения, который позволяет одновременно выполнять. . .
Как написать микросервис на C# с Kafka, MediatR, Redis и GitLab CI/CD
InfoMaster 15.01.2025
В современной разработке программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот подход позволяет разделить сложную систему. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru