gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.26k stars 10.31k forks source link

Document createRemoteFileNode #4302

Closed m-allanson closed 6 years ago

m-allanson commented 6 years ago

The docs for gatsby-source-filesystem's createRemoteFileNode are the word TODO. We should write up some documentation so it's DONE.

It's implemented here.

And there are example usages in:

Refs #3132

ajayns commented 6 years ago

@m-allanson Thanks for providing all the references to look into and get to know about it.

Referring to the example usage, I was able to understand what it does and where it can be used, but then how is this data later queried in GraphQL and used in the react components and so on?

KyleAMathews commented 6 years ago

Downloaded files are created as File nodes so you can query them e.g. via allFile. All the above source plugins create links directly to the file nodes e.g. gatsby-source-wordpress when it finds a referenced image, downloads it and then links to the image from the Media node type (it's been a while since I looked at source-wordpress so the details might be off).

ajayns commented 6 years ago

@KyleAMathews Okay that makes sense. One other thing I noticed was that in both the plugins, nodes are created and also remote ones for the same data. The method that's used in fetching data is, all data fetched and stored, and each of them is used to create nodes. Also before that separately, file nodes and iterated and remote nodes are created. I didn't quite understand the purpose of this?

pieh commented 6 years ago

@ajayns I can explain at least how and why it's done in wordpress plugin

As @KyleAMathews mentioned - plugin first creates Media nodes - this doesn't represent remote file directly - this reflects how wordpress models it's data - in wrodpress when you set image fields - you don't set url to image - you reference media object (or rather attachment in wordpress terminology). This media object has link to remote file, but it also has bunch of other data - like caption or description for images, it can contain stuff like image categories.

You can definitely skip this intermediate wrapper object if you don't need it or this is just not how you handle files/attachments/images in source of your data.

If you have data like this:

const data = {
  title: "foobar",
  picture: "http://placehold.it/600/24f355"
}

You can do:

if (data.picture) {
  const remoteFileNode = createRemoteFileNode({
    url: data.picture,
    store,
    cache,
    createNode,
  })

  if (remoteFileNode) {
    // gatsby convention - add `___NODE` to name of the field to let gatsby know
    // that we reference node here (important part is to assign `id` of node and not entire node).
    //  `___NODE` part will be removed leaving just `picture` as field name with `File` type
    data.picture___NODE = remoteFileNode.id
  }

  // we need to delete original url string as this would cause ambiguity as both 
  // `picture___NODE` and `picture` would construct same field. Alternatively you can
  // name your linked field with other name - that will work too
  data.picture___NODE
}
ajayns commented 6 years ago

@pieh I didn't quite understand that. Let's take the case of soucre-drupal which seems to bit more clearer to understand.

There, remote nodes are created for all files and then this seems to be done:

if (fileNode) {
          node.localFile___NODE = fileNode.id
}

Is localFile_NODE a property of each node? And what's the purpose of that step?

pieh commented 6 years ago

no - it adds localFile field to node (note that this is done before createNode function is called). ___NODE appendix to fieldname tells gatsby that this field will link to other node (in this case it's File node that is created by createRemoteFileNode).

You can name it however you like - apart from few required fields (id, children, parent and internal) you can specify any data you want in node - gatsby will automaticly build schema types for it for graphql.

ajayns commented 6 years ago

@pieh Okay that makes sense! Thank you!

ajayns commented 6 years ago

@m-allanson This issue can be closed now yeah?

m-allanson commented 6 years ago

@ajayns yes it can, thanks for your work on this!