將 GraphQL 與回應和 Oracle Content Management 搭配使用

簡介

GraphQL 是 API 的查詢語言,也是履行現有資料之查詢的程式實際執行。

本教學課程將向您介紹如何使用 GraphQL 與 React 連線 Oracle Content Management。尤其是,我們將使用 GraphQL 和 Apollo 從屬端查詢必要的資料,著重於反應最小範例網站上的現有「人員」頁面。其他頁面 (「首頁」和「聯絡方式」) 目前使用 REST API。

必要條件

繼續此教學課程之前,建議您先閱讀下列資訊:

若要依照本教學課程,您需要:

我們正在打造什麼

在 React 中建置的最低網站,您可以輕鬆擷取 Oracle Content Management 儲存區域中的影像和其他內容。

看看我們正在建置什麼、教學課程的結束狀態、使用 Oracle Content Management 內容的基本 React 最小網站:

https://headless.mycontentdemo.com/samples/oce-react-minimal-sample

此自學課程僅著重於此網站的「人員」頁面。

這是此教學課程結尾的人員頁面畫面:

此圖像顯示「反應最低限度」網站的「與我們聯絡」頁面。

若要繼續,您必須向 Oracle Content Management 進行有效訂閱,並且以「內容管理員」角色登入。

作業 1:瞭解人員頁面分類

可下載的資產套件包含名為 Minimal Main GraphQL 的資產,以及 slug 'minimalmaingraph'。

最小主要 GraphQL 資產包含 PeoplePage 類型的頁面,稱為「人員」。這是其外觀:

此圖像顯示主要 GraphQL 分類標準。

人員資產類型為 PeoplePage,其中包含人員的子類型。這是其外觀:

此圖像顯示「人員」頁面分類。

此為 people 資產的外觀 (請注意「屬性」面板中的所有中繼資料):

此圖像顯示人員分類。

工作 2:使用 Apollo 從屬端

若要使用 GraphQL 從 Oracle Content Management 查詢這些資產,我們必須在 package.json 檔案中新增 "@apollo/client「 相依性。

GraphQL API 的端點為 /content/published/api/v1.1/graphql 串連的伺服器 URL,定義在 src/scripts/services-graphql.js 檔案中。

const SERVER_URL_GRAPHQL = `${process.env.SERVER_URL}/content/published/api/v1.1/graphql`;

工作 3:執行並處理 GraphQL 查詢

src/page/Routes.js 檔案定義應用程式的路由。/page/people 路徑會導向「人員」元件。

export default [
      {
        ...App,
        routes: [
          {
            ...People,
            path: '/page/people',
            exact: true,
            title: 'People',
          },
          {
            ...Page,
            path: '/page/:slug',
            exact: true,
            title: 'Page',
          },
        ],
      },
    ];

「人員」元件負責轉譯「人員頁面」。開啟位於 src/page/People.jsx 的「人員」元件。

在伺服器端轉譯期間呼叫 fetchInitialData 函數,以從伺服器取得資料。

import fetchPeople from '../scripts/services-graphql';
    
    function fetchInitialData(req) {
      const pageslug = req.path.split('/').pop();
      return fetchPeople(pageslug);
    }

componentDidUpdate 會檢查位置 pathname 是否已變更 (表示導覽變更),然後相應地擷取資料。

  componentDidUpdate() {
        const { pageSlug } = this.state;
        const { location } = this.props;
        const { pathname } = location;
        const newSlug = pathname.split('/').pop();
        if (pageSlug !== newSlug) {
          this.fetchData(newSlug);
        }
      }
      // Client Side Data Fetching: called from Client when doing client side routing/hydration
      async fetchData(slug) {
        const pageData = await fetchPeople(slug);
        document.title = pageData.name;
        this.setState(() => ({
          pageData,
          pageSlug: slug,
        }));
      }

在 translate() 方法中,您可以看到要轉譯的資料是從元件的狀態取得。此資料具有公告區段與人員清單,因此「人員」元件的 成像 () 方法會重複通過清單,並呼叫清單中每個人員的「人員」元件。

「人員」元件會匯出包含 fetchInitialData 函數與元件的物件。

export default {
      fetchInitialData,
      component:  People,
    };

fetchPeople 方法是在 src/scripts/services-graphql.js 檔案中定義,並使用 Apollo 從屬端進行查詢,以取得「人員」頁面的所有資料。

如需有關如何使用 Oracle Content Management 查詢資料的更多資訊,請參閱文件

const GET_PEOPLE_PAGE = gql`
      query ($peopleSlug: String!, $channelToken: String!){
        getPeoplePage(slug: $peopleSlug, channelToken: $channelToken) {
          id
          slug
          name
          fields {
            announcement {
              id
              fields {
                type: fieldType
                heading
                body
                actions
                image {
                  ...sectionImages
                }
              }
            }
            people {
              id
              fields {
                fullname
                title
                biodata
                file {
                  metadata {
                    width
                    height
                  }
                }
                renditions {
                  name
                  format
                  file {
                    url
                    metadata {
                      height
                      width
                    }
                  }
                }
              }
            }
          }
        }
      }
      fragment sectionImages on image {
        id
        fields {
          file {
            metadata {
              width
              height
            }
          }
          renditions {
            name
            format
            file {
              url
              metadata {
                height
                width
              }
            }
          }
        }
      }`;
    
    export default async function fetchPeople(peopleSlug) {
      // Get the page details
      const channelToken = `${process.env.CHANNEL_TOKEN}`;
      const client = new ApolloClient(
        {
          link: new HttpLink({ uri: SERVER_URL_GRAPHQL, fetch }),
          cache: new InMemoryCache(),
        },
      );
      const page = await client.query({
        query: GET_PEOPLE_PAGE,
        variables: { peopleSlug, channelToken },
      });
    
      const pageData = process.env.IS_BROWSER
        ? page.data.getPeoplePage
        : JSON.parse(JSON.stringify(page.data.getPeoplePage));
      const { people, announcement } = pageData.fields;
      if (announcement.fields.image) {
        announcement.renditionURLs = getSourceSetGraphQL(announcement.fields.image);
      }
      if (people) {
        people.forEach((person) => {
          person.renditionURLs = getSourceSetGraphQL(person);
        });
      }
      return pageData;
    }

接著會處理傳回的結果,以建立顯示「人員」頁面的 HTML。您可以在 http://your_instance/content/published/api/v1.1/graphql/explorer 取得 GraphQL IDE。

此圖顯示總管。

結論

在此教學課程中,我們使用 GraphQL 將「人員」頁面新增至反應最小樣本網站,以取得該頁面的資料。其他頁面 (「首頁」和「與我們聯絡」) 仍使用 REST API。

如需 Oracle Content Management 中 GraphQL 的其他資訊,請參閱文件