How to prevent users from requesting all results in graphlql-go

59 Views Asked by At
type Book struct {
    ID string `json:"id"`
}

bookType := graphql.NewObject(graphql.ObjectConfig{
        Name:        "Books",
        Description: "Books List",
        Fields: graphql.Fields{
            "id": &graphql.Field{
                Type:        graphql.NewNonNull(graphql.Int),
                Description: "The identifier of the book.",
                Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                    if book, ok := p.Source.(*Book); ok {
                        return book.ID, nil
                    }

                    return nil, nil
                },
            },
        },
    })

    rootQuery := graphql.NewObject(graphql.ObjectConfig{
        Name: "RootQuery",
        Fields: graphql.Fields{
            "books": &graphql.Field{
                Type:        graphql.NewList(bookType),
                Description: "List of books.",
                Resolve: func(params graphql.ResolveParams) (interface{}, error) {
                    limit, _ := params.Args["limit"].(int)
                    rows, err := db.Query("SELECT id FROM books limit $1", limit)
                    checkErr(err)
                    var books []*Book

                    for rows.Next() {
                        book := &Book{}
                        err = rows.Scan(&book.ID)
                        checkErr(err)
                        books = append(books, book)
                    }
                    return books, nil
                },
            },
        },
    })

I'm trying to understand the best method to prevent someone from querying for all books in the database. I'd like to limit it to a maximum of 100 results.

So if the user queries with a limit of 50, it returns 50. If they don't provide a limit at all, it returns 100. If they provide greater than 100, then it returns an error.

I realize I can probably manually validate limit, _ := params.Args["limit"].(int) in the Resolve(), but wasn't sure if there was a better/built-in with graphql-go.

Any suggestions would be appreciated.

1

There are 1 best solutions below

0
On

So yes, you just validate the arguments inside of the resolver. That being said, after further research with this package, I opted to use gqlgen instead to avoid all of the reflection.