๋ธ”๋กœ๊ทธ

๐Ÿš€ AI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์‹œ๋ฌผ์˜ ๋Œ€ํ‘œ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ตœ์ ํ™”ํ•˜๊ธฐ โ€” ์ƒˆ๋กœ์šด Gato GraphQL v2 ์‚ฌ์šฉ๋ฒ•

Leonardo Losoviz
์ž‘์„ฑ์ž: Leonardo Losoviz ยท

Gato GraphQL v2.0์ด ์ถœ์‹œ๋˜์—ˆ์Œ์„ ๊ธฐ์˜๊ฒŒ ์•Œ๋ ค๋“œ๋ฆฝ๋‹ˆ๋‹ค!

์ด ์ƒˆ ๋ฒ„์ „๊ณผ PRO ํ™•์žฅ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด, ์ƒ์„ฑํ˜• AI๋ฅผ ํ†ตํ•ด ์ธ๋„ค์ผ์ด ์—†๋Š” ๊ฒŒ์‹œ๋ฌผ์˜ ๋Œ€ํ‘œ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” v2.0์— ์ถ”๊ฐ€๋œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค (๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ™•์ธํ•˜๋ ค๋ฉด GitHub ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”).

createMediaItem ๋ฎคํ…Œ์ด์…˜ ์ถ”๊ฐ€

createMediaItem ๋ฎคํ…Œ์ด์…˜์€ ๋ฏธ๋””์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์†Œ์Šค ํŒŒ์ผ์„ ์ œ๊ณตํ•˜๋Š” ๋ฐฉ๋ฒ•์€ 2๊ฐ€์ง€์ž…๋‹ˆ๋‹ค:

  1. URL์„ ํ†ตํ•ด
  2. ์ฝ˜ํ…์ธ ๋ฅผ ์ง์ ‘ ์ž…๋ ฅ

์ด ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด:

mutation CreateMediaItems {
  fromURL: createMediaItem(input: {
    from: {
      url: {
        source: "https://gatographql.com/assets/GatoGraphQL-logo.png"
      }
    }
    caption: "Gato GraphQL logo"
    altText: "This is the Gato GraphQL logo"
  }) {
    mediaItemID
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
    mediaItem {
      ...MediaItemData
    }
  }
 
  directlyByContents: createMediaItem(input: {
    from: {
      contents: {
        body: """
<html>
  <body>
    Hello world!
  </body>
</html>
        """
        filename: "hello-world.html"
      }
    }
    title: "Hello world!"
  }) {
    mediaItemID
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
    mediaItem {
      ...MediaItemData
    }
  }
}
 
fragment MediaItemData on Media {
  altText
  caption
  mimeType
  slug
  src
  title
}

...๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค:

{
  "data": {
    "fromURL": {
      "mediaItemID": 1380,
      "status": "SUCCESS",
      "errors": null,
      "mediaItem": {
        "altText": "This is the Gato GraphQL logo",
        "caption": "Gato GraphQL logo",
        "mimeType": "image/png",
        "slug": "gatographql-logo-png",
        "src": "https://mysite.com/wp-content/uploads/GatoGraphQL-logo.png",
        "title": "GatoGraphQL-logo.png"
      }
    },
    "directlyByContents": {
      "mediaItemID": 1381,
      "status": "SUCCESS",
      "errors": null,
      "mediaItem": {
        "altText": "",
        "caption": "",
        "mimeType": "text/html",
        "slug": "hello-world-html",
        "src": "https://mysite.com/wp-content/uploads/hello-world.html",
        "title": "Hello world!"
      }
    }
  }
}

myMediaItemCount, myMediaItems, myMediaItem ํ•„๋“œ ์ถ”๊ฐ€

๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๋Š” ์ด์ œ ์ž์‹ ์˜ ๋ชจ๋“  ๋ฏธ๋””์–ด ํŒŒ์ผ์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด:

query GetMediaItems {
  me {
    slug
  }
  
  myMediaItemCount
 
  myMediaItems(pagination: {
    limit: 3
  }) {
    ...MediaItemData
  }
 
  myMediaItem(by: { id: 1380 }) {
    ...MediaItemData
  }
}
 
fragment MediaItemData on Media {
  id
  mimeType
  src
  author {
    slug
  }
}

...๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค:

{
  "data": {
    "me": {
      "slug": "admin"
    },
    "myMediaItemCount": 2,
    "myMediaItems": [
      {
        "id": 1380,
        "mimeType": "image/png",
        "src": "https://mysite.com/wp-content/uploads/GatoGraphQL-logo.png",
        "author": {
          "slug": "admin"
        }
      },
      {
        "id": 1365,
        "mimeType": "image/png",
        "src": "https://mysite.com/wp-content/uploads/browser.png",
        "author": {
          "slug": "admin"
        }
      }
    ],
    "myMediaItem": {
      "id": 1380,
      "mimeType": "image/png",
      "src": "https://mysite.com/wp-content/uploads/GatoGraphQL-logo.png",
      "author": {
        "slug": "admin"
      }
    }
  }
}

[PRO] "AI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์‹œ๋ฌผ์˜ ๋Œ€ํ‘œ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ตœ์ ํ™”ํ•˜๊ธฐ" ๋ฏธ๋ฆฌ ์ •์˜๋œ ํผ์‹œ์Šคํ‹ฐ๋“œ ์ฟผ๋ฆฌ ์ถ”๊ฐ€

(์ด ๊ธฐ๋Šฅ์€ PRO ํ™•์žฅ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.)

"AI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์‹œ๋ฌผ์˜ ๋Œ€ํ‘œ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ตœ์ ํ™”ํ•˜๊ธฐ"๋ผ๋Š” ์ œ๋ชฉ์˜ ์ƒˆ๋กœ์šด ๋ฏธ๋ฆฌ ์ •์˜๋œ ํผ์‹œ์Šคํ‹ฐ๋“œ ์ฟผ๋ฆฌ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ์ฟผ๋ฆฌ๋Š” ์ƒ์„ฑํ˜• AI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋Œ€ํ‘œ ์ด๋ฏธ์ง€๊ฐ€ ์—†๋Š” ๊ฒŒ์‹œ๋ฌผ์— ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๋ฉฐ, ๊ฒŒ์‹œ๋ฌผ ์ œ๋ชฉ์„ ํ”„๋กฌํ”„ํŠธ๋กœ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์„œ๋น„์Šค ๊ณต๊ธ‰์ž ์ค‘์—์„œ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

์ด ์ฟผ๋ฆฌ๋Š” ๋จผ์ € ๊ฒŒ์‹œ๋ฌผ์— ๋Œ€ํ‘œ ์ด๋ฏธ์ง€๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์—†๋Š” ๊ฒฝ์šฐ, ์ƒ์„ฑํ˜• AI ์„œ๋น„์Šค๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒํ•œ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ•ด๋‹น API ํ‚ค๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ƒ์„ฑํ˜• AI ์ด๋ฏธ์ง€๋Š” ์›น์— ์ตœ์ ํ™”๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฏ€๋กœ (OpenAI ์ด๋ฏธ์ง€๋Š” 3MB์— ๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!), ์ฟผ๋ฆฌ๋Š” ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€๋ฅผ TinyPNG๋กœ ์ „์†กํ•˜์—ฌ ์••์ถ•ํ•ฉ๋‹ˆ๋‹ค. ์ด ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด API ํ‚ค๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ, ์ฟผ๋ฆฌ๋Š” ํ•ด๋‹น ์ด๋ฏธ์ง€๋กœ ์ƒˆ ๋ฏธ๋””์–ด ํ•ญ๋ชฉ์„ ์ƒ์„ฑํ•˜๊ณ  (๊ฒŒ์‹œ๋ฌผ ์ œ๋ชฉ์„ ์ฒจ๋ถ€ ํŒŒ์ผ ์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉฐ, 20์ž๋กœ ์ž˜๋ผ๋ƒ„), ๊ฒŒ์‹œ๋ฌผ์˜ ๋Œ€ํ‘œ ์ด๋ฏธ์ง€๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ GraphQL ์ฟผ๋ฆฌ์ž…๋‹ˆ๋‹ค:

query InitializeVariables(
  $openAIAPIKey: String
  $stableDiffusionAPIKey: String
  $tinyPngAPIKey: String
)
  @configureWarningsOnExportingDuplicateVariable(enabled: false)
{
  isFeaturedImageMissing: _echo(value: false)
    @export(as: "isFeaturedImageMissing")
    @remove
 
  generatedImageURL: _echo(value: null)
    @export(as: "generatedImageURL")
    @remove
 
  isImageGenerated: _echo(value: false)
    @export(as: "isImageGenerated")
    @remove
 
  mimeType: _echo(value: null)
    @export(as: "mimeType")
    @remove
 
  isMediaItemCreated: _echo(value: false)
    @export(as: "isMediaItemCreated")
    @remove
 
  useOpenAI: _notEmpty(value: $openAIAPIKey)
    @export(as: "useOpenAI")
    @remove
 
  useStableDiffusion: _notEmpty(value: $stableDiffusionAPIKey)
    @export(as: "useStableDiffusion")
    @remove
 
  useTinyPng: _notEmpty(value: $tinyPngAPIKey)
    @export(as: "useTinyPng")
    @remove
}
 
query ExportPostData(
  $postId: ID!
)
  @depends(on: "InitializeVariables")
{
  post(by: { id: $postId }) {
    hasFeaturedImage
    isFeaturedImageMissing: hasFeaturedImage
      @boolOpposite
      @export(as: "isFeaturedImageMissing")
    title
      @export(as: "postTitle")
    mediaItemFilename: rawTitle
      @default(value: "untitled", condition: IS_EMPTY)
      @strLowerCase
      @strSubstr(offset: 0, length: 20)
      @export(as: "filename")
      @remove
  }
}
 
query MaybeGenerateImageUsingOpenAI(
  $openAIAPIKey: String
  $imageSize: String! = "1024x1024" # 256x256, 512x512, or 1024x1024 pixels
)
  @depends(on: "ExportPostData")
  @include(if: $isFeaturedImageMissing)
  @include(if: $useOpenAI)
{
  openAIResponse: _sendJSONObjectItemHTTPRequest(input: {
    url: "https://api.openai.com/v1/images/generations",
    method: POST,
    options: {
      auth: {
        password: $openAIAPIKey
      },
      json: {
        prompt: $postTitle,
        size: $imageSize,
        n: 1,
        response_format: "url",
      }
    }
  })
    @underJSONObjectProperty(by: { key: "data" })
      @underArrayItem(index: 0)
        @underJSONObjectProperty(by: { key: "url" })
          @export(as: "generatedImageURL")
  
  openAPIImageCaption: _sprintf(
    string: "Image created by DALL-E using prompt: '%s'",
    values: [$postTitle]
  )
      @export(as: "imageCaption")
  
  openAIMediaItemFilename: _sprintf(
    string: "%s.png",
    values: [$filename]
  )
    @export(as: "filename")
}
 
query MaybeGenerateImageUsingStableDiffusion(
  $stableDiffusionAPIKey: String
  $width: Int! = 1024
  $height: Int! = 1024
)
  @depends(on: "ExportPostData")
  @include(if: $isFeaturedImageMissing)
  @include(if: $useStableDiffusion)
{
  stableDiffusionResponse: _sendJSONObjectItemHTTPRequest(input: {
    url: "https://stablediffusionapi.com/api/v3/text2img",
    method: POST,
    options: {
      json: {
        key: $stableDiffusionAPIKey
        prompt: $postTitle,
        width: $width
        height: $height
        samples: 1
      }
    }
  })
    @underJSONObjectProperty(by: { key: "output" })
      @underArrayItem(index: 0)
        @export(as: "generatedImageURL")
  
  stableDiffusionImageCaption: _sprintf(
    string: "Image created by Stable Diffusion using prompt: '%s'",
    values: [$postTitle]
  )
    @export(as: "imageCaption")
  
  stableDiffusionMediaItemFilename: _sprintf(
    string: "%s.png",
    values: [$filename]
  )
    @export(as: "filename")
}
 
query CheckIsImageGenerated
  @depends(on: [
    "MaybeGenerateImageUsingOpenAI",
    "MaybeGenerateImageUsingStableDiffusion"
  ])
  @include(if: $isFeaturedImageMissing)
{
  isImageGenerated: _notEmpty(value: $generatedImageURL)
    @export(as: "isImageGenerated")
}
 
query MaybeCompressGeneratedImage(
  $tinyPngAPIKey: String
)
  @depends(on: "CheckIsImageGenerated")
  @include(if: $isImageGenerated)
  @include(if: $useTinyPng)
{
  compressedImageResponse: _sendHTTPRequest(input: {
    url: "https://api.tinify.com/shrink",
    method: POST,
    options: {
      auth: {
        password: $tinyPngAPIKey
      },
      headers: [
        {
          name: "Content-Type",
          value: "application/json"
        }
      ],
      json: {
        source: {
          url: $generatedImageURL
        }
      }
    }
  }) {
    body
      @remove
    bodyJSONObject: _strDecodeJSONObject(string: $__body)
 
    mimeType: _objectProperty(
      object: $__bodyJSONObject
      by: { path: "output.type" }
    )
      @export(as: "mimeType")
 
    generatedImageURL: header(name: "Location")
      @export(as: "generatedImageURL")
  }
}
 
mutation CreateMediaItemFromGeneratedImage
  @depends(on: "MaybeCompressGeneratedImage")
  @include(if: $isImageGenerated)
{
  createMediaItem(input: {
    from: {
      url: {
        source: $generatedImageURL
        filename: $filename
      }
    }
    title: $postTitle
    caption: $imageCaption
    altText: $postTitle
    mimeType: $mimeType
  }) {
    mediaItemID
      @export(as: "mediaItemID")
    isMediaItemCreated: _notNull(value: $__mediaItemID)
      @export(as: "isMediaItemCreated")
      @remove
 
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
    mediaItem {
      altText
      caption
      mimeType
      slug
      src
      title
    }
  }
}
 
mutation SetMediaItemAsPostFeaturedImage(
  $postId: ID!
)
  @depends(on: "CreateMediaItemFromGeneratedImage")
  @include(if: $isMediaItemCreated)
{
  setFeaturedImageOnCustomPost(input: {
    customPostID: $postId
    mediaItemBy: { id: $mediaItemID }
  }) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
    customPost {
      __typename
      ...on CustomPost {
        featuredImage {
          id
          altText
          caption
          mimeType
          slug
          src
          title
        }
      }
    }
  }
}

[PRO] Helper Function Collection ํ™•์žฅ ๊ธฐ๋Šฅ์— _dataMatrixOutputAsCSV ํ•„๋“œ ์ถ”๊ฐ€

(์ด ๊ธฐ๋Šฅ์€ PRO ํ™•์žฅ ๊ธฐ๋Šฅ์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.)

_dataMatrixOutputAsCSV ํ•„๋“œ๊ฐ€ Helper Function Collection ํ™•์žฅ ๊ธฐ๋Šฅ(๋ฐ ํ•ด๋‹น ํ™•์žฅ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๋Š” ๋ชจ๋“  ๋ฒˆ๋“ค)์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ํ•„๋“œ๋Š” ๋ฐ์ดํ„ฐ ๋งคํŠธ๋ฆญ์Šค๋ฅผ ๋ฐ›์•„ CSV ๋ฌธ์ž์—ด์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ์ฟผ๋ฆฌ๋Š”:

csv: _dataMatrixOutputAsCSV(
  fields: 
    ["Name", "Surname", "Year"]
  data: [
    ["John", "Smith", 2003],
    ["Pedro", "Gonzales", 2012],
    ["Manuel", "Perez", 2008],
    ["Jose", "Pereyra", 1999],
    ["Jacinto", "Bloomberg", 1998],
    ["Jun-E", "Song", 1983],
    ["Juan David", "Santamaria", 1943],
    ["Luis Miguel", null, 1966],
  ]
)

...๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค:

{
  "data": {
    "csv": "Name,Surname,Year\nJohn,Smith,2003\nPedro,Gonzales,2012\nManuel,Perez,2008\nJose,Pereyra,1999\nJacinto,Bloomberg,1998\nJun-E,Song,1983\nJuan David,Santamaria,1943\nLuis Miguel,,1966\n"
  }
}

์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด WordPress ์‚ฌ์ดํŠธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ Google ์Šคํ”„๋ ˆ๋“œ์‹œํŠธ ๋“ฑ์œผ๋กœ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ์ฟผ๋ฆฌ๋Š” 100๊ฐœ ๊ฒŒ์‹œ๋ฌผ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์„œ ID, Title, Slug, Author name, Published date, URL, Content ์—ด์ด ํฌํ•จ๋œ CSV ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ๋ฏธ๋””์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค:

query ExportPostData(
  $limit: Int! = 100,
  $offset: Int! = 0
) {
  posts(
    pagination: { limit: $limit, offset: $offset },
    sort: { by: ID, order: ASC }
  ) {
    id @export(as: "postIds", type: LIST)
    title @export(as: "postTitles", type: LIST)
    slug @export(as: "postSlugs", type: LIST)
    author {
      name @export(as: "postAuthorNames", type: LIST)
    }
    dateStr(format: "d/m/Y") @export(as: "postPublishedDates", type: LIST)
    url @export(as: "postUrls", type: LIST)
    content @export(as: "postContents", type: LIST)
  }
}
 
query CreateDataMatrix
  @depends(on: "ExportPostData")
{
  csvDataMatrix: _echo(value: $postIds)
    @underEachArrayItem(
      passIndexOnwardsAs: "key"
      passValueOnwardsAs: "postId"
      affectDirectivesUnderPos: [1, 2, 3, 4, 5, 6, 7]
    )
      @applyField(
        name: "_arrayItem",
        arguments: {
          array: $postTitles,
          position: $key,
        },
        passOnwardsAs: "postTitle"
      )
      @applyField(
        name: "_arrayItem",
        arguments: {
          array: $postSlugs,
          position: $key,
        },
        passOnwardsAs: "postSlug"
      )
      @applyField(
        name: "_arrayItem",
        arguments: {
          array: $postAuthorNames,
          position: $key,
        },
        passOnwardsAs: "postAuthorName"
      )
      @applyField(
        name: "_arrayItem",
        arguments: {
          array: $postPublishedDates,
          position: $key,
        },
        passOnwardsAs: "postPublishedDate"
      )
      @applyField(
        name: "_arrayItem",
        arguments: {
          array: $postUrls,
          position: $key,
        },
        passOnwardsAs: "postUrl"
      )
      @applyField(
        name: "_arrayItem",
        arguments: {
          array: $postContents,
          position: $key,
        },
        passOnwardsAs: "postContent"
      )
      @applyField(
        name: "_echo",
        arguments: {
          value: [
            $postId,
            $postTitle,
            $postSlug,
            $postAuthorName,
            $postPublishedDate,
            $postUrl,
            $postContent
          ]
        },
        setResultInResponse: true
      )
    @export(as: "csvDataMatrix")
}
 
query OutputCSV
  @depends(on: "CreateDataMatrix")
{
  csvString: _dataMatrixOutputAsCSV(
    fields: [
      "ID",
      "Title",
      "Slug",
      "Author name",
      "Published date",
      "URL",
      "Content",
    ]
    data: $csvDataMatrix
  )
    @export(as: "csvString")
}
 
mutation CreateMediaItem
  @depends(on: "OutputCSV")
{
  createMediaItem(input: {
    from: {
      contents: {
        body: $csvString
        filename: "posts.csv"
      }
    }
    title: "Post data as CSV"
  }) {
    mediaItemID
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
    mediaItem {
      mimeType
      slug
      src
      title
    }
  }
}

v3.0์„ ์ค€๋น„ํ•˜๋ฉฐ

์ด๋ฒˆ ์ตœ์‹  ๋ฆด๋ฆฌ์Šค์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ฆ๊ฒจ ์‚ฌ์šฉํ•˜์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

Gato GraphQL์— ์ถ”๊ฐ€๋˜์—ˆ์œผ๋ฉด ํ•˜๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์žˆ์œผ์‹ ๊ฐ€์š”? ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด์ฃผ์„ธ์š”.

์ฆ๊ฒ๊ฒŒ ์‚ฌ์šฉํ•˜์„ธ์š”!


๋‰ด์Šค๋ ˆํ„ฐ ๊ตฌ๋…ํ•˜๊ธฐ

Gato GraphQL์˜ ๋ชจ๋“  ์—…๋ฐ์ดํŠธ๋ฅผ ๋†“์น˜์ง€ ๋งˆ์„ธ์š”.