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

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

14.08.2022, 13:35. Показов 833. Ответов 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 запрос :

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


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

Code
1
2
3
->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. Не нашел примеров, как отправить GraphQL запрос с Yew. У...

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

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

4
300 / 261 / 76
Регистрация: 17.04.2022
Сообщений: 838
Записей в блоге: 8
14.08.2022, 16:37 2
Я не знаю что такое graphql, но мне кажется, что в тексте json-подобного запроса, отправляемого на сервер, запрос должен содержать валидный json. На знание истины не претендую, но что-то подсказывает, что имена ключей надо брать в кавычки итд
0
Модератор
 Аватар для Curry
5118 / 3361 / 536
Регистрация: 01.06.2013
Сообщений: 7,101
Записей в блоге: 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
 Аватар для korvin_
4550 / 2748 / 486
Регистрация: 28.04.2012
Сообщений: 8,670
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, то в ней пустой слайс .

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

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему

Редактор формул (кликните на картинку в правом углу, чтобы закрыть)
Новые блоги и статьи
Лучшие практики оптимизации Docker Image
Mr. Docker 13.03.2025
Размер Docker-образа влияет на множество аспектов работы с контейнерами. Чем больше образ, тем дольше его загрузка в реестр и выгрузка из него. Для команд разработки, работающих с CI/ CD пайплайнами,. . .
Вопросы на собеседовании по Docker
Mr. Docker 13.03.2025
Ты сидишь напротив технического специалиста, и вдруг звучит вопрос про Docker Swarm или многоэтапные сборки. Пот на лбу? Не переживай, после этой статьи ты будешь готов ко всему! Эта статья будет. . .
Поиск текста в сносках : замена дефиса на тире или тире на дефис...
РоΜа 13.03.2025
Нужно было найти текст в сносках и заменить. Почему-то метод селекшн не сработал. . . пришлось гуглить. найденный на форумвба код пришлось править. Смысл - заменяет в сносках дефисы и тире на нужные. . . .
Real PATH definitions in bash scripts
jigi33 13.03.2025
Как поймать путь и путь к директории относительно запускаемого файла в BASH 1. поймать путь через вывод $(pwd) 2. более правильно - на основе realpath (см. скриншот)
Django или Flask: что выбрать для веб-разработки на Python
py-thonny 13.03.2025
Django – это высокоуровневый фреймворк, который придерживается философии "всё включено". Он предоставляет разработчику готовые решения для большинства типичных задач веб-разработки: от аутентификации. . .
Непрерывное развертывание в Java с Kubernetes
Javaican 13.03.2025
Чем так привлекателен Kubernetes для развертывания Java-приложений? Этот оркестратор контейнеров позволяет автоматизировать развертывание, масштабирование и управление контейнеризированными. . .
Предотвращение XSS, CSRF и SQL-инъекций в JavaScript
run.dev 13.03.2025
JavaScript занимает первые позиции среди языков веб-разработки, но его распространенность делает его привлекательной целью для злоумышленников. Межсайтовый скриптинг (XSS), межсайтовая подделка. . .
PHP 8: JIT-компиляция и улучшение производительно­сти
Jason-Webb 13.03.2025
PHP никогда не славился своей скоростью. Многие сталкивались с проблемами производительности при работе со сложными вычислениями или обработкой больших объемов данных. Традиционная модель выполнения. . .
Сериализация данных с Apache Avro в Kafka
Javaican 12.03.2025
Apache Kafka стала одним из ключевых решений для работы с большими потоками данных. Однако с ростом объемов передаваемых данных возникает проблема: как эффективно сериализовать и десериализовать. . .
Создание потребителей Kafka с помощью Reactor Kafka
Javaican 12.03.2025
Reactor Kafka — это библиотека, объединяющая Apache Kafka с реактивным программированием на базе Project Reactor. Такое сочетание позволяет строить неблокирующие, асинхронные приложения с контролем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru