10

I am using Strapi with Nuxt.js to implement my first Headless CMS. I am using Apollo and GraphQL.

I am running into the current error and I've had no luck to figure this out for days.

If I write:

query Page($id: ID!) {
  page(id: $id) {
    id
    slug
    title
  }
}

And pass the following variable:

{
  "id" : "1"
}

I received the correct expected result:

{
  "data": {
    "page": {
      "id": "1",
      "slug": "/",
      "title": "Homepage"
    }
  }
}

HOWEVER, I would like to get the content not via ID, but via a field that I created in Strapi, called "slug". Looking around, it seems like I should be able to do something like:

query Page($slug: String!) {
  page(slug: $slug) {
    id
    slug
    title
  }
}

With variable:

{
  "slug" : "/"
}

but I receive this error:

{
  "error": {
    "errors": [
      {
        "message": "Unknown argument \"slug\" on field \"page\" of type \"Query\".",
        "locations": [
          {
            "line": 2,
            "column": 8
          }
        ],
        "extensions": {
          "code": "GRAPHQL_VALIDATION_FAILED",
          "exception": {
            "stacktrace": [

... the error continues....

[UPDATE] After Italo replied, I changed it into:

query Pages($slug: String!) {
  page(where: {slug: $slug}) {
    id
    slug
    title
  }
}

But I now get the following error:

{
  "error": {
    "errors": [
      {
        "message": "Unknown argument \"where\" on field \"page\" of type \"Query\".",

I also noticed that I get a query if I change "page" into "pages", but it shows all of the pages...

What am I missing? Thanks!

Community
  • 1
  • 1
Saro
  • 529
  • 1
  • 7
  • 19

2 Answers2

12

To query one item using something other than the primary key (and using just the default built-in queries from Strapi), you need to use the filters avaiable as a where clause:

query Pages($slug: String!) {
  pages(where: {slug: $slug}) {
    id
    slug
    title
  }
}

Tip: use the Graphql interface avaiable in http://localhost:1337/graphql to test that. (if you are not already)

Italo Ayres
  • 2,603
  • 2
  • 16
  • 20
  • Hi Italo, thanks for your reply. Yes, I am using http://localhost:1337/graphql for testing, and making your changes, I now get the following error: "message": "Unknown argument \"where\" on field \"page\" of type \"Query\".", – Saro Jan 16 '20 at 13:57
  • 1
    Yeah, my mistake. Just try changing `page(where:)` to `pages(where:)` (to be clear, you're supposed to use the query that find all pages instead of the one that returns just one item) – Italo Ayres Jan 16 '20 at 20:30
  • Just go to the graphql interface and use the autocompletition (ctrl+space) to check if the where field is avaiable.@Saro – Italo Ayres Jan 16 '20 at 20:32
  • Yeah, it works this way. However, I have to reference to it as pages[0].id or I get nothing. I do get the correct one by slug. It kind of feel wrong to me to have to use the [0], so I wonder if there's a better way to do it. – Saro Jan 20 '20 at 14:44
  • 2
    It's ok using this way and getting the record using pages[0], nothing wrong with it at all. But if you want to have something better, the only way is [creating a custom endpoint on graphql schema](https://strapi.io/documentation/3.0.0-beta.x/plugins/graphql.html#customise-the-graphql-schema) It's not so hard and it's a good way to start tweeking strapi. – Italo Ayres Jan 20 '20 at 22:37
0

This seem to work for me using slug

create new file schema.graphql.js in api/blog-post/config/schema.graphql.js

module.exports = {
  query: "blogPostBySlug(slug: String!): BlogPost",
  resolver: {
    Query: {
      blogPostBySlug: {
        description: "Return blog post with a given slug",
        resolver: "application::blog-post.blog-post.findOne",
      },
    },
  },
};

change routes.json in api/blog-post/config/routes.json, from "path": "/blog-posts/:id" to "path": "/blog-posts/:slug:

{
  "method": "GET",
  "path": "/blog-posts/:slug",
  "handler": "blog-post.findOne",
  "config": {
    "policies": []
  }
},

enter image description here

atazmin
  • 4,757
  • 1
  • 32
  • 23