๐ฆธ๐ปโโ๏ธ ์๊ฐ: WordPress ์๋ Headless WordPress
Matt Mullenweg ๋ WPEngine ๋ ผ์ ์ดํ, Reddit(๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ๊ณณ์์๋) WordPress์ ๋์์ ์ฐพ๋ ์ฌ๋๋ค์ด ์ ์ ๋ ๋ง์์ง๊ณ ์๋ค๋ ๊ฒ์ ๋๊ผ์ต๋๋ค. ๋ฐ๋์ WordPress๋ฅผ ๋ ๋๊ณ ์ถ์ด์๊ฐ ์๋๋ผ(์ ์ด๋ ๋น์ฅ์ ์๋๋๋ผ๋), ์ด๋ค ์ ํ์ง๊ฐ ์๋์ง, ์ ์ฌ์ ์ธ ๋ง์ด๊ทธ๋ ์ด์ ์ด ์ผ๋ง๋ ์ด๋ ค์ธ์ง ์ดํดํ๊ณ ์ถ์ด ํ๋ ๊ฒ์ ๋๋ค. ์ํ์ ๋ถ์ฐ์ํค๋ ๋ฐฉ๋ฒ์ ์๊ณ ์ถ์ด ํฉ๋๋ค.
Headless WordPress๋ฅผ ์ฌ์ฉํ๋ ๋ถ๋ค์ ์ํด, Gato GraphQL์ ๋ฉ์ง ์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค: WordPress ์๋ Headless WordPress.
์ด ํฌ์คํธ์์๋ ์ด๊ฒ์ด ์ด๋ป๊ฒ ๊ฐ๋ฅํ์ง ์ค๋ช ํ๊ณ , ๋ฐ๋ชจ ์์์ ํตํด ์ง์ ๋ณด์ฌ๋๋ฆฝ๋๋ค.
Gato GraphQL์ ๋ ๋ฆฝ ์คํํ PHP ์ฑ์ผ๋ก ์คํํ๊ธฐ
Gato GraphQL์ Composer๋ก ๊ด๋ฆฌ๋๋ ๋ ๋ฆฝ ์คํํ PHP ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌ์ถ๋์์ผ๋ฉฐ, GraphQL ์๋ฒ๋ฅผ ๊ตฌ์ฑํ๋ ๋ชจ๋ PHP ์ปดํฌ๋ํธ๊ฐ WordPress์ ์์กดํ์ง ์์ต๋๋ค!
๋ฐ๋ผ์ GraphQL ์๋ฒ๋ ๋ ๋ฆฝ ์คํํ PHP ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ์คํ๋ ์ ์์ผ๋ฉฐ, WordPress ๊ธฐ๋ฐ์ด๋ ๋ค๋ฅธ ๋ฌด์์ด๋ ์ด๋ค PHP ์ ํ๋ฆฌ์ผ์ด์ ์๋ ํฌํจ์ํฌ ์ ์์ต๋๋ค.
ํน์ ์ฌ์ฉ ์ฌ๋ก์์ ์ ํ๋ฆฌ์ผ์ด์ ์ด WordPress ๋ฐ์ดํฐ์ ์ ๊ทผํ ํ์๊ฐ ์๋ค๋ฉด, ์ ์ด๋ ๊ทธ ์ฌ์ฉ ์ฌ๋ก์ ๋ํด์๋ ๋ฐ๋ก ์์ํ ์ ์์ต๋๋ค.
์ด ์์์์๋ ๊ทธ๋ฌํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์์ฐํฉ๋๋ค: GitHub API์ ์ฐ๋ํ์ฌ ๊ฐ๋ฐ ์ค์ GitHub Actions์์ ์ํฐํฉํธ๋ฅผ ๋ค์ด๋ก๋ยท์ค์นํ๋ ๋ชจ์ต์ ๋๋ค:
์์์์ GraphQL ์ฟผ๋ฆฌ๋ HTTP ์์ฒญ์ ์คํํ์ฌ GitHub Actions์์ ์์ฑ๋ ์ต์ Gato GraphQL ํ๋ฌ๊ทธ์ธ์ ๊ฐ์ ธ์ต๋๋ค. ์ด ํ๋ฌ๊ทธ์ธ๋ค์ ํ ๋ฆฌํ์คํธ ๋ณํฉ ์ ์ํฐํฉํธ๋ก ์ ๋ก๋๋ฉ๋๋ค.
GraphQL ์๋ต์์ ์ป์ ์ํฐํฉํธ์ URL์ WP-CLI์ ์ฃผ์ ๋์ด, ํ๋ฌ๊ทธ์ธ์ด ๋ก์ปฌ DEV ์น์๋ฒ์ ์๋์ผ๋ก ์ค์น๋๊ณ ํ ์คํธ๋ฅผ ์คํํ ์ ์๋ ์ํ๊ฐ ๋ฉ๋๋ค.
(์์ธํ ๋ด์ฉ์ ์ด ํฌ์คํธ์ ๋ง์ง๋ง ์น์ ์์ ์ค๋ช ํ๊ฒ ์ต๋๋ค.)
์ด ์ฌ์ฉ ์ฌ๋ก์์๋ WordPress ๋ฐ์ดํฐ์ ์ ํ ์ ๊ทผํ์ง ์์ผ๋ฏ๋ก, GraphQL ์๋ฒ๋ ์ด๋ฏธ ๋ ๋ฆฝ ์คํํ PHP ์ฑ์ผ๋ก ์คํ๋ ์ ์์ต๋๋ค.
ํ์ํ๋ค๋ฉด GitHub Actions ์ํฌํ๋ก์ฐ ๋ด์์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค!
Headless WordPress ์ฑ ๋ง์ด๊ทธ๋ ์ด์ ํ๊ธฐ
WordPress ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ฒฝ์ฐ์๋, WordPress ์์ด ๊ทธ๊ฒ์ ์คํํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
Gato GraphQL์ด ์ ๊ณตํ๋ GraphQL ์คํค๋ง์๋ WordPress ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ํ๋๊ฐ ํฌํจ๋์ด ์์ต๋๋ค: ํฌ์คํธ, ์ฌ์ฉ์, ๋๊ธ, ํ๊ทธ, ์นดํ ๊ณ ๋ฆฌ ๋ฑ์ ๋๋ค.
WordPress ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ PHP ๋ฆฌ์กธ๋ฒ ์ฝ๋๋ WordPress์ ์์กดํ๋ฉฐ, ํด๋น ์ฝ๋๋ WordPress๊ฐ ์๋ ์ฑ์์๋ ์คํ๋ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ Gato GraphQL์์๋ ์ด๋ฌํ ๋ฆฌ์กธ๋ฒ๋ค์ด ๊ฐ๊ฐ 2๊ฐ์ ํจํค์ง๋ก ๊ตฌํ๋์ด ์์ต๋๋ค:
- "๋ฐ๋๋ผ" PHP ๋ฒ์ : ๋ชจ๋ ๋ฒ์ฉ ์ฝ๋๋ฅผ ํฌํจํ๋ ๊ฒ
- WordPress ์ ์ฉ ๋ฒ์ : ํด๋น ๋ฆฌ์กธ๋ฒ๋ฅผ ์ถฉ์กฑํ๋ WordPress ๋ฉ์๋์ ๋ํ ์ค์ ํธ์ถ์ ํฌํจํ๋ ๊ฒ
์๋ฅผ ๋ค์ด, ์ด GraphQL ์ฟผ๋ฆฌ์์:
{
posts {
id
title
}
}...ํฌ์คํธ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ก์ง์ ๋ค์์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค:
Root.postsํ๋: ๋ฒ์ฉpostsํจํค์ง์ ์กด์ฌํฉ๋๋คget_posts๋ฉ์๋๋ฅผ ํตํ WordPress์ฉ ํด๊ฒฐ: WordPress ์ ์ฉposts-wpํจํค์ง์ ์กด์ฌํฉ๋๋ค.
WordPress ์ธ ํจํค์ง์ WordPress ํจํค์ง ๊ฐ์ ์ฝ๋ ๋ถํ ์ ์ฝ 80/20%๋ก, ์ฆ ์ฝ๋์ 80%๋ ๋ค๋ฅธ ํ๋ ์์ํฌ/CMS์์๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ๋ฉฐ, 20%์ ์ฝ๋๋ง ์ฌ๊ตฌํํ๋ฉด ๋ฉ๋๋ค.
๋์ฑ์ด, Gato GraphQL์ ๋ชจ๋ ๊ธฐ๋ฅ์ ๋ชจ๋์ ํตํด ์ ๊ณต๋๋ฉฐ, ๋ชจ๋์ ์์ ๋กญ๊ฒ ํ์ฑํยท๋นํ์ฑํํ ์ ์์ต๋๋ค.

Modules๋ ๋ณด์ ๋ชฉ์ ์ผ๋ก ๊ตฌํ๋ ๊ธฐ๋ฅ์
๋๋ค: ๊ณต๊ฐ API์์ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ๋
ธ์ถํ ํ์๊ฐ ์๋ค๋ฉด, Users ๋ชจ๋์ ๋นํ์ฑํํ๋ฉด ํด๋น ํ๋(์: Root.users)๊ฐ ์คํค๋ง์ ์ถ๊ฐ๋์ง ์์ต๋๋ค.
๋ชจ๋์ ๊ธฐ๋ฐ PHP ํจํค์ง์ ์ง์ ๋งคํ๋ฉ๋๋ค. ๋ฐ๋ผ์ Gato GraphQL์ ๋ ๋ฆฝ ์คํํ ์ฑ์ผ๋ก ์คํํ ๋, ํ์ํ ๋ชจ๋/ํจํค์ง๋ง ์ ํ์ ์ผ๋ก ๋ก๋ํ๊ณ ๋๋จธ์ง๋ ๋ก๋ํ์ง ์์ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ์ ํ๋ฆฌ์ผ์ด์
์ด ํฌ์คํธ, ์นดํ
๊ณ ๋ฆฌ, ํ๊ทธ ๋ฐ์ดํฐ๋ง ํ์ํ๋ค๋ฉด, posts-wp, categories-wp, tags-wp ํจํค์ง(๋ฐ ๊ทธ ์์กด์ฑ)๋ง ๋ก๋ํ๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ WordPress์์ ๋ค๋ฅธ ํ๋ ์์ํฌ(Laravel ๋๋ Symfony ๋ฑ)๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ ๋๋, ๊ทธ 3๊ฐ์ WordPress ์ ์ฉ ํจํค์ง๋ง ์ ํ๋ ์์ํฌ/CMS์ ๋ง๊ฒ ์ฌ๊ตฌํํ๋ฉด ๋๊ณ , ๊ทธ ์ธ์๋ ์๋ฌด๊ฒ๋ ๋ณ๊ฒฝํ ํ์๊ฐ ์์ต๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก, ์ค๋๋ถํฐ Headless WordPress๋ฅผ ์ฌ์ฉํ๋ฉด์, ๋์ค์ ์ต์ํ์ ๋ ธ๋ ฅ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค๋ฅธ ํ๋ ์์ํฌ๋ CMS๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ ์ ์๋ค๋ ์์ฌ๊ฐ์ ๊ฐ์ง ์ ์์ต๋๋ค.
๋ค๋ฅธ API์์ Gato GraphQL๋ก ์ ํํ๊ธฐ
์ด๋ฏธ Headless WordPress๋ฅผ ์ฌ์ฉํ๊ณ ์๋ค๋ฉด, ์ฑ์ WP REST API ๋๋ WPGraphQL ์ค ํ๋๋ฅผ ์ฌ์ฉํ๊ณ ์์ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
์ํ๊น๊ฒ๋, ์ด ๋ API ์ค ์ด๋ ๊ฒ์ ์ฌ์ฉํ๋๋ผ๋ WordPress์ ์ข ์๋ฉ๋๋ค: WordPress ๋ฐ์๋ WP REST API๊ฐ ์์ผ๋ฉฐ, WPGraphQL์ WordPress ์์ด๋ ๋์ํ์ง ์์ต๋๋ค.
๋คํํ๋, ๋ ์ค ์ด๋ ๊ฒ์ด๋ Gato GraphQL๋ก ๊ต์ฒดํ ์ ์์ผ๋ฉฐ, Headless WordPress ์ฑ์ WordPress๋ก๋ถํฐ ๋ง์ด๊ทธ๋ ์ด์ ํ ์ ์๋ ๋ฅ๋ ฅ์ ์ป๊ฒ ๋ฉ๋๋ค.
์ด ๊ฒฝ์ฐ ๋ค์ 2๋จ๊ณ๊ฐ ํ์ํฉ๋๋ค:
- WP REST API ๋๋ WPGraphQL์์ Gato GraphQL๋ก ์ ํ
- ํ์ํ WordPress ์ ์ฉ ํจํค์ง ์ฌ๊ตฌํ
API ์ ํ์ด ์ด๋ป๊ฒ ์ด๋ฃจ์ด์ง๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
WP REST API์์ Gato GraphQL์ persisted queries๋ก
Persisted Queries ํ์ฅ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด GraphQL๋ก ๊ตฌ์ฑ๋ REST ์ ์ฌ ์๋ํฌ์ธํธ๋ฅผ ๊ฒ์ํ ์ ์์ต๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ REST ์๋ํฌ์ธํธ์ ๋ํด ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ํด๋น persisted query ์๋ํฌ์ธํธ๋ฅผ ๋ง๋ค๊ณ , ๋์ ๊ทธ ์๋ํฌ์ธํธ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ๋ค์ GraphQL ์ฟผ๋ฆฌ๋ REST ์๋ํฌ์ธํธ /wp-json/wp/v2/posts/๋ฅผ ๋์ฒดํ ์ ์์ต๋๋ค:
{
posts {
id
date: dateStr(format: "Y-m-d\\TH:i:s")
modified: modifiedDateStr(format: "Y-m-d\\TH:i:s")
slug
status
link: url
title: self {
rendered: title
}
content: self {
rendered: content
},
excerpt: self {
rendered: excerpt
}
author
featured_media: featuredImage
sticky: isSticky
categories
tags
}
}API ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ํ์ฉํ๋ฉด persisted query๋ฅผ /graphql-query/wp/v2/posts/ ๊ฒฝ๋ก๋ก ๊ฒ์ํ ์ ์์ด ์๋ํฌ์ธํธ ๋งคํ์ด ์ฌ์์ง๋๋ค.
์ง์ ๋ ID์ ํฌ์คํธ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ REST ์๋ํฌ์ธํธ /wp-json/wp/v2/posts/{id}/๋ฅผ ์ฌํํ๋ ค๋ฉด, URL ํ๋ผ๋ฏธํฐ postId์ ํฌ์คํธ ID๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ๋ค์ persisted query๋ ์๋ํฌ์ธํธ /graphql-query/wp/v2/posts/single/?postId={id}๋ก ํธ์ถํ ์ ์์ต๋๋ค:
query GetPost($postId: ID!) {
post(by: { id: $postId }) {
id
date: dateStr(format: "Y-m-d\\TH:i:s")
modified: modifiedDateStr(format: "Y-m-d\\TH:i:s")
slug
status
link: url
title: self {
rendered: title
}
content: self {
rendered: content
},
excerpt: self {
rendered: excerpt
}
author
featured_media: featuredImage
sticky: isSticky
categories
tags
}
}WPGraphQL์์ Gato GraphQL๋ก
WPGraphQL๊ณผ Gato GraphQL์ GraphQL ์คํค๋ง๋ ์ ์ฌํ์ง๋ง ์ฝ๊ฐ ๋ค๋ฅด๋ฏ๋ก ์ ์์ด ํ์ํฉ๋๋ค.
Next.js WordPress ์คํํฐ leoloso/next-wordpress-starter๋ WPGraphQL๊ณผ Gato GraphQL ๋ชจ๋์์ ๋์ํฉ๋๋ค. ์คํํฐ๋ ๋ ์๋ฒ ๋ชจ๋์ ๋์ผํ JS ๋ก์ง์ ์ฌ์ฉํ๋ฉฐ, ๋ค๋ฅธ ๊ฒ์ GraphQL ์ฟผ๋ฆฌ๋ฟ์
๋๋ค.
์ด ์คํํฐ๋ ๋ ์๋ฒ ๊ฐ์ ์ฟผ๋ฆฌ๋ฅผ ์ ์์ํค๋ ์ฌ๋ฌ ์์๋ฅผ ์ ๊ณตํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ด WPGraphQL ์ฟผ๋ฆฌ๋:
fragment PostFields on Post {
id
categories {
edges {
node {
databaseId
id
name
slug
}
}
}
databaseId
date
isSticky
postId
slug
title
}...Gato GraphQL์ฉ์ผ๋ก ์ด๋ ๊ฒ ์ ์๋ฉ๋๋ค:
fragment PostFields on Post {
id
categories: self {
edges: categories(pagination: { limit: -1 }) {
node: self {
databaseId: id
id
name
slug
}
}
}
databaseId: id
date: dateStr
isSticky
postId: id
slug
title
}์์ธ: Gato GraphQL์ ๋ ๋ฆฝ ์คํํ PHP ์ฑ์ผ๋ก ์คํํ๊ธฐ
์ฌ๊ธฐ์๋ ์์ ๋์จ ๋ฐ๋ชจ ์์์ ๋ํ ์์ธํ ์ค๋ช ์ ๋๋ฆฝ๋๋ค.
์คํํ GraphQL ์ฟผ๋ฆฌ๋ ํ์ผ retrieve-github-artifacts.gql์ ์์ฑํฉ๋๋ค.
์ฟผ๋ฆฌ๋ ํ๊ฒฝ ๋ณ์ GITHUB_ACCESS_TOKEN์์ ์ก์ธ์ค ํ ํฐ์ ๊ฐ์ ธ์ GitHub API์ ์ฐ๊ฒฐํฉ๋๋ค. ์ ๊ณต๋ ๋ณ์๋ก๋ถํฐ actions/artifacts ์๋ํฌ์ธํธ์ ์ ์ฒด ๊ฒฝ๋ก๋ฅผ ๋์ ์ผ๋ก ์์ฑํ๊ณ , ์ด์ ๋ํด HTTP ์์ฒญ์ ์ ์กํฉ๋๋ค.
์๋ต์์ ๊ฐ ์ํฐํฉํธ ํญ๋ชฉ ๋ด์ "๋ค์ด๋ก๋ URL"์ ์ถ์ถํ๊ณ , ์ด์ ๋ํด ๋น๋๊ธฐ HTTP ์์ฒญ์ ์ ์กํฉ๋๋ค. ๊ฐ "๋ค์ด๋ก๋ URL"์ Location ํค๋์์ ์ค์ ๋ค์ด๋ก๋ ๊ฐ๋ฅํ ํ์ผ์ URL์ ์ป์ต๋๋ค.
๋ง์ง๋ง์ผ๋ก, WP-CLI์ ์ฃผ์ ํ๊ธฐ ํธํ๋๋ก ๋ชจ๋ URL์ ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถํ์ฌ ์ถ๋ ฅํฉ๋๋ค.
# File retrieve-github-artifacts.gql
query RetrieveProxyArtifactDownloadURLs(
$repoOwner: String!
$repoProject: String!
$perPage: Int = 1
$artifactName: String = ""
) {
githubAccessToken: _env(name: "GITHUB_ACCESS_TOKEN")
@remove
# Create the authorization header to send to GitHub
authorizationHeader: _sprintf(
string: "Bearer %s"
values: [$__githubAccessToken]
)
@remove
# Create the authorization header to send to GitHub
githubRequestHeaders: _echo(
value: [
{ name: "Accept", value: "application/vnd.github+json" }
{ name: "Authorization", value: $__authorizationHeader }
]
)
@remove
@export(as: "githubRequestHeaders")
githubAPIEndpoint: _sprintf(
string: "https://api.github.com/repos/%s/%s/actions/artifacts?per_page=%s&name=%s"
values: [$repoOwner, $repoProject, $perPage, $artifactName]
)
# Use the field from "Send HTTP Request Fields" to connect to GitHub
gitHubArtifactData: _sendJSONObjectItemHTTPRequest(
input: {
url: $__githubAPIEndpoint
options: { headers: $__githubRequestHeaders }
}
)
@remove
# Finally just extract the URL from within each "artifacts" item
gitHubProxyArtifactDownloadURLs: _objectProperty(
object: $__gitHubArtifactData
by: { key: "artifacts" }
)
@underEachArrayItem(passValueOnwardsAs: "artifactItem")
@applyField(
name: "_objectProperty"
arguments: { object: $artifactItem, by: { key: "archive_download_url" } }
setResultInResponse: true
)
@export(as: "gitHubProxyArtifactDownloadURLs")
}
query CreateHTTPRequestInputs
@depends(on: "RetrieveProxyArtifactDownloadURLs")
{
httpRequestInputs: _echo(value: $gitHubProxyArtifactDownloadURLs)
@underEachArrayItem(passValueOnwardsAs: "url")
@applyField(
name: "_objectAddEntry"
arguments: {
object: {
options: { headers: $githubRequestHeaders, allowRedirects: null }
}
key: "url"
value: $url
}
setResultInResponse: true
)
@export(as: "httpRequestInputs")
@remove
}
query RetrieveActualArtifactDownloadURLs
@depends(on: "CreateHTTPRequestInputs")
{
_sendHTTPRequests(inputs: $httpRequestInputs) {
artifactDownloadURL: header(name: "Location")
@export(as: "artifactDownloadURLs", type: LIST)
}
}
query PrintSpaceSeparatedArtifactDownloadURLs
@depends(on: "RetrieveActualArtifactDownloadURLs")
{
spaceSeparatedArtifactDownloadURLs: _arrayJoin(
array: $artifactDownloadURLs
separator: " "
)
}PHP ๋ก์ง์ Gato GraphQL ํ๋ฌ๊ทธ์ธ๊ณผ "Power Extensions" ๋ฒ๋ค(HTTP ์์ฒญ ์ ์ก ๋ฐ ๊ธฐํ ๊ธฐ๋ฅ์ ํ์)์์ ์ง์ ์ฝ๋๋ฅผ ๋ก๋ํฉ๋๋ค.
๋ ๋ฆฝ ์คํํ PHP ์ฑ์ผ๋ก์, ์ด๋ค ๋ชจ๋์ ์ด๊ธฐํํ ์ง ๋ช ์์ ์ผ๋ก ์ง์ ํ๊ณ ๊ธฐ๋ณธ๊ฐ์ด ์๋ ์ค์ ์ ์ ๊ณตํด์ผ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋ชจ๋ SendHTTPRequests์ https://api.github.com/repos์ ๋ํ ์ฐ๊ฒฐ์ ํ์ฉํ๊ณ , ๋ชจ๋ EnvironmentFields์ ํ๊ฒฝ ๋ณ์ GITHUB_ACCESS_TOKEN์ ๋ํ ์ ๊ทผ์ ํ์ฉํ๋๋ก ์ค์ ํฉ๋๋ค.
GraphQL ์คํค๋ง๋ GraphQL ์ฟผ๋ฆฌ๊ฐ ์ฒ์ ์คํ๋ ๋ ์์ฑ๋์ด ๋์คํฌ์ ์บ์๋ฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ ๋ฒ์งธ ์คํ๋ถํฐ๋ ์คํค๋ง๋ฅผ ๊ณ์ฐํ๋ ์ฝ๋๊ฐ ์ ํ ์คํ๋์ง ์์ ์คํ ์๋๊ฐ ๋นจ๋ผ์ง๋๋ค.
๋ง์ง๋ง์ผ๋ก, ๋ ๋ฆฝ ์คํํ ์ฑ์ GraphQL ์๋ฒ๋ฅผ ์ด๊ธฐํํ๊ณ , ์ฟผ๋ฆฌ๋ฅผ ์คํํ ๋ค ์๋ต์ ์ถ๋ ฅํฉ๋๋ค.
<?php
// File retrieve-github-artifacts.php
declare(strict_types=1);
use GraphQLByPoP\GraphQLServer\Server\StandaloneGraphQLServer;
use PoP\Root\Container\ContainerCacheConfiguration;
// Load the GraphQL server via the standalone PHP components
require_once (__DIR__ . '/wordpress/wp-content/plugins/gatographql/vendor/scoper-autoload.php');
// Load the PRO extensions via the standalone PHP components
require_once (__DIR__ . '/wordpress/wp-content/plugins/gatographql-power-extensions-bundle/vendor/scoper-autoload.php');
// Modules required in the GraphQL query
$moduleClasses = [
\PoPSchema\EnvironmentFields\Module::class,
\PoPSchema\FunctionFields\Module::class,
\GraphQLByPoP\ExportDirective\Module::class,
\GraphQLByPoP\DependsOnOperationsDirective\Module::class,
\GraphQLByPoP\RemoveDirective\Module::class,
\PoPSchema\ApplyFieldDirective\Module::class,
\PoPSchema\SendHTTPRequests\Module::class,
\PoPSchema\ConditionalMetaDirectives\Module::class,
\PoPSchema\DataIterationMetaDirectives\Module::class,
];
// Configure the modules
$moduleClassConfiguration = [
\PoP\GraphQLParser\Module::class => [
\PoP\GraphQLParser\Environment::ENABLE_MULTIPLE_QUERY_EXECUTION => true,
\PoP\GraphQLParser\Environment::USE_LAST_OPERATION_IN_DOCUMENT_FOR_MULTIPLE_QUERY_EXECUTION_WHEN_OPERATION_NAME_NOT_PROVIDED => true,
\PoP\GraphQLParser\Environment::ENABLE_RESOLVED_FIELD_VARIABLE_REFERENCES => true,
\PoP\GraphQLParser\Environment::ENABLE_COMPOSABLE_DIRECTIVES => true,
],
\PoPSchema\SendHTTPRequests\Module::class => [
\PoPSchema\SendHTTPRequests\Environment::SEND_HTTP_REQUEST_URL_ENTRIES => [
'#https://api.github.com/repos/(.*)#',
],
],
\PoPSchema\EnvironmentFields\Module::class => [
\PoPSchema\EnvironmentFields\Environment::ENVIRONMENT_VARIABLE_OR_PHP_CONSTANT_ENTRIES => [
'GITHUB_ACCESS_TOKEN',
],
],
];
// Cache the schema to disk, to speed-up execution from the 2nd time onwards
$containerCacheConfiguration = new ContainerCacheConfiguration('MyGraphQLServer', true, 'retrieve-github-artifacts', __DIR__ . '/tmp');
// Initialize the server
$graphQLServer = new StandaloneGraphQLServer($moduleClasses, $moduleClassConfiguration, [], [], $containerCacheConfiguration);
/**
* GraphQL query to execute, stored in its own .gql file
*
* @var string
*/
$query = file_get_contents(__DIR__ . '/retrieve-github-artifacts.gql');
// GraphQL variables
$variables = [
'repoOwner' => 'GatoGraphQL',
'repoProject' => 'GatoGraphQL',
'perPage' => 3
];
// Execute the query
$response = $graphQLServer->execute(
$query,
$variables,
);
// Print the response
echo $response->getContent();GraphQL ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ ค๋ฉด ํฐ๋ฏธ๋์์ ๋ค์์ ์คํํฉ๋๋ค(jq๋ฅผ ์ฌ์ฉํ์ฌ JSON ์ถ๋ ฅ์ ๋ณด๊ธฐ ์ข๊ฒ ์ ๋ฆฌํฉ๋๋ค):
php retrieve-github-artifacts.php | jq๋ง์ง๋ง์ผ๋ก, GraphQL ์๋ต์์ ์ํฐํฉํธ URL์ ์ถ์ถํ์ฌ WP-CLI์ ์ฃผ์ ํ๋ ค๋ฉด ๋ค์์ ์คํํฉ๋๋ค:
GITHUB_ARTIFACT_URLS=$(php retrieve-github-artifacts.php \
| grep -E -o '"spaceSeparatedArtifactDownloadURLs\":"(.*)"' \
| cut -d':' -f2- | cut -d'"' -f2- | rev | cut -d'"' -f2- | rev \
| sed 's/\\\//\//g')
wp plugin install ${GITHUB_ARTIFACT_URLS} --force --activate์์์์ ํ์ธํ ์ ์๋ฏ์ด, WordPress ์์ด Gato GraphQL์ ์คํํ ์ ์์์ด ์ ์ฆ๋์์ต๋๋ค.