上述響應必須轉換為架構定義語言 (SDL) 架構,以便 GraphQL 能夠理解它。使用 JSON 到 SDL 轉換器將 JSON 響應轉換為 SDL。然后,復制并粘貼來自 Postman 的響應。

將 AutogeneratedMainType 重命名為 PhotoQuery,將 PhotosResult 重命名為 PhotoResult,并將 photos 字段所在的類型中的列表項類型重命名為 Photo。這將提高架構的可讀性。

以下是最終的 SDL 架構:

type Src {
original: String
large2x: String
large: String
medium: String
small: String
portrait: String
landscape: String
tiny: String
}

type Photo {
id: Int
width: Int
height: Int
url: String
photographer: String
photographer_url: String
photographer_id: Int
avg_color: String
liked: Boolean
alt: String
src: Src
}

type PhotosResult {
page: Int
per_page: Int
total_results: Int
next_page: String
photos: [Photo]
}

我們還希望能夠搜索照片,而Pexels提供了一個額外的端點用于獲取搜索標識符。通過重復之前的Postman過程,我們可以查看該端點的響應。由于該響應的數據格式與之前的格式相同,因此無需再次將JSON轉換為SDL。此外,由于這兩個終端節點共享相同的基URL,所以我們無需創建新的遠程源。具體的搜索端點地址為:https://api.pexels.com/v1/search?query=sport。

使用 Hygraph 集成外部數據

要開始集成外部數據,我們首先要訪問 Hygraph 網站并注冊。注冊后,創建一個新項目,并在表單中填寫項目名稱、描述和數據存儲區域:

注冊新的 Hygraph 項目

添加和配置遠程源

Hygraph的內容聯合功能使用戶能夠將外部數據源整合進他們的賬戶,從而能夠通過一個單一的GraphQL端點輕松訪問所有數據。接下來,本節將展示如何集成Pexels數據源,以便從Hygraph的終端節點獲取數據。

為此,請按照以下步驟操作:點擊“Schema”>“REMOTE SOURCES”>“Add”,然后填寫基本信息,包括遠程源的名稱和描述。選擇“REST”作為源類型,并在相應的字段中輸入Pexels端點的基礎URL。在“Headers”(標頭)部分,添加key和value,這將使管理員能夠從GraphQL端點檢索Pexels中的所有可用數據。請注意,URL中應包含正確的授權信息,例如https://api.pexels.com/v1/authorization?API_KEY=your_api_key

在 Custom type definition 部分中,添加上面生成的架構:

將遠程源添加到 Hygraph 項目

將 API_KEY 替換為您從 Pexels 控制面板獲取的密鑰。

單擊 Add,您的 Remote Source 已準備就緒。

在 Hygraph 中創建和管理模型

模型是數據的基礎,它們定義了數據的內容。要在Hygraph中創建遠程源模型,請按照以下步驟操作:首先導航到“Schema”>“MODELS”,然后點擊“Add”按鈕。接下來,填寫模型名稱(例如“pexels-photo”)并保存。

此模型將用于保存從API接收的照片詳細信息。在屏幕的右側窗格中,向下滾動并從模型的側邊欄中選擇“REST”選項。然后,為該REST接口指定一個合適的名稱(例如“photosGET”)。接著,添加有關端點的詳細信息,包括請求方法(method)和返回類型(return type)。此外,請確保填寫輸入參數(input argument)部分的相關信息。這里的返回類型可以設置為“PhotosResult”,它代表了從API獲取的照片結果。

該表單應如下圖所示:

使用 Hygraph Continued 創建遠程源模型

最后,創建一個包含單行的文本字段,并將其命名為desc 。模型的儀表板應如下圖所示:

Hygraph 儀表板上的 Pexels 項目

我們的搜索數據模型也可以執行相同的操作:

在 Hygraph 中搜索模型數據表單

添加內容

現在,應用程序的數據模型已準備就緒,我們將從 Hygraph 內容菜單向其添加內容,以便向用戶顯示它們。

在左側窗格中,點擊“Content”選項卡。您應該會在“DEFAULT VIEWS”部分看到您的數據模型。選擇它,然后點擊右上角的“ADD ENTRY”按鈕。在打開的界面中,填寫“desc”字段,完成后點擊“保存并發布”。對于搜索功能,也請重復上述步驟來添加內容,但請注意填寫的內容應與搜索相關,例如“pexels-photo”或“photo”。

在我們的 Hygraph 內容菜單中添加內容

Hygraph 提供了一個 API Playground,我們可以在其中通過嘗試查詢和更改數據來測試 API 調用。您可以通過導航到 API playground 選項卡來測試它。

設置 Hygraph 權限

現在,我們來設置 Hygraph 權限以訪問應用程序中的數據。

Hygraph 提供了必要的終端節點,但默認情況下,除非提供足夠的權限,否則無法訪問這些終端節點。要使端點可訪問,請單擊 Project Settings > ACCESS > API Access > Permanent Auth Tokens,然后單擊 Add Token。為您的令牌命名,然后單擊添加和配置權限。這將為您創建一個經過身份驗證的令牌:

Hygraph 中的身份驗證令牌

復制令牌并將其保存在安全的地方。稍后我們將需要它來驗證數據并將其提取到我們的前端。

Content API 端點是訪問數據的主要方法。轉到 Content API 部分,然后單擊 Add Permission。選擇 Read 權限,如下所示,然后保存:

在我們的 Hygraph 設置中更改權限

太棒了!我們已經成功完成了Hygraph的設置。接下來,讓我們繼續利用Astro來開發前端,并從Hygraph中獲取所需的數據。

使用 Astro 構建前端

在本節中,我們將使用從 Hygraph 獲得的數據創建我們的 Pexel 克隆應用程序。如果你已經熟悉 Astro,請轉到?GitHub?并獲取代碼。打開終端,運行以下命令,然后選擇所需的模板:

npm create astro@latest

在構建我們的應用程序之前,請在我們的根文件夾中創建一個.env文件,并將其粘貼到您的 Hygraph API 端點和永久身份驗證令牌中:

PUBLIC_HYGRAPH_PERMANENTAUTH_TOKEN="your auth token"
PUBLIC_HYGRAPH_ENDPOINT="your public content endpoint"

從Hygraph儀表板中獲取并替換以下令牌:HYGRAPH_PERMANENT_AUTH_TOKEN 和 HYGRAPH_PUBLIC_CONTENT_ENDPOINT

構建我們的應用程序 UI

在基礎層面,您的Pexels克隆應用程序需要具備一個導航欄、一個主圖區域,以及能夠展示代表照片的卡片的功能。為此,您可以創建一個基本的導航組件,并利用layouts文件夾將其集成到所有頁面上。請通過向Layout.astro文件添加相應的代碼來進行更新,該文件位于layouts文件夾內。

<! --- components/Layout.astro --->
---
import Navbar from "../components/Navbar.astro"
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="description" content="Astro description" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<link rel="stylesheet" >
<title>{title}</title>
</head>
<body>
<Navbar />
<slot />
</body>
</html>

上面的代碼很簡單,它負責渲染導入的Navbar組件。Navbar組件作為一個占位符,允許在其中插入來自其他組件的內容或嵌套的Astro內容。在本文中,我們不會介紹相關的樣式,您可以從GitHub存儲庫中獲取它們。

接下來,請在components文件夾中創建一個新文件,命名為Navbar.astro,并添加以下代碼。

<! --- components/Navbar.astro --->
---
import Searchbar from "./SearchBar"
import "./Navbar.css"
---
<nav class="navbar">
<div class="container">
<div class="left">
<a href="/" class="logo-wrapper">
<img
class="Logo"
src={"/assets/logo.svg"}
alt="logo"
/>
<h2>Pexels-Clone</h2>
</a>
<Searchbar
client:load
/>
</div>
<div class="right">
<div class="dropdown">
<p class="dropbtn">Explore</p>
<div class="dropdown-content">
<a href="#">Discover Photos</a>
<a href="#">Popular Searches</a>
<a href="#">Free Videos</a>
<a href="#">Free Videos</a>
</div>
</div>
<p>License</p>
<button class="join">Join</button>
</div>
</div>
</nav>

您可能會注意到,在Navbar.astro中,我們有一個SearchBar組件。我們也希望在hero部分重用此組件。

為此,請在components文件夾中新建一個文件,命名為SearchBar.tsx,并向其中添加以下代碼。

// components/SearchBar.tsx
import { navigate } from "astro:transitions/client";
import React, { useState } from "react";
import "./SearchBar.css";

function Searchbar() {
return (
<form>
<div className="search-box">
<input
type="text"
name="searchTerm"
aria-label="search-img"
placeholder="Search for free photos"
/>
<button type="submit">
<i className="uis uis-search"></i>
</button>
</div>
</form>
);
}
export default Searchbar;

如果你嘗試運行服務器,你會得到一個錯誤,因為 React 還沒有在項目中配置。運行以下命令以添加 React:

npx astro add react

在終端上運行命令后,Astro 將更新你的配置文件并安裝任何必要的依賴項。

創建主頁并顯示我們的數據

現在在 components 目錄中創建一個組件文件Card.tsx,以顯示來自 Hygraph 的照片數據:

// components/Card.tsx
import { useState } from "react";

type TProps = {
src: string,
alt: string,
photographer: string,
original?: string,
};
const Card = ({ src, photographer, alt, original }: TProps) => {
return (
<>
<li className="card">
<img src={src} alt={alt} />
<div className="details">
<div className="photographer">
<i className="uis uis-camera"></i>
<span>{photographer}</span>
</div>
<button>
<span>Download</span>
<i className="uis uis-import"></i>
</button>
</div>
</li>
</>
);
};
export default Card;

pages目錄下的主頁文件中,您需要連接到Hygraph API,并將獲取的數據對象映射到相應的組件上,即PhotosCard組件。

為了從后端獲取數據,您將使用fetch函數向Hygraph發送一個POST請求。

<!--- pages/index.astro --->
---
import Card from "../components/Card";
import Layout from "../layouts/Layout.astro";
import type { Photo } from "../types/index";
import Hero from "../components/Hero.astro";

const response = await fetch(import.meta.env.PUBLIC_HYGRAPH_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: Bearer ${import.meta.env.PUBLIC_HYGRAPH_PERMANENTAUTH_TOKEN}, }, body: JSON.stringify({ query: ` query Pexels($perPage: Int) { pexelsPhotos { photos(perPage: $perPage) { photos { id alt photographer src { large2x original } } } } } `, variables: { perPage: 9 }, }), }); const data = await response.json(); const results = data?.data?.pexelsPhotos; --- <Layout title="Hygraph Pexels Clone"> <Hero /> <main class="container"> <section class="gallery"> {results.map((result: any) => ( <ul class="images"> {result.photos.photos.map((photo: Photo) => ( <Card alt="{photo.alt}" photographer="{photo.photographer}" src="{photo.src.large2x}" original="{photo.src.original}" client:idle /> ))} </ul> ))} <a href="/photos" class="load-more" style="text-decoration: none" >Show More</a > </section> </main> </Layout>

上面的代碼定義了一個查詢,用于從Hygraph獲取照片。在代碼中,首先設置了請求的頭信息和查詢文檔,然后通過fetch API向Hygraph端點發送請求。從響應中,代碼提取了照片的alt文本、攝影師姓名和圖片來源等相關信息,并計劃在首頁上展示9張照片。

值得注意的是,代碼中可能包含了一些傳遞給組件的屬性(props)。Astro提供了一些指令來控制組件在DOM中的加載和執行行為。在這里,使用了client:idle指令,它的作用是告訴Astro等到瀏覽器處于空閑狀態時再下載和初始化與該組件關聯的JavaScript。這可以作為一種優化網站性能的有效手段。

接下來,請在components目錄中創建一個新文件,命名為Hero.astro,并向其中添加相應的代碼。

<! --- components/Hero.astro --->
---
import Searchbar from "./SearchBar"
---
<header class="search">
<img
src="https://images.pexels.com/photos/1629236/pexels-photo-1629236.jpeg?auto=compress&cs=tinysrgb&w=600"
alt="search-img"
/>
<div class="content">
<h1>Pexel Clone Photos Gallery with Astro</h1>
<p>Search, preview and download any images within a second</p>
<div class="header-search">
<Searchbar client:idle />
</div>
</div>
</header>

這是 image 目錄的樣子:

Pexels 克隆鏡像目錄

集成搜索功能

接下來,我們打算為應用程序增加一個搜索查詢功能,這樣用戶就能搜索不同的照片了。

請前往components/SearchBar.tsx并使用以下代碼對其進行更新。

// components/SearchBar.tsx
import { navigate } from "astro:transitions/client";
import React, { useState } from "react";
import "./SearchBar.css";

function Searchbar() {
const [searchTerm, setSearchTerm] = useState<string>("");

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSearchTerm(event.target.value);
};

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (searchTerm.trim()) {
navigate(/search/${searchTerm}, history); } else { window.alert("input a text"); } }; return ( <form onSubmit={handleSubmit}> <div className="search-box"> <input type="text" name="searchTerm" aria-label="search-img" placeholder="Search for free photos" value={searchTerm} onChange={handleChange} /> <button type="submit"> <i className="uis uis-search"></i> </button> </div> </form> ); } export default Searchbar;

目前,當我們搜索照片時,系統不會有任何反應。為了解決這個問題,我們首先需要在pages目錄下設置一個對應的動態路由路徑。請在pages目錄中新建一個文件,命名為search/[searchTerm].astro,并向其中添加以下代碼。

<!--- search/[searchTerm].astro --->
---
import Layout from "../../layouts/Layout.astro";
import Card from "../../components/Card";
import type { Photo } from "../../types";

const { searchTerm } = Astro.params;

const data = await fetch(import.meta.env.PUBLIC_HYGRAPH_ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: Bearer ${import.meta.env.PUBLIC_HYGRAPH_PERMANENTAUTH_TOKEN}, }, body: JSON.stringify({ query: ` query pexels($searchTerm: String) { searchPhotos { search(searchTerm: $searchTerm) { photos { photographer id alt src { large2x original } } } } } `, variables: { searchTerm }, }), }).then((response) => response.json()); const results = data?.data?.searchPhotos; --- <Layout title="Search" Results for ${searchTerm}> <div style="margin: 2rem auto; max-width: 90%; width: 100%"> <h1>free {searchTerm}s photos</h1> <section class="gallery"> {results.map((result: any) => ( <ul class="images"> {result.search.photos.map((photo: Photo) => ( <Card alt="{photo.alt}" photographer="{photo.photographer}" src="{photo.src.large2x}" original="{photo.src.original}" client:idle /> ))} </ul> ))} </section> </div> </Layout>

現在,當您運行服務器時,您將遇到以下錯誤:

getStaticPaths()function 是動態路由所必需的。確保從動態路由中導出函數。getStaticPaths

在Astro中,如果一個頁面的文件名包含動態參數(例如[searchTerm]),則該頁面組件需要導出一個getStaticPaths函數。這是因為Astro是一個靜態網站構建器,它會在構建階段預先生成網站的所有頁面。

然而,有時我們可能希望某些動態頁面是可選的,即它們的值是根據用戶在構建頁面之前搜索的內容來確定的。對于這種情況,getStaticPaths函數可能不是最佳選擇,因為它要求我們在構建時就知道所有可能的路徑。

幸運的是,Astro提供了按需渲染模式(包括服務器渲染和混合渲染),這允許我們預渲染單個路由,并在需要時按需渲染其他路由。這種模式結合了靜態站點和動態應用程序的優點,特別適用于那些需要按需渲染的路由。

現在,如果您想為您的網站啟用按需渲染模式,請導航到astro.config.mjs文件,并進行相應的配置切換。在那里,您可以了解更多關于Astro按需渲染輸出模式的信息。

// astro.config.mjs
import { defineConfig } from "astro/config";
import react from "@astrojs/react";

// https://astro.build/config
export default defineConfig({
output: "hybrid",
integrations: [react()],
images: {
domains: ["media.graphassets.com"],
},
});

在Astro中,默認的渲染模式是”static”,這意味著在構建時,它會為所有頁面路由生成HTML。使用”static”渲染模式,構建過程中src/pages目錄中的所有頁面都會被預渲染為HTML,從而為每個頁面創建靜態的HTML文件。

另外,請在[searchTerm].astro文件的頂部添加以下代碼行:

// pages/search/[searchTerm].astro
export const prerender = false;

這使得頁面服務器呈現,而不是靜態 HTML,因為它禁用了預呈現。現在重新運行您的開發服務器并在瀏覽器中看到以下結果:

具有搜索功能的 Pexels 克隆

結論

在本文中,我們探討了從網站和應用程序的外部API手動獲取數據所面臨的挑戰。接著,我們介紹了Hygraph CMS及其遠程數據獲取功能,這些功能簡化了從外部來源獲取數據并在一個集中位置管理數據的過程。隨后,我們通過一個實際示例,展示了如何使用Pexels API設置Hygraph,并結合一個Astro項目,構建了一個功能完備的工作克隆。

利用Hygraph的Remote Sources和模型功能,您可以更加高效地管理數據,確保內容的一致性,并輕松構建集成了來自多個不同來源數據的應用程序。這樣一來,您不僅可以節省大量的開發時間,還能將更多精力投入到為用戶提供卓越的應用程序體驗上。

您是否添加新的 JS 庫來構建新功能或提高性能?如果他們反其道而行之呢?

毫無疑問,前端領域的復雜性正日益加劇。在向應用程序添加新的JavaScript庫和其他依賴項時,您需要更高的可見性來確保用戶不會遭遇任何未知問題。

LogRocket 是一種前端應用程序監控解決方案,可讓您重放 JavaScript 錯誤,就像它們發生在您自己的瀏覽器中一樣,以便您可以更有效地對錯誤做出反應。

LogRocket能夠無縫集成到任何應用程序中,不受框架限制,并且提供了插件來記錄來自Redux、Vuex和@ngrx/store的額外上下文信息。您可以聚合并報告問題發生時應用程序的狀態,而不是僅憑猜測去推斷問題原因。此外,LogRocket還會監控應用程序的性能,提供客戶端CPU負載、客戶端內存使用情況等關鍵指標的報告。

原文鏈接:https://blog.logrocket.com/how-to-fetch-data-external-apis-using-astro-hygraph/

上一篇:

無代碼創建自己的聊天機器人操作步驟

下一篇:

通過REST API與Elasticsearch交互
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費