Ders 3: Bir blog gönderisini kopyalama
Bir gönderiyi kopyalamak, Gato GraphQL'nin sitedeki verileri alma, işleme ve yeniden kaydetme yeteneğinin bir örneğidir.
Blog gönderisini kopyalamak için GraphQL query
Bu GraphQL query, $postId değişkeniyle belirtilen gönderiyi kopyalar:
query InitializeDynamicVariables
@configureWarningsOnExportingDuplicateVariable(enabled: false)
{
authorID: _echo(value: null)
@export(as: "authorID")
@remove
categoryIDs: _echo(value: [])
@export(as: "categoryIDs")
@remove
featuredImageID: _echo(value: null)
@export(as: "featuredImageID")
@remove
tagIDs: _echo(value: [])
@export(as: "tagIDs")
@remove
}
query GetPostAndExportData($postId: ID!)
@depends(on: "InitializeDynamicVariables")
{
post(by: { id : $postId }) {
# Fields not to be duplicated
id
slug
date
status
# Fields to be duplicated
author {
id @export(as: "authorID")
}
categories {
id @export(as: "categoryIDs", type: LIST)
}
rawContent @export(as: "rawContent")
rawExcerpt @export(as: "excerpt")
featuredImage {
id @export(as: "featuredImageID")
}
tags {
id @export(as: "tagIDs", type: LIST)
}
rawTitle @export(as: "title")
}
}
mutation DuplicatePost
@depends(on: "GetPostAndExportData")
{
createPost(input: {
status: draft,
authorBy: {
id: $authorID
},
categoriesBy: {
ids: $categoryIDs
},
contentAs: {
html: $rawContent
},
excerpt: $excerpt
featuredImageBy: {
id: $featuredImageID
},
tagsBy: {
ids: $tagIDs
},
title: $title
}) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
post {
# Fields not to be duplicated
id
slug
date
status
# Fields to be duplicated
author {
id
}
categories {
id
}
rawContent
excerpt
featuredImage {
id
}
tags {
id
}
title
}
}
}Adım adım: GraphQL query oluşturma
Aşağıda query'nin nasıl çalıştığına ilişkin ayrıntılı analiz yer almaktadır.
Gönderi verilerini alma
Bu GraphQL query, bir gönderinin temel verilerini alır:
query GetPost($postId: ID!) {
post(by: { id : $postId }) {
# Fields not to be duplicated
id
slug
date
status
# Fields to be duplicated
author {
id
}
categories {
id
}
rawContent
excerpt
featuredImage {
id
}
tags {
id
}
title
}
}Query çalıştırıldığında ($postId değişkeni geçirilerek), yanıt şu şekilde olabilir:
{
"data": {
"post": {
"id": 25,
"slug": "public-or-private-api-mode-for-extra-security",
"date": "2020-12-12T04:06:52+00:00",
"author": {
"id": 2
},
"categories": [
{
"id": 4
},
{
"id": 3
},
{
"id": 2
}
],
"rawContent": "<!-- wp:heading -->\n<h2>Verse Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:verse -->\n<pre class=\"wp-block-verse\">Write poetry and other literary expressions honoring all spaces and line-breaks.</pre>\n<!-- /wp:verse -->\n\n<!-- wp:heading -->\n<h2>Table Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:table {\"className\":\"is-style-stripes\"} -->\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td>Row 1 Column 1</td><td>Row 1 Column 2</td></tr><tr><td>Row 2 Column 1</td><td>Row 2 Column 2</td></tr><tr><td>Row 3 Column 1</td><td>Row 3 Column 2</td></tr></tbody></table></figure>\n<!-- /wp:table -->\n\n<!-- wp:heading -->\n<h2>Separator Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:separator -->\n<hr class=\"wp-block-separator\"/>\n<!-- /wp:separator -->\n\n<!-- wp:heading {\"className\":\"has-top-margin\"} -->\n<h2 class=\"has-top-margin\">Spacer Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:spacer -->\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"></div>\n<!-- /wp:spacer -->",
"excerpt": "Verse Block Write poetry and other literary expressions honoring all spaces and line-breaks. Table Block Row 1 Column 1 Row 1 Column 2 Row 2 Column 1 Row 2 Column 2 Row 3 Column 1 Row 3 Column 2 Separator Block Spacer Block",
"featuredImage": {
"id": 362
},
"tags": [
{
"id": 12
},
{
"id": 7
}
],
"title": "Public or Private API mode, for extra security"
}
}
}Bazı alanların kopyalanması gerektiğine (yazar, başlık ve içerik dahil), diğerlerinin ise kopyalanmayacağına (id, slug ve oluşturma tarihi gibi) dikkat edin.
Gönderiyi kopyalama: Birinci yaklaşım
Multiple Query Execution uzantısı sayesinde gönderinin veri öğelerini dışa aktarabilir ve aynı GraphQL belgesindeki başka bir query veya mutation içine yeniden enjekte edebiliriz.
Multiple Query Execution, tek bir istek içinde karmaşık işlevselliği çalıştırmamıza ve GraphQL belgesini bir dizi mantıksal/atomik birime bölerek mantığı daha iyi organize etmemize olanak tanır:
- Pipeline'a eklenebilecek işlem sayısında herhangi bir sınır yoktur
- Herhangi bir işlem birden fazla bağımlılık bildirebilir:
query SomeQuery @depends(on: ["SomePreviousOp", "AnotherPreviousOp"]) {
# ...
}- Herhangi bir işlem başka bir işleme bağımlı olabilir; bu işlem de başka bir işleme bağımlı olabilir ve bu böyle devam eder:
query ExecuteFirst
# ...
}
query ExecuteSecond @depends(on: ["ExecuteFirst"]) {
# ...
}
query ExecuteThird @depends(on: ["ExecuteSecond"]) {
# ...
}-
Belgedeki işlemlerden herhangi birini çalıştırabiliriz:
?operationName=ExecuteThirdşunu çalıştırır:ExecuteFirst>ExecuteSecond>ExecuteThird?operationName=ExecuteSecondşunu çalıştırır:ExecuteFirst>ExecuteSecond?operationName=ExecuteFirstşunu çalıştırır:ExecuteFirst
-
@dependsyalnızca bir işlem aldığında,[String]yerineStringalabilir:
query ExecuteFirst
# ...
}
query ExecuteSecond @depends(on: "ExecuteFirst") {
# ...
}- Hem
queryhem demutationişlemleri birbirine bağımlı olabilir:
query GetAndExportData
# ...
}
mutation MutateData @depends(on: "GetAndExportData") {
# ...
}
query CountMutatedResults @depends(on: "MutateData") {
# ...
}- Dinamik değişkenlerin işlem içinde bildirilmesi gerekmez
@export(type:)girdisi aracılığıyla dinamik değişkene dışa aktarılan verilerin çıktısını seçebiliriz:SINGLE(varsayılan): Tek bir alan değeriLIST: Birden fazla kaynağın alan değerini içeren bir diziDICTIONARY: Birden fazla kaynağın alan değerini içeren, anahtar:${resource ID}ve değer:${field value}biçiminde bir sözlük
Aşağıdaki query, GraphQL belgesinde birbirleriyle veri paylaşabilen iki işlemden oluşan bir pipeline oluşturur (GetPostAndExportData ve DuplicatePost):
DuplicatePost,@dependsdirektifi aracılığıyla önceGetPostAndExportData'nın çalıştırılmasını belirtirGetPostAndExportData,@exportdirektifi aracılığıyla verileri dinamik değişkenlere dışa aktarırDuplicatePostardından dinamik değişkenleri okur vecreatePostmutation'ına girdi olarak verir
query GetPostAndExportData($postId: ID!) {
post(by: { id : $postId }) {
# Fields not to be duplicated
id
slug
date
status
# Fields to be duplicated
author {
id @export(as: "authorID")
}
categories {
id @export(as: "categoryIDs", type: LIST)
}
rawContent @export(as: "rawContent")
rawExcerpt @export(as: "excerpt")
featuredImage {
id @export(as: "featuredImageID")
}
tags {
id @export(as: "tagIDs", type: LIST)
}
rawTitle @export(as: "title")
}
}
mutation DuplicatePost
@depends(on: "GetPostAndExportData")
{
createPost(input: {
status: draft,
authorBy: {
id: $authorID
},
categoriesBy: {
ids: $categoryIDs
},
contentAs: {
html: $rawContent
},
excerpt: $excerpt
featuredImageBy: {
id: $featuredImageID
},
tagsBy: {
ids: $tagIDs
},
title: $title
}) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
post {
# Fields not to be duplicated
id
slug
date
status
# Fields to be duplicated
author {
id
}
categories {
id
}
rawContent
excerpt
featuredImage {
id
}
tags {
id
}
title
}
}
}Yanıtta, yeni gönderinin alanlarının gerçekten aynı olduğunu görebiliriz:
{
"data": {
"post": {
"id": 25,
"slug": "public-or-private-api-mode-for-extra-security",
"date": "2020-12-12T04:06:52+00:00",
"status": "publish",
"author": {
"id": 2
},
"categories": [
{
"id": 4
},
{
"id": 3
},
{
"id": 2
}
],
"rawContent": "<!-- wp:heading -->\n<h2>Verse Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:verse -->\n<pre class=\"wp-block-verse\">Write poetry and other literary expressions honoring all spaces and line-breaks.</pre>\n<!-- /wp:verse -->\n\n<!-- wp:heading -->\n<h2>Table Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:table {\"className\":\"is-style-stripes\"} -->\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td>Row 1 Column 1</td><td>Row 1 Column 2</td></tr><tr><td>Row 2 Column 1</td><td>Row 2 Column 2</td></tr><tr><td>Row 3 Column 1</td><td>Row 3 Column 2</td></tr></tbody></table></figure>\n<!-- /wp:table -->\n\n<!-- wp:heading -->\n<h2>Separator Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:separator -->\n<hr class=\"wp-block-separator\"/>\n<!-- /wp:separator -->\n\n<!-- wp:heading {\"className\":\"has-top-margin\"} -->\n<h2 class=\"has-top-margin\">Spacer Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:spacer -->\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"></div>\n<!-- /wp:spacer -->",
"excerpt": "Verse Block Write poetry and other literary expressions honoring all spaces and line-breaks. Table Block Row 1 Column 1 Row 1 Column 2 Row 2 Column 1 Row 2 Column 2 Row 3 Column 1 Row 3 Column 2 Separator Block Spacer Block",
"featuredImage": {
"id": 362
},
"tags": [
{
"id": 12
},
{
"id": 7
}
],
"title": "Public or Private API mode, for extra security"
},
"createPost": {
"status": "SUCCESS",
"errors": null,
"post": {
"id": 1207,
"slug": "public-or-private-api-mode-for-extra-security-2",
"date": "2023-07-07T02:06:17+00:00",
"status": "draft",
"author": {
"id": 2
},
"categories": [
{
"id": 4
},
{
"id": 3
},
{
"id": 2
}
],
"rawContent": "<!-- wp:heading -->\n<h2>Verse Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:verse -->\n<pre class=\"wp-block-verse\">Write poetry and other literary expressions honoring all spaces and line-breaks.</pre>\n<!-- /wp:verse -->\n\n<!-- wp:heading -->\n<h2>Table Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:table {\"className\":\"is-style-stripes\"} -->\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td>Row 1 Column 1</td><td>Row 1 Column 2</td></tr><tr><td>Row 2 Column 1</td><td>Row 2 Column 2</td></tr><tr><td>Row 3 Column 1</td><td>Row 3 Column 2</td></tr></tbody></table></figure>\n<!-- /wp:table -->\n\n<!-- wp:heading -->\n<h2>Separator Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:separator -->\n<hr class=\"wp-block-separator\"/>\n<!-- /wp:separator -->\n\n<!-- wp:heading {\"className\":\"has-top-margin\"} -->\n<h2 class=\"has-top-margin\">Spacer Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:spacer -->\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"></div>\n<!-- /wp:spacer -->",
"excerpt": "Verse Block Write poetry and other literary expressions honoring all spaces and line-breaks. Table Block Row 1 Column 1 Row 1 Column 2 Row 2 Column 1 Row 2 Column 2 Row 3 Column 1 Row 3 Column 2 Separator Block Spacer Block",
"featuredImage": {
"id": 362
},
"tags": [
{
"id": 12
},
{
"id": 7
}
],
"title": "Public or Private API mode, for extra security"
}
}
}
}Birinci yaklaşımın sorunları
Yukarıdaki query, bir bağlantı alanı boş olduğunda hata döndürecektir; çünkü dinamik değişken dışa aktarılmayacaktır.
Örneğin, kopyalanacak gönderide öne çıkan görsel yoksa, featuredImage alanı null olacak ve bu nedenle id @export(as: "featuredImageID") hiçbir zaman çalıştırılmayacaktır:
{
post {
featuredImage {
id @export(as: "featuredImageID")
}
}
}Dinamik değişken $featuredImageID bu durumda mevcut olmayacağından yanıt bir hata verecektir:
{
"errors": [
{
"message": "No value has been exported for dynamic variable 'featuredImageID'",
"locations": [
{
"line": 39,
"column": 22
}
]
}
],
"data": {
// ...
}
}Aşağıdaki iki yaklaşım bu sorunu ele almaktadır.
Gönderiyi kopyalama: İkinci yaklaşım
Bağlantı alanları, Gato GraphQL'de de bir değer depolar. İlk kez çözümlendiğinde bu alanlar, işaret ettikleri kaynağın (veya kaynakların) ID'sini (ya bağlantılı kaynağın ID'sini ya da bağlantılı kaynakların ID'lerini içeren bir diziyi) içerecektir. Bağlantı çözümlendiğinde, ID('ler) gerçek kaynak nesnesiyle (nesneleriyle) değiştirilecektir.
Örneğin, aşağıdaki query'de:
{
post {
featuredImage {
id
}
tags {
id
}
}
}...featuredImage alanı başlangıçta 362 değerini (bu öne çıkan görselin ID'sidir) içerecek; tags alanı ise [12, 7] dizisini (bunlar etiket ID'leridir) içerecektir.
Dışa aktarılacak değer bir ID ($featuredImageID gibi) veya ID dizisi ($tagIDs gibi) olduğunda, bu özellikten yararlanarak ID('leri) bağlantı alanında zaten dışa aktarabiliriz.
Bunu yapmak yerine:
{
post {
featuredImage {
id @export(as: "featuredImageID")
}
tags {
id @export(as: "tagIDs", type: LIST)
}
}
}...bunu yapabiliriz:
{
post {
featuredImage @export(as: "featuredImageID") {
id
}
tags @export(as: "tagIDs") {
id
}
}
}(Bağlantı alanı zaten bir liste olduğundan, $tagIDs dışa aktarılırken type: LIST argümanının kaldırıldığına dikkat edin.)
Artık bu dinamik değişkenler her zaman dışa aktarılacak ve şu değerleri alacaktır:
- Gönderide öne çıkan görsel yoksa
$featuredImageIDiçinnull - Gönderide etiket yoksa
$tagIDsiçin boş dizi[]
GraphQL query uyarlandığında şu hale gelir:
query GetPostAndExportData($postId: ID!) {
post(by: { id : $postId }) {
# Fields not to be duplicated
id
slug
date
status
# Fields to be duplicated
author @export(as: "authorID") {
id
}
categories @export(as: "categoryIDs") {
id
}
rawContent @export(as: "rawContent")
rawExcerpt @export(as: "excerpt")
featuredImage @export(as: "featuredImageID") {
id
}
tags @export(as: "tagIDs") {
id
}
rawTitle @export(as: "title")
}
}
mutation DuplicatePost
@depends(on: "GetPostAndExportData")
{
createPost(input: {
status: draft,
authorBy: {
id: $authorID
},
categoriesBy: {
ids: $categoryIDs
},
contentAs: {
html: $rawContent
},
excerpt: $excerpt
featuredImageBy: {
id: $featuredImageID
},
tagsBy: {
ids: $tagIDs
},
title: $title
}) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
post {
# Fields not to be duplicated
id
slug
date
status
# Fields to be duplicated
author {
id
}
categories {
id
}
rawContent
excerpt
featuredImage {
id
}
tags {
id
}
title
}
}
}...yanıt artık doğru çalışmaktadır:
{
"data": {
"post": {
"id": 23,
"slug": "graphql-or-rest-you-can-have-both",
"date": "2020-12-12T04:04:54+00:00",
"status": "publish",
"author": {
"id": 2
},
"categories": [
{
"id": 1
}
],
"rawContent": "<!-- wp:heading -->\n<h2>Audio Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:audio -->\n<figure class=\"wp-block-audio\"><audio controls src=\"https://freemusicarchive.org/file/music/WFMU/Broke_For_Free/Directionless_EP/Broke_For_Free_-_01_-_Night_Owl.mp3\"></audio></figure>\n<!-- /wp:audio -->\n\n<!-- wp:heading -->\n<h2>Video Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:video -->\n<figure class=\"wp-block-video\"><video controls src=\"https://archive.org/download/SlowMotionFlame/slomoflame_512kb.mp4\"></video></figure>\n<!-- /wp:video -->\n\n<!-- wp:heading -->\n<h2>Custom HTML Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:html -->\n<strong>This is a HTML block.</strong>\n<!-- /wp:html -->\n\n<!-- wp:heading {\"className\":\"has-top-margin\"} -->\n<h2 class=\"has-top-margin\">Preformatted Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:preformatted -->\n<pre class=\"wp-block-preformatted\">This is some preformatted text. Preformatted text keeps your s p a c e s, tabs and<br>linebreaks as they are.</pre>\n<!-- /wp:preformatted -->",
"excerpt": "Audio Block Video Block Custom HTML Block This is a HTML block. Preformatted Block This is some preformatted text. Preformatted text keeps your s p a c e s, tabs andlinebreaks as they are.",
"featuredImage": null,
"tags": [],
"title": "GraphQL or REST? Why not both?"
},
"createPost": {
"status": "SUCCESS",
"errors": null,
"post": {
"id": 1209,
"slug": "graphql-or-rest-why-not-both",
"date": "2023-07-07T03:24:31+00:00",
"status": "draft",
"author": {
"id": 2
},
"categories": [
{
"id": 1
}
],
"rawContent": "<!-- wp:heading -->\n<h2>Audio Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:audio -->\n<figure class=\"wp-block-audio\"><audio controls src=\"https://freemusicarchive.org/file/music/WFMU/Broke_For_Free/Directionless_EP/Broke_For_Free_-_01_-_Night_Owl.mp3\"></audio></figure>\n<!-- /wp:audio -->\n\n<!-- wp:heading -->\n<h2>Video Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:video -->\n<figure class=\"wp-block-video\"><video controls src=\"https://archive.org/download/SlowMotionFlame/slomoflame_512kb.mp4\"></video></figure>\n<!-- /wp:video -->\n\n<!-- wp:heading -->\n<h2>Custom HTML Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:html -->\n<strong>This is a HTML block.</strong>\n<!-- /wp:html -->\n\n<!-- wp:heading {\"className\":\"has-top-margin\"} -->\n<h2 class=\"has-top-margin\">Preformatted Block</h2>\n<!-- /wp:heading -->\n\n<!-- wp:preformatted -->\n<pre class=\"wp-block-preformatted\">This is some preformatted text. Preformatted text keeps your s p a c e s, tabs and<br>linebreaks as they are.</pre>\n<!-- /wp:preformatted -->",
"excerpt": "Audio Block Video Block Custom HTML Block This is a HTML block. Preformatted Block This is some preformatted text. Preformatted text keeps your s p a c e s, tabs andlinebreaks as they are.",
"featuredImage": null,
"tags": [],
"title": "GraphQL or REST? Why not both?"
}
}
}
}İkinci yaklaşımın sorunları
Yukarıdaki çözüm yalnızca ID dışa aktarımı için çalışır (çünkü bağlantı alanlarında depolanan değerler bunlardır). Etiket slug'ları gibi başka şeyler için çalışmayacaktır:
{
post {
tags {
slug @export(as: "tagSlugs", type: LIST)
}
}
}Aşağıdaki yaklaşım bu sorunu ele almaktadır.
Gönderiyi kopyalama: Üçüncü yaklaşım
PHP Functions Via Schema uzantısından _echo global alanı aracılığıyla her dinamik değişkeni null veya boş değerle başlatmak için başlangıçta ek bir işlem çalıştırabiliriz.
Böylece her dinamik değişken en az bir kez dışa aktarılmış olacaktır. Alan değeri boş değilse yeniden dışa aktarılacak ve bu ikinci değer birincinin üzerine yazacaktır.
Bu query'de $tagSlugs dinamik değişkeni boş bir dizi ile başlatılmakta ve gönderide slug'lar varsa yeniden dışa aktarılmaktadır:
query InitializeDynamicVariables {
tagSlugs: _echo(value: []) @export(as: "tagSlugs")
}
query ExportData
@depends(on: "InitializeDynamicVariables")
{
post {
tags {
slug @export(as: "tagSlugs", type: LIST)
}
}
}_echoglobal alanı, türü ne olursa olsun sağlanan her şeyi döndürür:
query {
string: _echo(value: "page")
int: _echo(value: 3)
bool: _echo(value: true)
jsonObject: _echo(value: {
name: "Robert"
surname: "Spencer"
})
null: _echo(value: null)
arrayOfString: _echo(value: ["something", "new"])
arrayOfInt: _echo(value: [1, 3, 5])
arrayOfArraysOfBool: _echo(value: [[true, false], [false]])
arrayOfMixed: _echo(value: [1, true, "string", [1, 3, 5], {key: "value"}])
}Bu çözüm, ID'ler veya diğer herhangi bir veri türünü dışa aktarmak için çalıştığından öncekinden daha kapsamlıdır.
GraphQL query uyarlandığında şu hale gelir:
query InitializeDynamicVariables {
authorID: _echo(value: null) @export(as: "authorID")
categoryIDs: _echo(value: []) @export(as: "categoryIDs")
featuredImageID: _echo(value: null) @export(as: "featuredImageID")
tagIDs: _echo(value: []) @export(as: "tagIDs")}
query GetPostAndExportData($postId: ID!)
@depends(on: "InitializeDynamicVariables")
{
post(by: { id : $postId }) {
# Fields not to be duplicated
id
slug
date
status
# Fields to be duplicated
author {
id @export(as: "authorID")
}
categories {
id @export(as: "categoryIDs", type: LIST)
}
rawContent @export(as: "rawContent")
rawExcerpt @export(as: "excerpt")
featuredImage {
id @export(as: "featuredImageID")
}
tags {
id @export(as: "tagIDs", type: LIST)
}
rawTitle @export(as: "title")
}
}
mutation DuplicatePost
@depends(on: "GetPostAndExportData")
{
createPost(input: {
status: draft,
authorBy: {
id: $authorID
},
categoriesBy: {
ids: $categoryIDs
},
contentAs: {
html: $rawContent
},
excerpt: $excerpt
featuredImageBy: {
id: $featuredImageID
},
tagsBy: {
ids: $tagIDs
},
title: $title
}) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
post {
# Fields not to be duplicated
id
slug
date
status
# Fields to be duplicated
author {
id
}
categories {
id
}
rawContent
excerpt
featuredImage {
id
}
tags {
id
}
title
}
}
}Üçüncü yaklaşımdaki uyarılar
Bir dinamik değişken birden fazla kez dışa aktarıldığında, GraphQL motoru varsayılan olarak GraphQL yanıtına bir uyarı ekler:
{
"extensions": {
"warnings": [
{
"message": "Dynamic variable with name 'tagSlugs' had already been set, had its value overridden",
"locations": [
{
"line": 22,
"column": 21
}
]
}
]
},
"data": {
// ...
}
}Bir sonraki birleşik yaklaşım bu uyarıyı ele almaktadır.
Gönderiyi kopyalama: Birleşik yaklaşım
Önceki yaklaşımdaki GraphQL query'yi kullanıyor ve şunları yaparak optimize ediyoruz:
- "Yinelenen dinamik değişken" uyarısının oluşturulmaması
InitializeDynamicVariablesiçindeki alanların değerlerinin GraphQL yanıtında yazdırılmaması (bunlara gerek yoktur; yalnızca yardımcı alanlardır)
Bu öğeleri sırasıyla şu şekilde ele alıyoruz:
- İşleme
@configureWarningsOnExportingDuplicateVariable(enabled: false)direktifini ekleyerek uyarının oluşturulmasını devre dışı bırakıyoruz - Kaldırılacak alanların her birine Field Response Removal uzantısından
@removedirektifini ekliyoruz
Bir gönderiyi kopyalamak için birleşik GraphQL query şudur:
query InitializeDynamicVariables
@configureWarningsOnExportingDuplicateVariable(enabled: false)
{
authorID: _echo(value: null)
@export(as: "authorID")
@remove
categoryIDs: _echo(value: [])
@export(as: "categoryIDs")
@remove
featuredImageID: _echo(value: null)
@export(as: "featuredImageID")
@remove
tagIDs: _echo(value: [])
@export(as: "tagIDs")
@remove
}
query GetPostAndExportData($postId: ID!)
@depends(on: "InitializeDynamicVariables")
{
post(by: { id : $postId }) {
# Fields not to be duplicated
id
slug
date
status
# Fields to be duplicated
author {
id @export(as: "authorID")
}
categories {
id @export(as: "categoryIDs", type: LIST)
}
rawContent @export(as: "rawContent")
rawExcerpt @export(as: "excerpt")
featuredImage {
id @export(as: "featuredImageID")
}
tags {
id @export(as: "tagIDs", type: LIST)
}
rawTitle @export(as: "title")
}
}
mutation DuplicatePost
@depends(on: "GetPostAndExportData")
{
createPost(input: {
status: draft,
authorBy: {
id: $authorID
},
categoriesBy: {
ids: $categoryIDs
},
contentAs: {
html: $rawContent
},
excerpt: $excerpt
featuredImageBy: {
id: $featuredImageID
},
tagsBy: {
ids: $tagIDs
},
title: $title
}) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
post {
# Fields not to be duplicated
id
slug
date
status
# Fields to be duplicated
author {
id
}
categories {
id
}
rawContent
excerpt
featuredImage {
id
}
tags {
id
}
title
}
}
}